A Query for drill-down over facet categories. You should call Add(string, string[]) for every group of categories you want to drill-down over.

NOTE: if you choose to create your own Query by calling Term, it is recommended to wrap it with ConstantScoreQuery and set the boost to 0.0f, so that it does not affect the scores of the documents. @lucene.experimental

Inheritance: Query
        /// <summary>
        /// Used by <see cref="DrillSideways"/>
        /// </summary>
        internal DrillDownQuery(FacetsConfig config, Filter filter, DrillDownQuery other)
        {
            query = new BooleanQuery(true); // disable coord

            BooleanClause[] clauses = other.query.Clauses;
            if (clauses.Length == other.drillDownDims.Count)
            {
                throw new System.ArgumentException("cannot apply filter unless baseQuery isn't null; pass ConstantScoreQuery instead");
            }
            Debug.Assert(clauses.Length == 1 + other.drillDownDims.Count, clauses.Length + " vs " + (1 + other.drillDownDims.Count));
            drillDownDims.AddAll(other.drillDownDims);
            query.Add(new FilteredQuery(clauses[0].Query, filter), Occur.MUST);
            for (int i = 1; i < clauses.Length; i++)
            {
                query.Add(clauses[i].Query, Occur.MUST);
            }
            this.config = config;
        }
        public virtual void TestScoringNoBaseQuery()
        {
            // verify that drill-down queries (with no base query) returns 0.0 score
            IndexSearcher searcher = NewSearcher(reader);

            DrillDownQuery q = new DrillDownQuery(config);
            q.Add("a");
            TopDocs docs = searcher.Search(q, reader.MaxDoc); // fetch all available docs to this query
            foreach (ScoreDoc sd in docs.ScoreDocs)
            {
                Assert.AreEqual(0f, sd.Score, 0f);
            }
        }
        public virtual void TestScoring()
        {
            // verify that drill-down queries do not modify scores
            IndexSearcher searcher = NewSearcher(reader);

            float[] scores = new float[reader.MaxDoc];

            Query q = new TermQuery(new Term("content", "foo"));
            TopDocs docs = searcher.Search(q, reader.MaxDoc); // fetch all available docs to this query
            foreach (ScoreDoc sd in docs.ScoreDocs)
            {
                scores[sd.Doc] = sd.Score;
            }

            // create a drill-down query with category "a", scores should not change
            DrillDownQuery q2 = new DrillDownQuery(config, q);
            q2.Add("a");
            docs = searcher.Search(q2, reader.MaxDoc); // fetch all available docs to this query
            foreach (ScoreDoc sd in docs.ScoreDocs)
            {
                Assert.AreEqual(scores[sd.Doc], sd.Score, 0f, "score of doc=" + sd.Doc + " modified");
            }
        }
        public virtual void TestQueryImplicitDefaultParams()
        {
            IndexSearcher searcher = NewSearcher(reader);

            // Create the base query to start with
            DrillDownQuery q = new DrillDownQuery(config);
            q.Add("a");

            // Making sure the query yields 5 documents with the facet "b" and the
            // previous (facet "a") query as a base query
            DrillDownQuery q2 = new DrillDownQuery(config, q);
            q2.Add("b");
            TopDocs docs = searcher.Search(q2, 100);
            Assert.AreEqual(5, docs.TotalHits);

            // Check that content:foo (which yields 50% results) and facet/b (which yields 20%)
            // would gather together 10 results (10%..)
            Query fooQuery = new TermQuery(new Term("content", "foo"));
            DrillDownQuery q4 = new DrillDownQuery(config, fooQuery);
            q4.Add("b");
            docs = searcher.Search(q4, 100);
            Assert.AreEqual(10, docs.TotalHits);
        }
 public virtual void TestNoDrillDown()
 {
     Query @base = new MatchAllDocsQuery();
     DrillDownQuery q = new DrillDownQuery(config, @base);
     Query rewrite = q.Rewrite(reader).Rewrite(reader);
     Assert.AreSame(@base, rewrite);
 }
        public virtual void TestClone()
        {
            var q = new DrillDownQuery(config, new MatchAllDocsQuery());
            q.Add("a");

            var clone = q.Clone() as DrillDownQuery;
            Assert.NotNull(clone);
            clone.Add("b");
            Assert.False(q.ToString().Equals(clone.ToString()), "query wasn't cloned: source=" + q + " clone=" + clone);
        }
        public virtual void TestAndOrs()
        {
            IndexSearcher searcher = NewSearcher(reader);

            // test (a/1 OR a/2) AND b/1
            DrillDownQuery q = new DrillDownQuery(config);
            q.Add("a", "1");
            q.Add("a", "2");
            q.Add("b", "1");
            TopDocs docs = searcher.Search(q, 100);
            Assert.AreEqual(5, docs.TotalHits);
        }
