Java 在Solr组件准备方法内执行分布式搜索
我正在编写一个自定义Solr组件。在组件的prepare方法中,我正在执行一个作为自定义参数给出的查询(在Java 在Solr组件准备方法内执行分布式搜索,java,solr,lucene,sharding,Java,Solr,Lucene,Sharding,我正在编写一个自定义Solr组件。在组件的prepare方法中,我正在执行一个作为自定义参数给出的查询(在req.params中)。我不是在prepare方法中运行q参数查询,而是在自定义参数中定义的另一个输入查询。我正在使用定制输入查询返回的文档在prepare方法中做一些准备工作 问题在于,由于我的索引分布在多个分片中,因此自定义查询返回的文档仅位于其中一个分片上。换句话说,在我的prepare方法中执行的搜索不是分布式的,我得到的是部分结果。这或多或少是我在prepare方法中执行搜索的方
req.params
中)。我不是在prepare方法中运行q
参数查询,而是在自定义参数中定义的另一个输入查询。我正在使用定制输入查询返回的文档在prepare方法中做一些准备工作
问题在于,由于我的索引分布在多个分片中,因此自定义查询返回的文档仅位于其中一个分片上。换句话说,在我的prepare方法中执行的搜索不是分布式的,我得到的是部分结果。这或多或少是我在prepare方法中执行搜索的方式:
rb.req.getSearcher().getDocList(customQuery, null, null, offset, len, 0);
有没有办法在prepare方法中进行分布式搜索,并从所有碎片中获取匹配的文档
编辑: 我目前的解决方案是使用Solrj执行查询,大致如下所示:
SolrServer server = new HttpSolrServer(url);
SolrQuery request = new SolrQuery(customQuery);
NamedList queryResponse = server.query(request).getResponse();
然后解析响应以获取返回文档的内容。我不喜欢我的解决方案有几个原因。原因之一是我必须解析响应。但主要原因是我必须将Solr服务器url作为参数传递。我将url放在solrconfig.xml
文件中。是否可以在不显式声明Solr服务器url的情况下(可能通过ZooKeeper)以某种方式构造SolrServer实例?简单的方法
用于执行分布式查询。向其提供Zookeeper url和集合名称(可在响应生成器中获得):
现在,每个碎片将执行由您在其自己的核心上设置的参数定义的请求。这将发生在舞台上。您仍然需要处理碎片的响应,组合它们并使用它们。处理所有这些响应的正确位置是在组件的handleResponses
方法中。因此,如果处于正确的阶段,请覆盖handleResponses
,并对碎片响应执行任何需要执行的操作。您可能需要将它们保存在某个位置,以便稍后在finishStage
方法中引用它们
@Override public void handleResponses(ResponseBuilder rb, ShardRequest sreq) {
...
if (stage == MY_STAGE) {
List<ShardResponse> responses = sreq.responses;
for (ShardResponse response : responses) {
//do something with the response, maybe save it somewhere
rb.finished.remove(sreq);
}
}
...
}
重要的信息是使用响应生成器阶段来控制组件相对于其他组件的执行流。如果希望在执行实际查询之前执行代码,则不必将代码放入prepare方法。您只需创建或使用一个阶段,该阶段是stage\u START
和stage\u EXECUTE\u QUERY
的中间阶段
用于执行分布式查询。向其提供Zookeeper url和集合名称(可在响应生成器中获得):
现在,每个碎片将执行由您在其自己的核心上设置的参数定义的请求。这将发生在舞台上。您仍然需要处理碎片的响应,组合它们并使用它们。处理所有这些响应的正确位置是在组件的handleResponses
方法中。因此,如果处于正确的阶段,请覆盖handleResponses
,并对碎片响应执行任何需要执行的操作。您可能需要将它们保存在某个位置,以便稍后在finishStage
方法中引用它们
@Override public void handleResponses(ResponseBuilder rb, ShardRequest sreq) {
...
if (stage == MY_STAGE) {
List<ShardResponse> responses = sreq.responses;
for (ShardResponse response : responses) {
//do something with the response, maybe save it somewhere
rb.finished.remove(sreq);
}
}
...
}
重要的信息是使用响应生成器阶段来控制组件相对于其他组件的执行流。如果希望在执行实际查询之前执行代码,则不必将代码放入prepare方法。您只需创建或使用一个介于stage\u START
和stage\u EXECUTE\u QUERY
之间的阶段
@Override public void handleResponses(ResponseBuilder rb, ShardRequest sreq) {
...
if (stage == MY_STAGE) {
List<ShardResponse> responses = sreq.responses;
for (ShardResponse response : responses) {
//do something with the response, maybe save it somewhere
rb.finished.remove(sreq);
}
}
...
}
@Override public void finishStage(ResponseBuilder rb) {
...
if (rb.stage == MY_STAGE) {
// do whatever you need to do with the results
}
...
}