在SOLR中快速检索大型数据集

时间:2016-12-07 17:42:38

标签: solr solrj

在SOLR中快速检索大型数据集的最佳方法是什么?

我的索引有1000万条记录(6个字符串字段)。我使用的查询和过滤器将结果集降低到270万条记录,我希望以编程方式分页并获取另一个进程的数据。

目前我使用SOLRJ和cursorMark一次获得300000条记录。每个查询需要15-20秒。有没有办法提高速度?减少"块的大小"似乎没有效果。将300000减少到50000的含义使得查询更快,但是它们中的更多并且总时间相当。

我认为问题是SOLR必须获得整个2.7mil的结果集,然后在每次调用时将间隔需求减少。将其与"尺寸相结合"结果集,我可以理解为什么它很慢。我正在寻找加速它的一些想法。

我的SOLRJ代码如下:

Solr版本:4.10.2

SolrQuery query = new SolrQuery();
query.setQuery("*:*");
query.setFilterQueries("text:\"*SEARCH STUFF*\"");
query.setParam("fl","id,srfCode");
query.setStart(0);
query.setRows(300000);
query.setSort("sortId", SolrQuery.ORDER.asc);
query.set("cursorMark", "*");

UPDATE 我尝试了以下尝试" stream" solr的数据。不幸的是,查询本身仍然是获取数据的瓶颈。一旦我拥有它,我可以快速处理它。但我仍然需要一种更快的方式来获取数据。

package org.search.builder;

import java.io.IOException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.StreamingResponseCallback;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.apache.solr.common.SolrDocument;
import org.junit.Test;

public class SolrStream {

     long startTime = 0;
     long endTime = 0;

      @Test
      public void streaming() throws SolrServerException, IOException, InterruptedException {
        long overallstartTime = System.currentTimeMillis();
        startTime = System.currentTimeMillis();

        HttpSolrServer server = new HttpSolrServer("https://solrserver/solr/indexname");
        SolrQuery tmpQuery = new SolrQuery();
        tmpQuery.setQuery("*:*");
        tmpQuery.setFilterQueries("text:\"*SEARCH STUFF*\"");
        tmpQuery.setParam("fl","id,srfCode");
        tmpQuery.setStart(0);
        tmpQuery.setRows(300000);
        tmpQuery.set("cursorMark", "*");
        //Sort needs to be unique or have tie breakers.  In this case rowId will never be a duplicate
        //If you can have duplicates then you need a tie breaker (sort should include a second column to sort on)
        tmpQuery.setSort("rowId", SolrQuery.ORDER.asc);
        final BlockingQueue<SolrDocument> tmpQueue = new LinkedBlockingQueue<SolrDocument>();
        server.queryAndStreamResponse(tmpQuery, new MyCallbackHander(tmpQueue));
        SolrDocument tmpDoc;
        do {
          tmpDoc = tmpQueue.take();
        } while (!(tmpDoc instanceof StopDoc));

        System.out.println("Overall Time: " + (System.currentTimeMillis() - overallstartTime) + " ms");
      }

      private class StopDoc 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 StopDoc());
          }
        }

        @Override
        public void streamSolrDocument(SolrDocument aDoc) {
          currentPosition++;
          if (queue.size() % 50000 == 0)
          {
              System.out.println("adding doc " + currentPosition + " of " + numFound);
              System.out.println("Overall Time: " + (System.currentTimeMillis() - startTime) + " ms");
              startTime = System.currentTimeMillis();

          }
          queue.add(aDoc);
          if (currentPosition == numFound) {
            queue.add(new StopDoc());
          }
        }
      }
}

1 个答案:

答案 0 :(得分:0)

MatsLindh对导出请求处理程序的建议工作得很好。

将此requestHandler添加到solrconfig(如果尚未存在)

  <requestHandler name="/export" class="solr.SearchHandler">
    <lst name="invariants">
      <str name="rq">{!xport}</str>
      <str name="wt">xsort</str>
      <str name="distrib">false</str>
    </lst>

    <arr name="components">
      <str>query</str>
    </arr>
  </requestHandler>

然后这样称呼它: / export?q = rowId:[1 TO 4000]&amp; fq = text:\&#34; STUFF \&#34;&amp; fl = field1,field2&amp; sort = sortColumn asc

*您需要排序并拥有一组fl

现在我只需要弄清楚如何让/ export在solrcloud设置中工作。

谢谢!