/// <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); }
/// <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)); }
/// <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()); }
/// <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); }
/// <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); } }
/// <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); }