Solr - 上传 XML 文件,使用 XSLT 处理并在 URL 中提供额外的字段值

Solr - Upload XML file, process with XSLT and supply extra field values in URL

我正在尝试将 XML 文档(RSS 提要)上传到 Solr。我称之为索引文件

curl "http://localhost:8983/solr/1-3/update?commit=true&commitWithin=10000&tr=updateXml.xsl&literalsOverride=true&literal.client_uid=3" -H "Content-Type: text/xml" --data-binary @myfile.xml

核心名称是 1-3,它正确处理文件,当我不包含 [=16= 时,我可以搜索我在 schema.xml 中指定的所有产品和字段] 在架构中或将其设为 optional 字段。

这是我想包含在 URL 中的额外字段(文档本身没有此值)

<field name="client_uid" type="long" indexed="true" stored="true" multiValued="false" required="true"/>

我的文件中有大约 22,000 个文档。我尝试通过 URL 中的 literal.client_uid 参数提供值,但出现此错误。

<?xml version="1.0" encoding="UTF-8"?>
<response>
<lst name="responseHeader"><int name="status">400</int><int name="QTime">3007</int></lst><lst name="error"><str name="msg">[doc=117755] missing required field: client_uid</str><int name="code">400</int></lst>
</response>

我正在使用 Solr 5.4.0

怎么了?

您的问题是关于在 update-request.

中使用 literalsOverride-参数

答案简而言之:默认情况下 solrconfig.xml 路径 /update 连接到 UpdateRequestHandler (which support parameter tr) and the path /update/extract is connected to (tika)ExtractingRequestHandler(使用参数 literalsOverride)。

在你的情况下/updatetr是个好主意,但你不能用literalsOverride就是这种情况。您也无法从 XSL-Transformation 内部访问 url-parameters(这对于 XSLTResponseWriter 是可能的)。

恕我直言,您有四种可能性:

  • 生成updateXml1.xsl和updateXml2.xsl和updateXml3.xsl,唯一的区别在于设置字段的值
  • 对不同的核心使用不同的 schema.xml 并将您的值设置为 schema.xml
  • 中的 default-values
  • 在将 RSS 提要发送到 solr 之前更改它
  • 更改 solr org.apache.solr.handler.loader.XMLLoader.getTransformer(String, SolrQueryRequest)

想通了。正如 @Karsten R. 所解释的,它不会工作,因为请求处理程序不同并且 UpdateRequestHandler 不支持它。

我决定使用 updateRequestProcessorChain(在 solrconfig.xml 中)并创建了一个 .jar 库,其中包含一个新的 UpdateRequestProcessorFactory class处理器链。

来自 solrconfig.xml

的快照
<updateRequestProcessorChain name="mychain">
  <processor class="mypackage.solr.MyNewProcessorFactory"/>
  <processor class="solr.LogUpdateProcessorFactory" />
  <processor class="solr.RunUpdateProcessorFactory" />
</updateRequestProcessorChain>`

Solr 插件的代码(这个 .jar 文件进入 lib 文件夹,其中 solr.xml 是 - 您需要第一次自己创建 lib 文件夹)

package dreamagility.solr;

import java.io.IOException;

import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.update.AddUpdateCommand;
import org.apache.solr.update.processor.UpdateRequestProcessor;
import org.apache.solr.update.processor.UpdateRequestProcessorFactory;

/**
 * Created by Daniel on 06/01/2016.
 *
 * Adds extra tags to each document to be able to filter based on the client id it belongs to
 * This is something that is not included as a part of the feed which is indexed but it will be supplied with
 * the URL as a parameter.
 */
public class MyNewProcessorFactory extends UpdateRequestProcessorFactory {

    @Override
    public UpdateRequestProcessor getInstance(SolrQueryRequest solrQueryRequest, SolrQueryResponse solrQueryResponse, UpdateRequestProcessor updateRequestProcessor) {
        return new MyNewProcessorFactory(solrQueryRequest, solrQueryResponse, updateRequestProcessor);
    }
}

class MyNewProcessorFactoryextends UpdateRequestProcessor {
    private SolrQueryRequest solrQueryRequest;
    private SolrQueryResponse solrQueryResponse;
    private UpdateRequestProcessor updateRequestProcessor;

    public MyNewProcessorFactory(SolrQueryRequest _solrQueryRequest, SolrQueryResponse _solrQueryResponse, UpdateRequestProcessor _updateRequestProcessor) {
        super(_updateRequestProcessor);

        this.solrQueryRequest = _solrQueryRequest;
        this.solrQueryResponse = _solrQueryResponse;
        this.updateRequestProcessor = _updateRequestProcessor;
    }

    @Override
    public void processAdd(AddUpdateCommand cmd) throws IOException {
        SolrInputDocument document = cmd.getSolrInputDocument();
        SolrParams params = this.solrQueryRequest.getParams();

        int clientId = params.getInt("clientId");

        document.addField("client_uid", clientId);

        super.processAdd(cmd);
    }
}

我的 HTTP 调用如下所示

curl "http://localhost:8983/solr/1-3/update?commit=true&commitWithin=10000&tr=updateXml.xsl&overwrite=true&clientId=3update.chain=mychain" -H "Content-Type: text/xml" --data-binary @myfile.xml