Solr Performance为许多文档查询

Mar*_*aun 1 java lucene performance solr

我希望Solr始终检索搜索找到的所有文档(我知道Solr不是为此而构建的,但无论如何)我目前正在使用以下代码执行此操作:

    ...
    List<Article> ret = new ArrayList<Article>();
    QueryResponse response = solr.query(query);
    int offset = 0;
    int totalResults = (int) response.getResults().getNumFound();
    List<Article> ret = new ArrayList<Article>((int) totalResults);
    query.setRows(FETCH_SIZE);
    while(offset < totalResults) {
        //requires an int? wtf?
        query.setStart((int) offset);
        int left = totalResults - offset;
        if(left < FETCH_SIZE) {
            query.setRows(left);
        }
        response = solr.query(query);
        List<Article> current = response.getBeans(Article.class);
        offset += current.size();
        ret.addAll(current);
    }
   ...
Run Code Online (Sandbox Code Playgroud)

这是有效的,但是如果查询超过1000次点击则相当慢(我在这里读到了这个.这是由Solr引起的,因为我每次都设置启动 - 由于某种原因 - 需要一些时间).什么是更好(和更快)的方法来做到这一点?

che*_*ffe 8

要改进建议的答案,您可以使用流式响应.特别是在获取所有结果的情况下添加了这个.正如你在Solr的Jira中所看到的那样,那个人想和你一样做.这已经在Solr 4中实现.

这也在Solrj的javadoc中描述.

在开始发送响应之前,Solr将打包响应并创建整个XML/JSON文档.然后您的客户需要解压所有这些并将其作为列表提供给您.通过使用流式和并行处理(使用这种排队方法时可以执行此操作),性能应该进一步提高.

是的,你将失去自动bean映射,但由于性能是一个因素,我认为这是可以接受的.

这是一个样本单元测试:

public class StreamingTest {

  @Test
  public void streaming() throws SolrServerException, IOException, InterruptedException {
    HttpSolrServer server = new HttpSolrServer("http://your-server");
    SolrQuery tmpQuery = new SolrQuery("your query");
    tmpQuery.setRows(Integer.MAX_VALUE);
    final BlockingQueue<SolrDocument> tmpQueue = new LinkedBlockingQueue<SolrDocument>();
    server.queryAndStreamResponse(tmpQuery, new MyCallbackHander(tmpQueue));
    SolrDocument tmpDoc;
    do {
      tmpDoc = tmpQueue.take();
    } while (!(tmpDoc instanceof PoisonDoc));
  }

  private class PoisonDoc extends SolrDocument {
    // marker to finish queuing
  }

  private class MyCallbackHander extends StreamingResponseCallback {
    private BlockingQueue<SolrDocument> queue;
    private long currentPosition;
    private long numFound;

    public MyCallbackHander(BlockingQueue<SolrDocument> aQueue) {
      queue = aQueue;
    }

    @Override
    public void streamDocListInfo(long aNumFound, long aStart, Float aMaxScore) {
      // called before start of streaming
      // probably use for some statistics
      currentPosition = aStart;
      numFound = aNumFound;
      if (numFound == 0) {
        queue.add(new PoisonDoc());
      }
    }

    @Override
    public void streamSolrDocument(SolrDocument aDoc) {
      currentPosition++;
      System.out.println("adding doc " + currentPosition + " of " + numFound);
      queue.add(aDoc);
      if (currentPosition == numFound) {
        queue.add(new PoisonDoc());
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)