private IEnumerable <FacetMatch> FindMatchesInQuery(Query baseQueryWithoutFacetDrilldown, IList <FacetFieldInfo> allFacetFieldInfos, FacetFieldInfo facetFieldInfoToCalculateFor) { var calculations = 0; var queryFilter = new CachingWrapperFilter(new QueryWrapperFilter(CreateFacetedQuery(baseQueryWithoutFacetDrilldown, allFacetFieldInfos, facetFieldInfoToCalculateFor.FieldName))); var bitsQueryWithoutFacetDrilldown = new OpenBitSetDISI(queryFilter.GetDocIdSet(IndexReader).Iterator(), IndexReader.MaxDoc); var baseQueryWithoutFacetDrilldownCopy = new OpenBitSetDISI(bitsQueryWithoutFacetDrilldown.Bits.Length) { Bits = new long[bitsQueryWithoutFacetDrilldown.Bits.Length] }; var calculatedFacetCounts = new ResultCollection(facetFieldInfoToCalculateFor); foreach (var facetValueBitSet in GetOrCreateFacetBitSet(facetFieldInfoToCalculateFor.FieldName).FacetValueBitSetList) { var isSelected = calculatedFacetCounts.IsSelected(facetValueBitSet.Value); if (!isSelected && facetValueBitSet.Count < calculatedFacetCounts.MinCountForNonSelected) //Impossible to get a better result { if (calculatedFacetCounts.HaveEnoughResults) { break; } } bitsQueryWithoutFacetDrilldown.Bits.CopyTo(baseQueryWithoutFacetDrilldownCopy.Bits, 0); baseQueryWithoutFacetDrilldownCopy.NumWords = bitsQueryWithoutFacetDrilldown.NumWords; var bitset = facetValueBitSet.Bitset ?? CalculateOpenBitSetDisi(facetFieldInfoToCalculateFor.FieldName, facetValueBitSet.Value); baseQueryWithoutFacetDrilldownCopy.And(bitset); var count = baseQueryWithoutFacetDrilldownCopy.Cardinality(); if (count == 0) { continue; } var match = new FacetMatch { Count = count, Value = facetValueBitSet.Value, FacetFieldName = facetFieldInfoToCalculateFor.FieldName }; calculations++; if (isSelected) { calculatedFacetCounts.AddToSelected(match); } else { calculatedFacetCounts.AddToNonSelected(match); } } return(calculatedFacetCounts.GetList()); }
public SimpleFacetedSearch(IndexReader reader, string[] groupByFields) { this._Reader = reader; List<FieldValuesBitSets> fieldValuesBitSets = new List<FieldValuesBitSets>(); //STEP 1 //f1 = A, B //f2 = I, J //f3 = 1, 2, 3 int maxFacets = 1; IList<IList<string>> inputToCP = new List<IList<string>>(); foreach (string field in groupByFields) { FieldValuesBitSets f = new FieldValuesBitSets(reader, field); maxFacets *= f.FieldValueBitSetPair.Count; if (maxFacets > MAX_FACETS) throw new Exception("Facet count exceeded " + MAX_FACETS); fieldValuesBitSets.Add(f); inputToCP.Add(f.FieldValueBitSetPair.Keys.ToList()); } //STEP 2 // comb1: A I 1 // comb2: A I 2 etc. var cp = inputToCP.CartesianProduct(); //SETP 3 //create a single BitSet for each combination //BitSet1: A AND I AND 1 //BitSet2: A AND I AND 2 etc. //and remove impossible comb's (for ex, B J 3) from list. #if !NET35 Parallel.ForEach(cp, combinations => #else foreach(var combinations in cp) #endif { OpenBitSetDISI bitSet = new OpenBitSetDISI(_Reader.MaxDoc); bitSet.Set(0, bitSet.Size()); List<string> comb = combinations.ToList(); for (int j = 0; j < comb.Count; j++) { bitSet.And(fieldValuesBitSets[j].FieldValueBitSetPair[comb[j]]); } //STEP 3 if (bitSet.Cardinality() > 0) { lock(_Groups) _Groups.Add(new KeyValuePair<List<string>, OpenBitSetDISI>(comb, bitSet)); } }
private void DoChain(OpenBitSetDISI result, Logic logic, DocIdSet dis) { if (dis is OpenBitSet) { // optimized case for OpenBitSets switch (logic) { case Logic.OR: result.Or((OpenBitSet)dis); break; case Logic.AND: result.And((OpenBitSet)dis); break; case Logic.ANDNOT: result.AndNot((OpenBitSet)dis); break; case Logic.XOR: result.Xor((OpenBitSet)dis); break; default: DoChain(result, DEFAULT, dis); break; } } else { DocIdSetIterator disi; if (dis == null) { disi = DocIdSet.EMPTY_DOCIDSET.Iterator(); } else { disi = dis.Iterator(); if (disi == null) { disi = DocIdSet.EMPTY_DOCIDSET.Iterator(); } } switch (logic) { case Logic.OR: result.InPlaceOr(disi); break; case Logic.AND: result.InPlaceAnd(disi); break; case Logic.ANDNOT: result.InPlaceNot(disi); break; case Logic.XOR: result.InPlaceXor(disi); break; default: DoChain(result, DEFAULT, dis); break; } } }