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() { //We only want to run the base query once, so we capture all of the facet-ing terms then run the query // once through the collector and pull out all of the terms in one shot var allCollector = new GatherAllCollector(); var facetsByName = new Dictionary <string, Dictionary <string, int> >(); IndexSearcher currentIndexSearcher; using (Database.IndexStorage.GetCurrentIndexSearcher(Index, out currentIndexSearcher)) { var baseQuery = Database.IndexStorage.GetLuceneQuery(Index, IndexQuery, Database.IndexQueryTriggers); currentIndexSearcher.Search(baseQuery, allCollector); var fields = Facets.Values.Select(x => x.Name) .Concat(Ranges.Select(x => x.Key)); var fieldsToRead = new HashSet <string>(fields); IndexedTerms.ReadEntriesForFields(currentIndexSearcher.IndexReader, fieldsToRead, allCollector.Documents, term => { List <ParsedRange> list; if (Ranges.TryGetValue(term.Field, out list)) { var num = NumericStringToNum(term.Text); for (int i = 0; i < list.Count; i++) { var parsedRange = list[i]; if (parsedRange.IsMatch(term.Text)) { Results.Results[term.Field].Values[i].Hits++; } } } Facet value; if (Facets.TryGetValue(term.Field, out value)) { var facetValues = facetsByName.GetOrAdd(term.Field); facetValues[term.Text] = facetValues.GetOrDefault(term.Text) + 1; } }); } UpdateFacetResults(facetsByName); }
public void Execute() { //We only want to run the base query once, so we capture all of the facet-ing terms then run the query // once through the collector and pull out all of the terms in one shot var allCollector = new GatherAllCollector(); var facetsByName = new Dictionary <string, Dictionary <string, FacetValue> >(); using (var currentState = Database.IndexStorage.GetCurrentStateHolder(Index)) { var currentIndexSearcher = currentState.IndexSearcher; var baseQuery = Database.IndexStorage.GetLuceneQuery(Index, IndexQuery, Database.IndexQueryTriggers); currentIndexSearcher.Search(baseQuery, allCollector); var fields = Facets.Values.Select(x => x.Name) .Concat(Ranges.Select(x => x.Key)); var fieldsToRead = new HashSet <string>(fields); FieldTermVector fieldTermVector; var allVectoredTerms = fieldsToRead.All(s => indexDefinition.TermVectors.TryGetValue(s, out fieldTermVector) && fieldTermVector != FieldTermVector.No); if (allVectoredTerms) { IndexedTerms.ReadEntriesForFieldsFromTermVectors(currentState, fieldsToRead, allCollector.Documents, (field, value, doc) => HandleFacets(field, value, facetsByName, doc)); } else { IndexedTerms.ReadEntriesForFields(currentState, fieldsToRead, allCollector.Documents, (field, value, doc) => HandleFacets(field, value, facetsByName, doc)); } UpdateFacetResults(facetsByName); CompleteFacetCalculationsStage1(currentState, allVectoredTerms); CompleteFacetCalculationsStage2(); } }
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); } } }
public void Execute() { ValidateFacets(); //We only want to run the base query once, so we capture all of the facet-ing terms then run the query // once through the collector and pull out all of the terms in one shot var allCollector = new GatherAllCollector(); var facetsByName = new Dictionary <string, Dictionary <string, FacetValue> >(); using (var currentState = Database.IndexStorage.GetCurrentStateHolder(Index)) { var currentIndexSearcher = currentState.IndexSearcher; var baseQuery = Database.IndexStorage.GetDocumentQuery(Index, IndexQuery, Database.IndexQueryTriggers); currentIndexSearcher.Search(baseQuery, allCollector); var indexReader = currentIndexSearcher.IndexReader; var fields = Facets.Values.Select(x => x.Name) .Concat(Ranges.Select(x => x.Key)); var fieldsToRead = new HashSet <string>(fields); IndexedTerms.ReadEntriesForFields(currentState, fieldsToRead, allCollector.Documents, (term, doc) => { var facets = Facets.Values.Where(facet => facet.Name == term.Field); foreach (var facet in facets) { switch (facet.Mode) { case FacetMode.Default: var facetValues = facetsByName.GetOrAdd(facet.DisplayName); FacetValue existing; if (facetValues.TryGetValue(term.Text, out existing) == false) { existing = new FacetValue { Range = GetRangeName(term) }; facetValues[term.Text] = existing; } ApplyFacetValueHit(existing, facet, doc, null, indexReader); break; case FacetMode.Ranges: List <ParsedRange> list; if (Ranges.TryGetValue(term.Field, out list)) { for (int i = 0; i < list.Count; i++) { var parsedRange = list[i]; if (parsedRange.IsMatch(term.Text)) { var facetValue = Results.Results[term.Field].Values[i]; ApplyFacetValueHit(facetValue, facet, doc, parsedRange, indexReader); } } } break; default: throw new ArgumentOutOfRangeException(); } } }); UpdateFacetResults(facetsByName); CompleteFacetCalculationsStage1(currentState); CompleteFacetCalculationsStage2(); } }