Beispiel #1
0
        public override Query Rewrite(IndexReader reader)
        {
            if (rewrittenQuery != null)
            {
                return(rewrittenQuery);
            }
            //load up the list of possible terms
            foreach (FieldVals f in fieldVals)
            {
                AddTerms(reader, f);
            }
            //clear the list of fields
            fieldVals.Clear();

            BooleanQuery bq = new BooleanQuery();


            //create BooleanQueries to hold the variants for each token/field pair and ensure it
            // has no coord factor
            //Step 1: sort the termqueries by term/field
            HashMap <Term, List <ScoreTerm> > variantQueries = new HashMap <Term, List <ScoreTerm> >();
            int size = q.Size();

            for (int i = 0; i < size; i++)
            {
                ScoreTerm st = q.Pop();
                var       l  = variantQueries[st.fuzziedSourceTerm];
                if (l == null)
                {
                    l = new List <ScoreTerm>();
                    variantQueries.Add(st.fuzziedSourceTerm, l);
                }
                l.Add(st);
            }
            //Step 2: Organize the sorted termqueries into zero-coord scoring boolean queries
            foreach (var variants in variantQueries.Values)
            {
                if (variants.Count == 1)
                {
                    //optimize where only one selected variant
                    ScoreTerm st = variants[0];
                    TermQuery tq = new FuzzyTermQuery(st.Term, ignoreTF);
                    tq.Boost = st.Score; // set the boost to a mix of IDF and score
                    bq.Add(tq, Occur.SHOULD);
                }
                else
                {
                    BooleanQuery termVariants = new BooleanQuery(true); //disable coord and IDF for these term variants
                    foreach (ScoreTerm st in variants)
                    {
                        TermQuery tq = new FuzzyTermQuery(st.Term, ignoreTF); // found a match
                        tq.Boost = st.Score;                                  // set the boost using the ScoreTerm's score
                        termVariants.Add(tq, Occur.SHOULD);                   // add to query
                    }
                    bq.Add(termVariants, Occur.SHOULD);                       // add to query
                }
            }
            //TODO possible alternative step 3 - organize above booleans into a new layer of field-based
            // booleans with a minimum-should-match of NumFields-1?
            bq.Boost            = Boost;
            this.rewrittenQuery = bq;
            return(bq);
        }