public void testBooleanOptionalNoTiebreaker() throws Exception {

    BooleanQuery q = new BooleanQuery();
    {
      DisjunctionMaxQuery q1 = new DisjunctionMaxQuery(0.0f);
      q1.add(tq("hed", "albino"));
      q1.add(tq("dek", "albino"));
      q.add(q1, BooleanClause.Occur.SHOULD); // false,false);
    }
    {
      DisjunctionMaxQuery q2 = new DisjunctionMaxQuery(0.0f);
      q2.add(tq("hed", "elephant"));
      q2.add(tq("dek", "elephant"));
      q.add(q2, BooleanClause.Occur.SHOULD); // false,false);
    }
    QueryUtils.check(q, s);

    ScoreDoc[] h = s.search(q, null, 1000).scoreDocs;

    try {
      assertEquals("4 docs should match " + q.toString(), 4, h.length);
      float score = h[0].score;
      for (int i = 1; i < h.length - 1; i++) {
        /* note: -1 */
        assertEquals("score #" + i + " is not the same", score, h[i].score, SCORE_COMP_THRESH);
      }
      assertEquals("wrong last", "d1", s.doc(h[h.length - 1].doc).get("id"));
      float score1 = h[h.length - 1].score;
      assertTrue(
          "d1 does not have worse score then others: " + score + " >? " + score1, score > score1);
    } catch (Error e) {
      printHits("testBooleanOptionalNoTiebreaker", h, s);
      throw e;
    }
  }
  public void testBooleanRequiredEqualScores() throws Exception {

    BooleanQuery q = new BooleanQuery();
    {
      DisjunctionMaxQuery q1 = new DisjunctionMaxQuery(0.0f);
      q1.add(tq("hed", "albino"));
      q1.add(tq("dek", "albino"));
      q.add(q1, BooleanClause.Occur.MUST); // true,false);
      QueryUtils.check(q1, s);
    }
    {
      DisjunctionMaxQuery q2 = new DisjunctionMaxQuery(0.0f);
      q2.add(tq("hed", "elephant"));
      q2.add(tq("dek", "elephant"));
      q.add(q2, BooleanClause.Occur.MUST); // true,false);
      QueryUtils.check(q2, s);
    }

    QueryUtils.check(q, s);

    ScoreDoc[] h = s.search(q, null, 1000).scoreDocs;

    try {
      assertEquals("3 docs should match " + q.toString(), 3, h.length);
      float score = h[0].score;
      for (int i = 1; i < h.length; i++) {
        assertEquals("score #" + i + " is not the same", score, h[i].score, SCORE_COMP_THRESH);
      }
    } catch (Error e) {
      printHits("testBooleanRequiredEqualScores1", h, s);
      throw e;
    }
  }
  public void testDMQ7() throws Exception {
    DisjunctionMaxQuery q = new DisjunctionMaxQuery(0.5f);

    BooleanQuery booleanQuery = new BooleanQuery();
    booleanQuery.add(new TermQuery(new Term(FIELD, "yy")), BooleanClause.Occur.MUST_NOT);
    booleanQuery.add(new TermQuery(new Term(FIELD, "w3")), BooleanClause.Occur.SHOULD);

    q.add(booleanQuery);
    q.add(new TermQuery(new Term(FIELD, "w2")));
    qtest(q, new int[] {0, 1, 2, 3});
  }
  public void testSkipToFirsttimeHit() throws IOException {
    final DisjunctionMaxQuery dq = new DisjunctionMaxQuery(0.0f);
    dq.add(tq("dek", "albino"));
    dq.add(tq("dek", "DOES_NOT_EXIST"));

    QueryUtils.check(dq, s);

    final Weight dw = dq.weight(s);
    final Scorer ds = dw.scorer(s.getIndexReader(), true, false);
    assertTrue("firsttime skipTo found no match", ds.advance(3) != DocIdSetIterator.NO_MORE_DOCS);
    assertEquals("found wrong docid", "d4", r.document(ds.docID()).get("id"));
  }
  public void testBooleanOptionalWithTiebreakerAndBoost() throws Exception {

    BooleanQuery q = new BooleanQuery();
    {
      DisjunctionMaxQuery q1 = new DisjunctionMaxQuery(0.01f);
      q1.add(tq("hed", "albino", 1.5f));
      q1.add(tq("dek", "albino"));
      q.add(q1, BooleanClause.Occur.SHOULD); // false,false);
    }
    {
      DisjunctionMaxQuery q2 = new DisjunctionMaxQuery(0.01f);
      q2.add(tq("hed", "elephant", 1.5f));
      q2.add(tq("dek", "elephant"));
      q.add(q2, BooleanClause.Occur.SHOULD); // false,false);
    }
    QueryUtils.check(q, s);

    ScoreDoc[] h = s.search(q, null, 1000).scoreDocs;

    try {

      assertEquals("4 docs should match " + q.toString(), 4, h.length);

      float score0 = h[0].score;
      float score1 = h[1].score;
      float score2 = h[2].score;
      float score3 = h[3].score;

      String doc0 = s.doc(h[0].doc).get("id");
      String doc1 = s.doc(h[1].doc).get("id");
      String doc2 = s.doc(h[2].doc).get("id");
      String doc3 = s.doc(h[3].doc).get("id");

      assertEquals("doc0 should be d4: ", "d4", doc0);
      assertEquals("doc1 should be d3: ", "d3", doc1);
      assertEquals("doc2 should be d2: ", "d2", doc2);
      assertEquals("doc3 should be d1: ", "d1", doc3);

      assertTrue(
          "d4 does not have a better score then d3: " + score0 + " >? " + score1, score0 > score1);
      assertTrue(
          "d3 does not have a better score then d2: " + score1 + " >? " + score2, score1 > score2);
      assertTrue(
          "d3 does not have a better score then d1: " + score2 + " >? " + score3, score2 > score3);

    } catch (Error e) {
      printHits("testBooleanOptionalWithTiebreakerAndBoost", h, s);
      throw e;
    }
  }
  public void testBooleanOptionalWithTiebreaker() throws Exception {

    BooleanQuery q = new BooleanQuery();
    {
      DisjunctionMaxQuery q1 = new DisjunctionMaxQuery(0.01f);
      q1.add(tq("hed", "albino"));
      q1.add(tq("dek", "albino"));
      q.add(q1, BooleanClause.Occur.SHOULD); // false,false);
    }
    {
      DisjunctionMaxQuery q2 = new DisjunctionMaxQuery(0.01f);
      q2.add(tq("hed", "elephant"));
      q2.add(tq("dek", "elephant"));
      q.add(q2, BooleanClause.Occur.SHOULD); // false,false);
    }
    QueryUtils.check(q, s);

    ScoreDoc[] h = s.search(q, null, 1000).scoreDocs;

    try {

      assertEquals("4 docs should match " + q.toString(), 4, h.length);

      float score0 = h[0].score;
      float score1 = h[1].score;
      float score2 = h[2].score;
      float score3 = h[3].score;

      String doc0 = s.doc(h[0].doc).get("id");
      String doc1 = s.doc(h[1].doc).get("id");
      String doc2 = s.doc(h[2].doc).get("id");
      String doc3 = s.doc(h[3].doc).get("id");

      assertTrue("doc0 should be d2 or d4: " + doc0, doc0.equals("d2") || doc0.equals("d4"));
      assertTrue("doc1 should be d2 or d4: " + doc0, doc1.equals("d2") || doc1.equals("d4"));
      assertEquals("score0 and score1 should match", score0, score1, SCORE_COMP_THRESH);
      assertEquals("wrong third", "d3", doc2);
      assertTrue(
          "d3 does not have worse score then d2 and d4: " + score1 + " >? " + score2,
          score1 > score2);

      assertEquals("wrong fourth", "d1", doc3);
      assertTrue(
          "d1 does not have worse score then d3: " + score2 + " >? " + score3, score2 > score3);

    } catch (Error e) {
      printHits("testBooleanOptionalWithTiebreaker", h, s);
      throw e;
    }
  }
  public void testSkipToFirsttimeMiss() throws IOException {
    final DisjunctionMaxQuery dq = new DisjunctionMaxQuery(0.0f);
    dq.add(tq("id", "d1"));
    dq.add(tq("dek", "DOES_NOT_EXIST"));

    QueryUtils.check(dq, s);

    final Weight dw = dq.weight(s);
    final Scorer ds = dw.scorer(s.getIndexReader(), true, false);
    final boolean skipOk = ds.advance(3) != DocIdSetIterator.NO_MORE_DOCS;
    if (skipOk) {
      fail("firsttime skipTo found a match? ... " + r.document(ds.docID()).get("id"));
    }
  }
 protected Query dmq(float tieBreakerMultiplier, Query... queries) {
   DisjunctionMaxQuery query = new DisjunctionMaxQuery(tieBreakerMultiplier);
   for (Query q : queries) {
     query.add(q);
   }
   return query;
 }
  public void testDMQ9() throws Exception {
    DisjunctionMaxQuery q = new DisjunctionMaxQuery(0.5f);

    BooleanQuery booleanQuery = new BooleanQuery();
    booleanQuery.add(new TermQuery(new Term(FIELD, "yy")), BooleanClause.Occur.SHOULD);

    TermQuery boostedQuery = new TermQuery(new Term(FIELD, "w5"));
    boostedQuery.setBoost(100);
    booleanQuery.add(boostedQuery, BooleanClause.Occur.SHOULD);
    q.add(booleanQuery);

    TermQuery xxBoostedQuery = new TermQuery(new Term(FIELD, "xx"));
    xxBoostedQuery.setBoost(0);
    q.add(xxBoostedQuery);

    qtest(q, new int[] {0, 2, 3});
  }
  public void testSimpleEqualScores2() throws Exception {

    DisjunctionMaxQuery q = new DisjunctionMaxQuery(0.0f);
    q.add(tq("dek", "albino"));
    q.add(tq("dek", "elephant"));
    QueryUtils.check(q, s);

    ScoreDoc[] h = s.search(q, null, 1000).scoreDocs;

    try {
      assertEquals("3 docs should match " + q.toString(), 3, h.length);
      float score = h[0].score;
      for (int i = 1; i < h.length; i++) {
        assertEquals("score #" + i + " is not the same", score, h[i].score, SCORE_COMP_THRESH);
      }
    } catch (Error e) {
      printHits("testSimpleEqualScores2", h, s);
      throw e;
    }
  }
  public void testSimpleTiebreaker() throws Exception {

    DisjunctionMaxQuery q = new DisjunctionMaxQuery(0.01f);
    q.add(tq("dek", "albino"));
    q.add(tq("dek", "elephant"));
    QueryUtils.check(q, s);

    ScoreDoc[] h = s.search(q, null, 1000).scoreDocs;

    try {
      assertEquals("3 docs should match " + q.toString(), 3, h.length);
      assertEquals("wrong first", "d2", s.doc(h[0].doc).get("id"));
      float score0 = h[0].score;
      float score1 = h[1].score;
      float score2 = h[2].score;
      assertTrue(
          "d2 does not have better score then others: " + score0 + " >? " + score1,
          score0 > score1);
      assertEquals("d4 and d1 don't have equal scores", score1, score2, SCORE_COMP_THRESH);
    } catch (Error e) {
      printHits("testSimpleTiebreaker", h, s);
      throw e;
    }
  }
  public Query getQuery(Element e) throws ParserException {
    float tieBreaker = DOMUtils.getAttribute(e, "tieBreaker", 0.0f);
    DisjunctionMaxQuery dq = new DisjunctionMaxQuery(tieBreaker);
    dq.setBoost(DOMUtils.getAttribute(e, "boost", 1.0f));

    NodeList nl = e.getChildNodes();
    for (int i = 0; i < nl.getLength(); i++) {
      Node node = nl.item(i);
      if (node instanceof Element) { // all elements are disjuncts.
        Element queryElem = (Element) node;
        Query q = factory.getQuery(queryElem);
        dq.add(q);
      }
    }

    return dq;
  }
 /**
  * Creates a new DisjunctionMaxQuery
  *
  * @param disjuncts a {@code Collection<Query>} of all the disjuncts to add
  * @param tieBreakerMultiplier the weight to give to each matching non-maximum disjunct
  */
 public DisjunctionMaxQuery(Collection<Query> disjuncts, float tieBreakerMultiplier) {
   this.tieBreakerMultiplier = tieBreakerMultiplier;
   add(disjuncts);
 }
 public void testDMQ4() throws Exception {
   DisjunctionMaxQuery q = new DisjunctionMaxQuery(0.5f);
   q.add(new TermQuery(new Term(FIELD, "QQ")));
   q.add(new TermQuery(new Term(FIELD, "xx")));
   qtest(q, new int[] {2, 3});
 }
 public void testDMQ2() throws Exception {
   DisjunctionMaxQuery q = new DisjunctionMaxQuery(0.5f);
   q.add(new TermQuery(new Term(FIELD, "w1")));
   q.add(new TermQuery(new Term(FIELD, "w5")));
   qtest(q, new int[] {0, 1, 2, 3});
 }