private void HandleFacets( List <ReaderFacetInfo> returnedReaders, KeyValuePair <string, FacetedQueryParser.FacetResult> result, Dictionary <string, Dictionary <string, FacetValues> > facetsByName, bool legacy, CancellationToken token) { var needToApplyAggregation = result.Value.Aggregations.Count > 0; foreach (var readerFacetInfo in returnedReaders) { var termsForField = IndexedTerms.GetTermsAndDocumentsFor(readerFacetInfo.Reader, readerFacetInfo.DocBase, result.Value.AggregateBy, _indexName, _state); if (facetsByName.TryGetValue(result.Key, out var facetValues) == false) { facetsByName[result.Key] = facetValues = new Dictionary <string, FacetValues>(); } foreach (var kvp in termsForField) { token.ThrowIfCancellationRequested(); var intersectedDocuments = GetIntersectedDocuments(new ArraySegment <int>(kvp.Value), readerFacetInfo.Results, needToApplyAggregation); var intersectCount = intersectedDocuments.Count; if (intersectCount == 0) { continue; } if (facetValues.TryGetValue(kvp.Key, out var collectionOfFacetValues) == false) { var range = FacetedQueryHelper.GetRangeName(result.Value.AggregateBy, kvp.Key); collectionOfFacetValues = new FacetValues(legacy); if (needToApplyAggregation == false) { collectionOfFacetValues.AddDefault(range); } else { foreach (var aggregation in result.Value.Aggregations) { collectionOfFacetValues.Add(aggregation.Key, range); } } facetValues.Add(kvp.Key, collectionOfFacetValues); } collectionOfFacetValues.IncrementCount(intersectCount); if (needToApplyAggregation) { var docsInQuery = new ArraySegment <int>(intersectedDocuments.Documents, 0, intersectedDocuments.Count); ApplyAggregation(result.Value.Aggregations, collectionOfFacetValues, docsInQuery, readerFacetInfo.Reader, readerFacetInfo.DocBase, _state); } } } }
private void HandleFacets(List <ReaderFacetInfo> returnedReaders, KeyValuePair <string, FacetedQueryParser.FacetResult> result, Dictionary <string, Dictionary <string, FacetValue> > facetsByName) { foreach (var readerFacetInfo in returnedReaders) { var termsForField = IndexedTerms.GetTermsAndDocumentsFor(readerFacetInfo.Reader, readerFacetInfo.DocBase, result.Value.AggregateBy, _indexName, _state); if (facetsByName.TryGetValue(result.Key, out Dictionary <string, FacetValue> facetValues) == false) { facetsByName[result.Key] = facetValues = new Dictionary <string, FacetValue>(); } foreach (var kvp in termsForField) { var needToApplyAggregation = result.Value.Aggregations.Count > 0; var intersectedDocuments = GetIntersectedDocuments(new ArraySegment <int>(kvp.Value), readerFacetInfo.Results, needToApplyAggregation); var intersectCount = intersectedDocuments.Count; if (intersectCount == 0) { continue; } if (facetValues.TryGetValue(kvp.Key, out FacetValue facetValue) == false) { facetValue = new FacetValue { Range = FacetedQueryHelper.GetRangeName(result.Value.AggregateBy, kvp.Key) }; facetValues.Add(kvp.Key, facetValue); } facetValue.Count += intersectCount; if (needToApplyAggregation) { var docsInQuery = new ArraySegment <int>(intersectedDocuments.Documents, 0, intersectedDocuments.Count); ApplyAggregation(result.Value.Aggregations, facetValue, docsInQuery, readerFacetInfo.Reader, readerFacetInfo.DocBase, _state); } } } }
public Dictionary <string, FacetResult> FacetedQuery(FacetQueryServerSide query, JsonOperationContext context, Func <string, SpatialField> getSpatialField, CancellationToken token) { var results = FacetedQueryParser.Parse(query.Facets, out Dictionary <string, Facet> defaultFacets, out Dictionary <string, List <FacetedQueryParser.ParsedRange> > rangeFacets); var facetsByName = new Dictionary <string, Dictionary <string, FacetValue> >(); uint fieldsHash = 0; if (query.Metadata.IsDistinct) { fieldsHash = CalculateQueryFieldsHash(query); } var baseQuery = GetLuceneQuery(context, query.Metadata, query.QueryParameters, _analyzer, getSpatialField); var returnedReaders = GetQueryMatchingDocuments(_searcher, baseQuery, _state); foreach (var facet in defaultFacets.Values) { if (facet.Mode != FacetMode.Default) { continue; } Dictionary <string, HashSet <IndexSearcherHolder.StringCollectionValue> > distinctItems = null; HashSet <IndexSearcherHolder.StringCollectionValue> alreadySeen = null; if (query.Metadata.IsDistinct) { distinctItems = new Dictionary <string, HashSet <IndexSearcherHolder.StringCollectionValue> >(); } foreach (var readerFacetInfo in returnedReaders) { var termsForField = IndexedTerms.GetTermsAndDocumentsFor(readerFacetInfo.Reader, readerFacetInfo.DocBase, facet.Name, _indexName, _state); if (facetsByName.TryGetValue(facet.DisplayName, out Dictionary <string, FacetValue> facetValues) == false) { facetsByName[facet.DisplayName] = facetValues = new Dictionary <string, FacetValue>(); } foreach (var kvp in termsForField) { if (query.Metadata.IsDistinct) { if (distinctItems.TryGetValue(kvp.Key, out alreadySeen) == false) { alreadySeen = new HashSet <IndexSearcherHolder.StringCollectionValue>(); distinctItems[kvp.Key] = alreadySeen; } } var needToApplyAggregation = (facet.Aggregation == FacetAggregation.None || facet.Aggregation == FacetAggregation.Count) == false; var intersectedDocuments = GetIntersectedDocuments(new ArraySegment <int>(kvp.Value), readerFacetInfo.Results, alreadySeen, query, fieldsHash, needToApplyAggregation, context); var intersectCount = intersectedDocuments.Count; if (intersectCount == 0) { continue; } if (facetValues.TryGetValue(kvp.Key, out FacetValue facetValue) == false) { facetValue = new FacetValue { Range = FacetedQueryHelper.GetRangeName(facet.Name, kvp.Key) }; facetValues.Add(kvp.Key, facetValue); } facetValue.Hits += intersectCount; facetValue.Count = facetValue.Hits; if (needToApplyAggregation) { var docsInQuery = new ArraySegment <int>(intersectedDocuments.Documents, 0, intersectedDocuments.Count); ApplyAggregation(facet, facetValue, docsInQuery, readerFacetInfo.Reader, readerFacetInfo.DocBase, _state); } } } } foreach (var range in rangeFacets) { var facet = defaultFacets[range.Key]; var needToApplyAggregation = (facet.Aggregation == FacetAggregation.None || facet.Aggregation == FacetAggregation.Count) == false; Dictionary <string, HashSet <IndexSearcherHolder.StringCollectionValue> > distinctItems = null; HashSet <IndexSearcherHolder.StringCollectionValue> alreadySeen = null; if (query.Metadata.IsDistinct) { distinctItems = new Dictionary <string, HashSet <IndexSearcherHolder.StringCollectionValue> >(); } foreach (var readerFacetInfo in returnedReaders) { var termsForField = IndexedTerms.GetTermsAndDocumentsFor(readerFacetInfo.Reader, readerFacetInfo.DocBase, facet.Name, _indexName, _state); if (query.Metadata.IsDistinct) { if (distinctItems.TryGetValue(range.Key, out alreadySeen) == false) { alreadySeen = new HashSet <IndexSearcherHolder.StringCollectionValue>(); distinctItems[range.Key] = alreadySeen; } } var facetResult = results[range.Key]; var ranges = range.Value; foreach (var kvp in termsForField) { for (int i = 0; i < ranges.Count; i++) { var parsedRange = ranges[i]; if (parsedRange.IsMatch(kvp.Key)) { var facetValue = facetResult.Values[i]; var intersectedDocuments = GetIntersectedDocuments(new ArraySegment <int>(kvp.Value), readerFacetInfo.Results, alreadySeen, query, fieldsHash, needToApplyAggregation, context); var intersectCount = intersectedDocuments.Count; if (intersectCount == 0) { continue; } facetValue.Hits += intersectCount; facetValue.Count = facetValue.Hits; if (needToApplyAggregation) { var docsInQuery = new ArraySegment <int>(intersectedDocuments.Documents, 0, intersectedDocuments.Count); ApplyAggregation(facet, facetValue, docsInQuery, readerFacetInfo.Reader, readerFacetInfo.DocBase, _state); IntArraysPool.Instance.FreeArray(intersectedDocuments.Documents); intersectedDocuments.Documents = null; } } } } } } UpdateFacetResults(results, query, defaultFacets, facetsByName); CompleteFacetCalculationsStage(results, defaultFacets); foreach (var readerFacetInfo in returnedReaders) { IntArraysPool.Instance.FreeArray(readerFacetInfo.Results.Array); } return(results); }