Esempio n. 8
0
 /// <summary>
 /// Search, sorting by score, and computing
 /// drill down and sideways counts.
 /// </summary>
 public virtual DrillSidewaysResult Search(DrillDownQuery query, int topN)
 {
     return(Search(null, query, topN));
 }
Esempio n. 9
0
 /// <summary>
 /// Search, sorting by score, and computing
 /// drill down and sideways counts.
 /// </summary>
 public virtual DrillSidewaysResult Search(ScoreDoc after, DrillDownQuery query, int topN)
 {
     int limit = searcher.IndexReader.MaxDoc;
     if (limit == 0)
     {
         limit = 1; // the collector does not alow numHits = 0
     }
     topN = Math.Min(topN, limit);
     TopScoreDocCollector hitCollector = TopScoreDocCollector.Create(topN, after, true);
     DrillSidewaysResult r = Search(query, hitCollector);
     return new DrillSidewaysResult(r.Facets, hitCollector.TopDocs());
 }
Esempio n. 10
0
 /// <summary>
 /// Search, sorting by score, and computing
 /// drill down and sideways counts.
 /// </summary>
 public virtual DrillSidewaysResult Search(DrillDownQuery query, int topN)
 {
     return Search(null, query, topN);
 }
Esempio n. 11
0
 /// <summary>
 /// Search, sorting by <seealso cref="Sort"/>, and computing
 /// drill down and sideways counts.
 /// </summary>
 public virtual DrillSidewaysResult Search(DrillDownQuery query, Filter filter, FieldDoc after, int topN, Sort sort, bool doDocScores, bool doMaxScore)
 {
     if (filter != null)
     {
         query = new DrillDownQuery(config, filter, query);
     }
     if (sort != null)
     {
         int limit = searcher.IndexReader.MaxDoc;
         if (limit == 0)
         {
             limit = 1; // the collector does not alow numHits = 0
         }
         topN = Math.Min(topN, limit);
         TopFieldCollector hitCollector = TopFieldCollector.Create(sort, topN, after, true, doDocScores, doMaxScore, true);
         DrillSidewaysResult r = Search(query, hitCollector);
         return new DrillSidewaysResult(r.Facets, hitCollector.TopDocs());
     }
     else
     {
         return Search(after, query, topN);
     }
 }
Esempio n. 12
0
        /// <summary>
        /// Search, collecting hits with a <seealso cref="Collector"/>, and
        /// computing drill down and sideways counts.
        /// </summary>
        public virtual DrillSidewaysResult Search(DrillDownQuery query, Collector hitCollector)
        {

            IDictionary<string, int?> drillDownDims = query.Dims;

            FacetsCollector drillDownCollector = new FacetsCollector();

            if (drillDownDims.Count == 0)
            {
                // There are no drill-down dims, so there is no
                // drill-sideways to compute:
                searcher.Search(query, MultiCollector.Wrap(hitCollector, drillDownCollector));
                return new DrillSidewaysResult(BuildFacetsResult(drillDownCollector, null, null), null);
            }

            BooleanQuery ddq = query.BooleanQuery;
            BooleanClause[] clauses = ddq.Clauses;

            Query baseQuery;
            int startClause;
            if (clauses.Length == drillDownDims.Count)
            {
                // TODO: we could optimize this pure-browse case by
                // making a custom scorer instead:
                baseQuery = new MatchAllDocsQuery();
                startClause = 0;
            }
            else
            {
                Debug.Assert(clauses.Length == 1 + drillDownDims.Count);
                baseQuery = clauses[0].Query;
                startClause = 1;
            }

            FacetsCollector[] drillSidewaysCollectors = new FacetsCollector[drillDownDims.Count];
            for (int i = 0; i < drillSidewaysCollectors.Length; i++)
            {
                drillSidewaysCollectors[i] = new FacetsCollector();
            }

            Query[] drillDownQueries = new Query[clauses.Length - startClause];
            for (int i = startClause; i < clauses.Length; i++)
            {
                drillDownQueries[i - startClause] = clauses[i].Query;
            }
            DrillSidewaysQuery dsq = new DrillSidewaysQuery(baseQuery, drillDownCollector, drillSidewaysCollectors, drillDownQueries, ScoreSubDocsAtOnce());
            searcher.Search(dsq, hitCollector);

            return new DrillSidewaysResult(BuildFacetsResult(drillDownCollector, drillSidewaysCollectors, drillDownDims.Keys.ToArray()), null);
        }