public SparseFacetedSearcher(IndexReader reader, params string[] groupByFields)
{
this.reader = reader;
var fieldValuesBitSets = new List<FieldValuesDocIDs>();
//STEP 1
//f1 = A, B
//f2 = I, J
//f3 = 1, 2, 3
int maxFacets = 1;
var inputToCP = new List<List<string>>();
foreach (string field in groupByFields)
{
var f = new FieldValuesDocIDs(reader, field);
maxFacets *= f.FieldValueDocIDsPair.Count;
if (maxFacets > MAX_FACETS) throw new Exception("Facet count exceeded " + MAX_FACETS);
fieldValuesBitSets.Add(f);
inputToCP.Add(f.FieldValueDocIDsPair.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.
Parallel.ForEach(cp, combinations =>
{
var comb = combinations.ToList();
var bitSet = fieldValuesBitSets[0].FieldValueDocIDsPair[comb[0]];
for (int j = 1; j < comb.Count; j++)
bitSet = bitSet.WalkingIntersect(fieldValuesBitSets[j].FieldValueDocIDsPair[comb[j]]).ToList();
//STEP 3
if (bitSet.Any())
{
lock (groups)
groups.Add(Tuple.Create(new FacetName(comb), bitSet));
}
});
//Now groups has 7 rows (as <List<string>, BitSet> pairs)
}