多值字段中值的Solr顺序

时间:2014-11-27 17:31:19

标签: solr

从动态字段中存储了多个值的字段,此数据在输入xml文件中以正确的顺序排列,但是当我们进行搜索时,数据的顺序完全不同。有没有办法控制这个订单?

让我来描述一下这个过程 1-输入文件附带动态字段,其格式为*_foo 2- solr将添加此动态字段中的值,并将值复制到allFoos 3-我们搜索多值字段,并分析其内容。

我们发现allFoos中存储的值会丢失输入文件给出的顺序。

这个虚拟数据提供了一个关于我们如何处理字段和副本的示例。 然后更改的字段和值的名称进行测试,但预计resut将是相同的。

模式

<dynamicField name="`*_foo`" type="string" indexed="false" stored="true"/>
<field name="`allFoos`" type="string" indexed="true" stored="true" required="false" multiValued="true"/>
<copyField source="`*_foo`" dest="`allFoos`"/>

输入文件

<add>
    <doc>
        <field name="field_1_foo" update="set">1</field>
        <field name="field_2_foo" update="set">2</field>
        <field name="field_3_foo" update="set">3</field>
        <field name="field_4_foo" update="set">4</field>
        <field name="field_5_foo" update="set">5</field>
        <field name="field_6_foo" update="set">6</field>
        <field name="field_7_foo" update="set">7</field>
        <field name="field_8_foo" update="set">8</field>
        <field name="field_9_foo" update="set">9</field>
        <field name="field_10_foo" update="set">10</field>
        <field name="field_11_foo" update="set">11</field>
        <field name="field_12_foo" update="set">12</field>
        <field name="field_13_foo" update="set">13</field>
        <field name="field_14_foo" update="set">17</field>
        <field name="field_15_foo" update="set">15</field>
        <field name="field_16_foo" update="set">16</field>
        <field name="field_17_foo" update="set">17</field>
        <field name="field_18_foo" update="set">18</field>
        <field name="field_19_foo" update="set">19</field>
        <field name="field_20_foo" update="set">20</field>
        <field name="field_21_foo" update="set">21</field>
        <field name="field_22_foo" update="set">21</field>
        <field name="field_23_foo" update="set">21</field>
        <field name="field_24_foo" update="set">21</field>
        <field name="field_25_foo" update="set">21</field>
    </doc>
</add>

结果

"allFoos": [ "3", "16", "25", "20", "19", "7", "21", "6", "13", "8", "5", "18", "24", "17", "23", "15", "4", "10", "12", "11", "2", "14", "22", "9", "1"]

每次搜索结果都是一样的,我已经多次删除并重新插入相同的数据,并且它总是按照相同的顺序。

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

Yonik Seely在this thread结束时很好地总结了它:

  

保证维持订单   多值字段中的值。不同领域的顺序不是   保持。

因此,由于您要将25个不同的字段复制到allFoos,因此无法保证。默认情况下,SolrInputDocumentLinkedHashMap支持,但也有一个接受任意Map<String,SolrInputField>的构造函数,这意味着不应依赖文档中字段的排序。

  public SolrInputDocument() {
    _fields = new LinkedHashMap<>();
  }

  public SolrInputDocument(Map<String,SolrInputField> fields) {
    _fields = fields;
  }

作为文档提取过程的一部分,您可以预处理数据以生成单个字段,并以正确的顺序将值添加到该字段。应保持单个字段中的订单。这最好在外部管道中完成,您可以在其中查看源文档中的原始顺序。也许如果某些排序或其他逻辑可以从字段名称重建正确的顺序,您可以通过安装自定义UpdateRequestProcessorFactory实现在Solr中完成。

答案 1 :(得分:1)

使用StatelessScriptUpdateProcessorFactory处理器有一个稳定的推荐选项。我们将使用Javascript按照我们需要的顺序获取所有字段和值。我将用一些步骤来写这个:

您的 schema.xml 将是相同的,除了架构不得有第三行(关于复制字段:* ... copyField源 _foo字段到allFoos字段.. 的)。这部分将委托给Javascript代码。它仍然是这样的:

<dynamicField name="`*_foo`" type="string" indexed="false" stored="true"/>
<field name="`allFoos`" type="string" indexed="true" stored="true" required="false" multiValued="true"/>

在核心的 solrconfig.xml 中,写下:

<!-- ... part of your solrconfig.xml ... -->

<requestHandler name="/update" class="solr.UpdateRequestHandler"> 
    <lst name="defaults"> 
        <str name="update.chain">custom</str>
    </lst> 
</requestHandler>

<!-- ... part of your solrconfig.xml ... -->

<updateRequestProcessorChain name="custom">

    <processor class="solr.StatelessScriptUpdateProcessorFactory">
        <str name="script">update-script.js</str>
        <lst name="params">
            <str name="config_param">example config parameter</str>
        </lst>
    </processor>

    <processor class="solr.LogUpdateProcessorFactory" />
    <processor class="solr.RunUpdateProcessorFactory" />

</updateRequestProcessorChain>

<!-- ... part of your solrconfig.xml ... -->

有了这个,我们告诉Solr使用链接插件'custom',一个自定义的URP(Update Request Processor),当你使用'update'时,它会使用 StatelessScriptUpdateProcessorFactory 处理器请求处理程序如果您正在使用其他请求处理程序,请在所需的请求处理程序中设置它。

您必须在'conf'核心目录的同一级文件夹中有一个' update-script.js '文件,其中包含您需要的所有功能以及一些示例。

在此 update-script.js 文件的函数processAdd(cmd)中,写下:

doc = cmd.solrDoc;  // org.apache.solr.common.SolrInputDocument
id = doc.getFieldValue("id");
logger.info("update-script#processAdd: id = " + id);

fieldNames = doc.getFieldNames().toArray();

for (var i = 0; i < fieldNames.length; i++) {

    fieldValue = doc.getFieldValue(fieldName[i]);
    doc.addField("allFoos", String(fieldValue.toString()));
}

这在Solr中的任何摄取/更新的字段数据之前处理(这部分执行委托在RunUpdateProcessorFactory上)。

全部完成。