private void CompleteFacetCalculationsStage1(IndexSearcherHolder.IndexSearcherHoldingState state, bool allVectoredTerms) { var fieldsToRead = new HashSet <string>(Facets .Where(x => x.Value.Aggregation != FacetAggregation.None && x.Value.Aggregation != FacetAggregation.Count) .Select(x => x.Value.AggregationField) .Where(x => x != null)); if (fieldsToRead.Count == 0) { return; } var allDocs = new HashSet <int>(matches.Values.SelectMany(x => x.Docs)); if (allVectoredTerms) { IndexedTerms.ReadEntriesForFieldsFromTermVectors(state, fieldsToRead, allDocs, GetValueFromIndex, (field, textVal, currentVal, docId) => HandleFacetsCalculationStage1(docId, field, textVal, currentVal)); } else { IndexedTerms.ReadEntriesForFields(state, fieldsToRead, allDocs, GetValueFromIndex, (field, textVal, currentVal, docId) => HandleFacetsCalculationStage1(docId, field, textVal, currentVal)); } }
private void CompleteFacetCalculationsStage1(IndexSearcherHolder.IndexSearcherHoldingState state) { var fieldsToRead = new HashSet <string>(Facets .Where(x => x.Value.Aggregation != FacetAggregation.None && x.Value.Aggregation != FacetAggregation.Count) .Select(x => x.Value.AggregationField) .Where(x => x != null)); if (fieldsToRead.Count == 0) { return; } var allDocs = new HashSet <int>(matches.Values.SelectMany(x => x.Docs)); IndexedTerms.ReadEntriesForFields(state, fieldsToRead, allDocs, GetValueFromIndex, (term, currentVal, docId) => { foreach (var match in matches) { if (match.Value.Docs.Contains(docId) == false) { continue; } var facet = match.Value.Facet; if (term.Field != facet.AggregationField) { continue; } switch (facet.Mode) { case FacetMode.Default: ApplyAggregation(facet, match.Key, currentVal); break; case FacetMode.Ranges: if (!match.Value.Range.IsMatch(term.Text)) { continue; } ApplyAggregation(facet, match.Key, currentVal); break; default: throw new ArgumentOutOfRangeException(); } } }); }
public void Execute() { ValidateFacets(); var facetsByName = new Dictionary <string, Dictionary <string, FacetValue> >(); bool isDistinct = IndexQuery.IsDistinct; if (isDistinct) { _fieldsCrc = IndexQuery.FieldsToFetch.Aggregate <string, uint>(0, (current, field) => Crc.Value(field, current)); } _currentState = Database.IndexStorage.GetCurrentStateHolder(Index); using (_currentState) { var currentIndexSearcher = _currentState.IndexSearcher; var baseQuery = Database.IndexStorage.GetDocumentQuery(Index, IndexQuery, Database.IndexQueryTriggers); var returnedReaders = GetQueryMatchingDocuments(currentIndexSearcher, baseQuery); foreach (var facet in Facets.Values) { if (facet.Mode != FacetMode.Default) { continue; } Dictionary <string, HashSet <IndexSearcherHolder.StringCollectionValue> > distinctItems = null; HashSet <IndexSearcherHolder.StringCollectionValue> alreadySeen = null; if (isDistinct) { distinctItems = new Dictionary <string, HashSet <IndexSearcherHolder.StringCollectionValue> >(); } foreach (var readerFacetInfo in returnedReaders) { var termsForField = IndexedTerms.GetTermsAndDocumentsFor(readerFacetInfo.Reader, readerFacetInfo.DocBase, facet.Name, Database.Name, Index); Dictionary <string, FacetValue> facetValues; if (facetsByName.TryGetValue(facet.DisplayName, out facetValues) == false) { facetsByName[facet.DisplayName] = facetValues = new Dictionary <string, FacetValue>(); } foreach (var kvp in termsForField) { if (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, needToApplyAggregation); var intersectCount = intersectedDocuments.Count; if (intersectCount == 0) { continue; } FacetValue facetValue; if (facetValues.TryGetValue(kvp.Key, out facetValue) == false) { facetValue = new FacetValue { Range = 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); } } } } foreach (var range in Ranges) { var facet = Facets[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 (isDistinct) { distinctItems = new Dictionary <string, HashSet <IndexSearcherHolder.StringCollectionValue> >(); } foreach (var readerFacetInfo in returnedReaders) { var termsForField = IndexedTerms.GetTermsAndDocumentsFor(readerFacetInfo.Reader, readerFacetInfo.DocBase, facet.Name, Database.Name, Index); if (isDistinct) { if (distinctItems.TryGetValue(range.Key, out alreadySeen) == false) { alreadySeen = new HashSet <IndexSearcherHolder.StringCollectionValue>(); distinctItems[range.Key] = alreadySeen; } } var facetResult = Results.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, needToApplyAggregation); 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); IntArraysPool.Instance.FreeArray(intersectedDocuments.Documents); intersectedDocuments.Documents = null; } } } } } } UpdateFacetResults(facetsByName); CompleteFacetCalculationsStage(); foreach (var readerFacetInfo in returnedReaders) { IntArraysPool.Instance.FreeArray(readerFacetInfo.Results.Array); } } }