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



我已经开发了一个solr组件,该组件扩展了用户查询并在查询中添加了其他条款。对于此扩展,我们要求向外部REST API的API提出请求。此查询扩展逻辑主要是在preepar()方法中。在独立模式下,一切都按预期工作。当我们在SolrCloud环境中部署此插件时,每个碎片都调用外部REST API以进行查询扩展。

我的问题是,我们可以只对外部REST API进行一个呼叫,因为它与从每个碎片发送到外部服务的相同请求。我们如何修改组件以每个搜索请求仅拨打一个电话?

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

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

  • 硬件中的一个主机中的一个进入组件,并检查Local主机是否是硬有线主机。不过,这会使主机负载不平衡。
  • 进行任意测量,任何组件都可以检查自己,例如主机1-10在当前分钟等于主机数时发射外部请求。
  • 甚至在搜索前端扔一个骰子,将主机名通过查询参数送到solr,并让组件检查此参数(从responsebuilder.req.getParams()从其本地hostName中获取它。
  • 您可以在那里真正发挥创意。

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

请在Solr Wiki中阅读更多。

您可以使用的方法就像:

  • 将您的组件重写为RequestHandler(或仅通过标准请求Handler包装)
  • 使您的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处理。但是组件也可以处理这些条款。

最新更新