自定义Solr组件插件中的查询构造

时间:2017-02-27 08:49:42

标签: solr

我开发了一个solr组件,它扩展了用户查询并为查询添加了其他子句。对于此扩展,我们向外部REST api提出请求。此查询扩展逻辑主要在prepare()方法中。在独立模式下,一切都按预期工作。当我们在SolrCloud环境中部署此插件时,每个分片都会调用外部REST API来进行查询扩展。

我的问题是,我们可以只对外部REST api进行一次调用,因为它从每个分片发送到外部服务的请求相同。我们如何修改我们的组件,使每个搜索请求只能调用一次?

2 个答案:

答案 0 :(得分:0)

您可以使用的方法如下:

  • 将您的组件重写为requestHandler(或只是通过标准requestHandler包装)
  • 让你的requestHandler知道特殊标志,它会触发/不触发你自己的自定义逻辑。我的意思是这样的(我知道这不是幻想):

    public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception {
        ...
        SolrParams params = req.getParams();
        if (req.getParams().get("apiCallWasSent") == null) {
            makeApiCall(req, rsp);
            params = new ModifiableSolrParams(params);
            params.add("apiCallWasSent", "true");
            req.setParams(params);
        }
        ...
        super.handleRequestBody(req, rsp);
    }
    
  • 在我看来,这些额外的查询子句以及与查询本身相关的所有内容都应由您自己的QParserPlugin处理。但组件也可以处理这些条款。

答案 1 :(得分:0)

在prepare()方法中,就在外部API调用之前,您可以检查RequestBuilder.isDistrib()。对于即将分发的请求,此布尔值将为true。然后,您可以使用此信息来确定是否可以只执行外部请求,或者您需要设置一个执行此任务的SolrCloud主机。

如何确定用于外部API的SolrCloud主机?你可以......

  • 将其中一个主机硬连线到组件中,并检查localhost是否为硬连线主机。但这会使主机负载失衡。
  • 任意组件可以检查自己的任意测量,如主机1-10在当前分钟等于主机号码时触发外部请求。
  • 甚至在搜索前端掷骰子,通过查询参数将主机名提供给Solr,并让组件检查此参数(从ResponseBuilder.req.getParams()获取它的本地主机名。
  • 你可以在那里获得真正的创意。

从外部API获得答案后,​​您可以使用modifyRequest()更新结果中的所有其他主机。

请在Solr Wiki

中阅读更多内容