You are viewing a plain text version of this content. The canonical link for it is here.
Posted to solr-user@lucene.apache.org by Andrew Morrison <am...@etsy.com> on 2012/06/13 01:24:39 UTC

Interleaving Results from Sub-Queries

I'm working on creating a Query that interleaves the results of a set of
sub-queries and was hoping I could get some input on the design.

The general idea is that if given Query q1 and Query q2  I'd like to add
them to a parent Query q0 so that the when q0 is scored, the order of
results in score descending order is

   1. 1st doc from q1
   2. 1st doc from q2
   3. 2nd doc from q1
   4. 2nd doc from q2
   5. 3rd doc from q1
   6. ...

In the attached code, we add all sub-query Scorers to an InterleaveScorer
that

   - scores all docs from each sub-scorer,
   - puts those {doc, score} pairs in a heap
   - iteratively pops from each heap until each is out of documents

Can anyone think of a cleaner way of doing this?

Below is a test that shows a general outline of its functionality.

  @Test
  public void testSimple() {
    assertU(adoc("id", "0", "name", "alpha"));
    assertU(adoc("id", "1", "name", "alpha"));
    assertU(adoc("id", "2", "name", "alpha"));
    assertU(adoc("id", "3", "name", "beta"));
    assertU(adoc("id", "4", "name", "beta"));
    assertU(commit());

    SolrQueryRequest req =
      req("q", "{!interleave q0=name:alpha q1=name:beta}",
          "sort", "score desc",
          "fl", "id,score");

    assertQ("id 0 should be in position 1", req,
        "/response/result/doc[position()=1]/int[text()=0]");
    assertQ("position 1 should have score 100.0", req,
        "/response/result/doc[position()=1]/float[text()=100.0]");

    assertQ("id 3 should be in position 2", req,
        "/response/result/doc[position()=2]/int[text()=3]");
    assertQ("position 2 should have score 99.99999", req,
        "/response/result/doc[position()=2]/float[text()=99.99999]");

    assertQ("id 2 should be in position 3", req,
        "/response/result/doc[position()=3]/int[text()=2]");
    assertQ("position 3 should have score 99.99998", req,
        "/response/result/doc[position()=3]/float[text()=99.99998]");

    assertQ("id 4 should be in position 4", req,
        "/response/result/doc[position()=4]/int[text()=4]");
    assertQ("position 4 should have score 99.99997", req,
        "/response/result/doc[position()=4]/float[text()=99.99997]");

    assertQ("id 1 should be in position 5", req,
        "/response/result/doc[position()=5]/int[text()=1]");
    assertQ("position 5 should have score 99.99996", req,
        "/response/result/doc[position()=5]/float[text()=99.99996]");
  }


Andrew Morrison | Software Engineer | Etsy