rclabo commented on a change in pull request #475:
URL: https://github.com/apache/lucenenet/pull/475#discussion_r625143263
##########
File path: src/Lucene.Net.Grouping/GroupingSearch.cs
##########
@@ -161,86 +196,261 @@ public virtual ITopGroups<object> Search(IndexSearcher
searcher, Filter filter,
}
/// <summary>
- /// Executes a grouped search. Both the first pass and second pass are
executed on the specified searcher.
+ /// Executes a grouped search base on the field specified via the
constructor. Both the first pass
+ /// and second pass are executed on the specified searcher.
+ /// </summary>
+ /// <param name="searcher">The <see cref="IndexSearcher"/> instance to
execute the grouped search on.</param>
+ /// <param name="query">The query to execute with the grouping</param>
+ /// <param name="groupOffset">The group offset</param>
+ /// <param name="groupLimit">The number of groups to return from the
specified group offset</param>
+ /// <returns>the grouped result as a <see cref="ITopGroups{Object}"/>
instance</returns>
+ /// <exception cref="IOException">If any I/O related errors
occur</exception>
+ // LUCENENET additional method signature. Makes searching by field
easier due to concrete return type
+ public virtual ITopGroups<BytesRef> SearchByField(IndexSearcher
searcher, Query query, int groupOffset, int groupLimit)
+ {
+ return GroupByField<BytesRef>(searcher, null, query, groupOffset,
groupLimit);
+ }
+
+
+ /// <summary>
+ /// Executes a grouped search base on the field specified via the
constructor. Both the first pass
+ /// and second pass are executed on the specified searcher.
/// </summary>
- /// <typeparam name="TGroupValue">The expected return type of the
search.</typeparam>
/// <param name="searcher">The <see cref="IndexSearcher"/> instance to
execute the grouped search on.</param>
/// <param name="filter">The filter to execute with the
grouping</param>
/// <param name="query">The query to execute with the grouping</param>
/// <param name="groupOffset">The group offset</param>
/// <param name="groupLimit">The number of groups to return from the
specified group offset</param>
/// <returns>the grouped result as a <see cref="ITopGroups{Object}"/>
instance</returns>
/// <exception cref="IOException">If any I/O related errors
occur</exception>
- public virtual ITopGroups<TGroupValue>
Search<TGroupValue>(IndexSearcher searcher, Filter filter, Query query, int
groupOffset, int groupLimit)
+ // LUCENENET additional method signature. Makes searching by field
easier due to concrete return type
+ public virtual ITopGroups<BytesRef> SearchByField(IndexSearcher
searcher, Filter filter, Query query, int groupOffset, int groupLimit)
{
- if (groupField != null || groupFunction != null)
+ if (groupField is null)
{
- return GroupByFieldOrFunction<TGroupValue>(searcher, filter,
query, groupOffset, groupLimit);
+ throw IllegalStateException.Create("Must use constructor to
set pass a non null value for groupField.");
}
- else if (groupEndDocs != null)
+
+ if (groupFunction != null)
{
- return GroupByDocBlock<TGroupValue>(searcher, filter, query,
groupOffset, groupLimit);
+ throw IllegalStateException.Create("The groupFunction must be
null.");
}
- else
+ return GroupByField<BytesRef>(searcher, filter, query,
groupOffset, groupLimit);
+ }
+
+ /// <summary>
+ /// Executes a grouped search base on the function specified by a <see
cref="ValueSource"/> passed via the constructor.
+ /// Both the first pass and second pass are executed on the specified
searcher.
+ /// </summary>
+ /// <param name="searcher">The <see cref="IndexSearcher"/> instance to
execute the grouped search on.</param>
+ /// <param name="query">The query to execute with the grouping</param>
+ /// <param name="groupOffset">The group offset</param>
+ /// <param name="groupLimit">The number of groups to return from the
specified group offset</param>
+ /// <returns>the grouped result as a <see cref="ITopGroups{Object}"/>
instance</returns>
+ /// <exception cref="IOException">If any I/O related errors
occur</exception>
+ // LUCENENET additional method signature. Makes searching by function
easier due to ability to specify type of MutableValue returned.
+ public virtual ITopGroups<TMutableValue>
SearchByFunction<TMutableValue>(IndexSearcher searcher, Query query, int
groupOffset, int groupLimit)
+ where TMutableValue : MutableValue
+ {
+ return GroupByFunction<TMutableValue>(searcher, null, query,
groupOffset, groupLimit);
+ }
+
+ /// <summary>
+ /// Executes a grouped search base on the function specified by a <see
cref="ValueSource"/> passed via the constructor.
+ /// Both the first pass and second pass are executed on the specified
searcher.
+ /// </summary>
+ /// <param name="searcher">The <see cref="IndexSearcher"/> instance to
execute the grouped search on.</param>
+ /// <param name="filter">The filter to execute with the
grouping</param>
+ /// <param name="query">The query to execute with the grouping</param>
+ /// <param name="groupOffset">The group offset</param>
+ /// <param name="groupLimit">The number of groups to return from the
specified group offset</param>
+ /// <returns>the grouped result as a <see cref="ITopGroups{Object}"/>
instance</returns>
+ /// <exception cref="IOException">If any I/O related errors
occur</exception>
+ // LUCENENET additional method signature. Makes searching by function
easier due to ability to specify type of MutableValue returned.
+ public virtual ITopGroups<TMutableValue>
SearchByFunction<TMutableValue>(IndexSearcher searcher, Filter filter, Query
query, int groupOffset, int groupLimit)
+ where TMutableValue : MutableValue
+ {
+ if (groupFunction is null)
{
throw IllegalStateException.Create("Either groupField,
groupFunction or groupEndDocs must be set."); // This can't happen...
}
+
+ if (groupField != null)
+ {
+ throw new Exception("The valueSource must be null.");
+ }
+ return GroupByFunction<TMutableValue>(searcher, filter, query,
groupOffset, groupLimit);
}
- protected virtual ITopGroups<TGroupValue>
GroupByFieldOrFunction<TGroupValue>(IndexSearcher searcher, Filter filter,
Query query, int groupOffset, int groupLimit)
+ //LUCENENET: Method replaced by two methods GroupByField and
GroupByFunction so that a generic type constraint
+ // can be added to the GroupByFunction case.
+ //protected virtual ITopGroups GroupByFieldOrFunction(IndexSearcher
searcher, Filter filter, Query query, int groupOffset, int groupLimit)
+ //{
+ //}
+
+
+ //LUCENENET Specific. One of two methods that replace
GroupByFieldOrFunction. Used support SearchByField.
+ // This method is essentually a Field specific version of the
GroupByFieldOrFunction.
+ protected virtual ITopGroups<TGroupValue>
GroupByField<TGroupValue>(IndexSearcher searcher, Filter filter, Query query,
int groupOffset, int groupLimit)
{
int topN = groupOffset + groupLimit;
IAbstractFirstPassGroupingCollector<TGroupValue>
firstPassCollector;
IAbstractAllGroupsCollector<TGroupValue> allGroupsCollector;
AbstractAllGroupHeadsCollector allGroupHeadsCollector;
- if (groupFunction != null)
+
+ if (groupField is null)
+ {
+ throw IllegalStateException.Create("groupField must be set via
the constructor.");
+ }
+
+ firstPassCollector =
(IAbstractFirstPassGroupingCollector<TGroupValue>)new
TermFirstPassGroupingCollector(groupField, groupSort, topN);
+ if (allGroups)
+ {
+ allGroupsCollector =
(IAbstractAllGroupsCollector<TGroupValue>)new
TermAllGroupsCollector(groupField, initialSize);
+ }
+ else
+ {
+ allGroupsCollector = null;
+ }
+ if (allGroupHeads)
{
- firstPassCollector =
(IAbstractFirstPassGroupingCollector<TGroupValue>)new
FunctionFirstPassGroupingCollector(groupFunction, valueSourceContext,
groupSort, topN);
+ allGroupHeadsCollector =
TermAllGroupHeadsCollector.Create(groupField, sortWithinGroup, initialSize);
+ }
+ else
+ {
+ allGroupHeadsCollector = null;
+ }
+
+ ICollector firstRound;
+ if (allGroupHeads || allGroups)
+ {
+ List<ICollector> collectors = new List<ICollector>();
+ collectors.Add(firstPassCollector);
+
if (allGroups)
{
- allGroupsCollector =
(IAbstractAllGroupsCollector<TGroupValue>)new
FunctionAllGroupsCollector(groupFunction, valueSourceContext);
- }
- else
- {
- allGroupsCollector = null;
+ collectors.Add(allGroupsCollector);
}
if (allGroupHeads)
{
- allGroupHeadsCollector = new
FunctionAllGroupHeadsCollector(groupFunction, valueSourceContext,
sortWithinGroup);
- }
- else
- {
- allGroupHeadsCollector = null;
+ collectors.Add(allGroupHeadsCollector);
}
+ firstRound = MultiCollector.Wrap(collectors.ToArray(/* new
Collector[collectors.size()] */));
}
else
{
- firstPassCollector =
(IAbstractFirstPassGroupingCollector<TGroupValue>)new
TermFirstPassGroupingCollector(groupField, groupSort, topN);
- if (allGroups)
- {
- allGroupsCollector =
(IAbstractAllGroupsCollector<TGroupValue>)new
TermAllGroupsCollector(groupField, initialSize);
- }
- else
- {
- allGroupsCollector = null;
- }
- if (allGroupHeads)
+ firstRound = firstPassCollector;
+ }
+
+ CachingCollector cachedCollector = null;
+ if (maxCacheRAMMB != null || maxDocsToCache != null)
+ {
+ if (maxCacheRAMMB != null)
{
- allGroupHeadsCollector =
TermAllGroupHeadsCollector.Create(groupField, sortWithinGroup, initialSize);
+ cachedCollector = CachingCollector.Create(firstRound,
cacheScores, maxCacheRAMMB.Value);
}
else
{
- allGroupHeadsCollector = null;
+ cachedCollector = CachingCollector.Create(firstRound,
cacheScores, maxDocsToCache.Value);
}
+ searcher.Search(query, filter, cachedCollector);
+ }
+ else
+ {
+ searcher.Search(query, filter, firstRound);
+ }
+
+ if (allGroups)
+ {
+ matchingGroups = (ICollection)allGroupsCollector.Groups;
Review comment:
I think so. I could also probably convert the matchingGroups member
var from a `ICollection` to a `ICollection<TGroupValue>` if that's preferred
for the reasons you cited. It would mean that [ICollection
GetAllMatchingGroups()](https://github.com/apache/lucenenet/blob/master/src/Lucene.Net.Grouping/GroupingSearch.cs#L707)
would need to be removed but it appears to only be used by one test which can
easily be upgraded to use the generic version of the same method. So I can
make those changes if that sounds good.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]