public void testTermNonDefault() {
    String aField = config.getDimConfig("a").indexFieldName;
    Term termA = DrillDownQuery.term(aField, "a");
    assertEquals(new Term(aField, "a"), termA);

    String bField = config.getDimConfig("b").indexFieldName;
    Term termB = DrillDownQuery.term(bField, "b");
    assertEquals(new Term(bField, "b"), termB);
  }
  /**
   * Search, collecting hits with a {@link Collector}, and computing drill down and sideways counts.
   */
  @SuppressWarnings({"rawtypes", "unchecked"})
  public DrillSidewaysResult search(DrillDownQuery query, Collector hitCollector)
      throws IOException {

    Map<String, Integer> drillDownDims = query.getDims();

    FacetsCollector drillDownCollector = new FacetsCollector();

    if (drillDownDims.isEmpty()) {
      // 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.getBooleanQuery();
    BooleanClause[] clauses = ddq.getClauses();

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

    FacetsCollector[] drillSidewaysCollectors = new FacetsCollector[drillDownDims.size()];
    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].getQuery();
    }
    DrillSidewaysQuery dsq =
        new DrillSidewaysQuery(
            baseQuery,
            drillDownCollector,
            drillSidewaysCollectors,
            drillDownQueries,
            scoreSubDocsAtOnce());
    searcher.search(dsq, hitCollector);

    return new DrillSidewaysResult(
        buildFacetsResult(
            drillDownCollector,
            drillSidewaysCollectors,
            drillDownDims.keySet().toArray(new String[drillDownDims.size()])),
        null);
  }
  public void testScoringNoBaseQuery() throws IOException {
    // 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
    for (ScoreDoc sd : docs.scoreDocs) {
      assertEquals(0f, sd.score, 0f);
    }
  }
  public void testAndOrs() throws Exception {
    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);
    assertEquals(5, docs.totalHits);
  }
  public void testQuery() throws IOException {
    IndexSearcher searcher = newSearcher(reader);

    // Making sure the query yields 25 documents with the facet "a"
    DrillDownQuery q = new DrillDownQuery(config);
    q.add("a");
    System.out.println("q=" + q);
    QueryUtils.check(q);
    TopDocs docs = searcher.search(q, 100);
    assertEquals(25, docs.totalHits);

    // 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");
    docs = searcher.search(q2, 100);
    assertEquals(5, docs.totalHits);

    // Making sure that a query of both facet "a" and facet "b" yields 5 results
    DrillDownQuery q3 = new DrillDownQuery(config);
    q3.add("a");
    q3.add("b");
    docs = searcher.search(q3, 100);

    assertEquals(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);
    assertEquals(10, docs.totalHits);
  }
  public void testScoring() throws IOException {
    // 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
    for (ScoreDoc sd : 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
    for (ScoreDoc sd : docs.scoreDocs) {
      assertEquals("score of doc=" + sd.doc + " modified", scores[sd.doc], sd.score, 0f);
    }
  }
  public void testClone() throws Exception {
    DrillDownQuery q = new DrillDownQuery(config, new MatchAllDocsQuery());
    q.add("a");

    DrillDownQuery clone = q.clone();
    clone.add("b");

    assertFalse(
        "query wasn't cloned: source=" + q + " clone=" + clone,
        q.toString().equals(clone.toString()));
  }
  private TopDocsName drillDown(Map<String, String> facets_value) throws IOException {

    // Passing no baseQuery means we drill down on all
    // documents ("browse only"):

    DrillDownQuery q = new DrillDownQuery(taxoConfig);

    for (Map.Entry<String, String> entry : facets_value.entrySet()) {
      q.add(entry.getKey(), entry.getValue());
    }

    FacetsCollector fc = new FacetsCollector();
    TopDocs docs = FacetsCollector.search(indexSearcher, q, 100000, fc);

    List<TopDocName> topDocNames = new ArrayList<TopDocName>();

    for (ScoreDoc scoreDoc : docs.scoreDocs) {
      String filename = indexSearcher.doc(scoreDoc.doc).get("filename");
      String videoID = indexSearcher.doc(scoreDoc.doc).get("videoID");
      String frameNumber = indexSearcher.doc(scoreDoc.doc).get("frameNumber");
      float score = scoreDoc.score;
      TopDocName docname = new TopDocName(score, filename, videoID, frameNumber);
      topDocNames.add(docname);
    }

    List<FacetResult> facetResults = new ArrayList<FacetResult>();

    // Count both "Publish Date" and "Author" dimensions
    Facets facets = new FastTaxonomyFacetCounts(taxoReader, taxoConfig, fc);
    facetResults.add(facets.getTopChildren(11, "person"));
    facetResults.add(facets.getTopChildren(20, "objects"));
    facetResults.add(facets.getTopChildren(200, "background"));
    TopDocsName results = new TopDocsName(1.0f, topDocNames, facetResults);

    return results;
  }
  public void testQueryImplicitDefaultParams() throws IOException {
    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);
    assertEquals(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);
    assertEquals(10, docs.totalHits);
  }
 public void testNoDrillDown() throws Exception {
   Query base = new MatchAllDocsQuery();
   DrillDownQuery q = new DrillDownQuery(config, base);
   Query rewrite = q.rewrite(reader).rewrite(reader);
   assertSame(base, rewrite);
 }