Solr Composite Уникальный ключ из существующих полей в схеме

У меня есть индекс с именем LocationIndex в solr с полями следующим образом:

<fields>
    <field name="solr_id" type="string" stored="true" required="true" indexed="true"/>
    <field name="solr_ver" type="string" stored="true" required="true" indexed="true" default="0000"/>
    // and some more fields
</fields>
<uniqueKey>solr_id</uniqueKey>

Но теперь я хочу изменить схему так, чтобы уникальный ключ был составным из двух уже существующих полей solr_id и solr_ver... что-то следующим образом:

<fields>
    <field name="solr_id" type="string" stored="true" required="true" indexed="true"/>
    <field name="solr_ver" type="string" stored="true" required="true" indexed="true" default="0000"/>
    <field name="composite-id" type="string" stored="true" required="true" indexed="true"/>
    // and some more fields
</fields>
<uniqueKey>solr_ver-solr_id</uniqueKey>

После поиска я обнаружил, что это возможно, добавив следующее в схему: (ref: Solr Composite Уникальный ключ из существующих полей в схеме)

<updateRequestProcessorChain name="composite-id">
  <processor class="solr.CloneFieldUpdateProcessorFactory">
    <str name="source">docid_s</str>
    <str name="source">userid_s</str>
    <str name="dest">id</str>
  </processor>
  <processor class="solr.ConcatFieldUpdateProcessorFactory">
    <str name="fieldName">id</str>
    <str name="delimiter">--</str>
  </processor>
  <processor class="solr.LogUpdateProcessorFactory" />
  <processor class="solr.RunUpdateProcessorFactory" />
</updateRequestProcessorChain>

Итак, я изменил схему и, наконец, выглядит так:

<updateRequestProcessorChain name="composite-id">
  <processor class="solr.CloneFieldUpdateProcessorFactory">
    <str name="source">solr_ver</str>
    <str name="source">solr_id</str>
    <str name="dest">id</str>
  </processor>
  <processor class="solr.ConcatFieldUpdateProcessorFactory">
    <str name="fieldName">id</str>
    <str name="delimiter">-</str>
  </processor>
  <processor class="solr.LogUpdateProcessorFactory" />
  <processor class="solr.RunUpdateProcessorFactory" />
</updateRequestProcessorChain>

<fields>
    <field name="solr_id" type="string" stored="true" required="true" indexed="true"/>
    <field name="solr_ver" type="string" stored="true" required="true" indexed="true" default="0000"/>
    <field name="id" type="string" stored="true" required="true" indexed="true"/>
    // and some more fields
</fields>
<uniqueKey>id</uniqueKey>

Но при добавлении документа это дает мне ошибку:

org.apache.solr.client.solrj.SolrServerException: Server at http://localhost:8983/solr/LocationIndex returned non ok status:400, message:Document [null] missing required field: id

Я не понимаю, какие изменения в схеме необходимы для работы по желанию?

В документе, который я добавляю, он содержит поля solr_ver и solr_id. Как и где он (solr) создаст поле id, объединив оба эти поля, что-то вроде solr_ver-solr_id?

EDIT:

В этой ссылке Это дано как ссылка на эту цепочку. Bu Я не могу понять, как он будет использоваться в схеме? И где я должен вносить изменения?

Ответ 1

Итак, похоже, что вы правильно определили свой updateRequestProcessorChain, и он должен работать. Однако вам нужно добавить это в файл solrconfig.xml, а не в schema.xml. Дополнительная ссылка, которую вы указали, показывает вам, как изменить файл solrconfig.xml и добавить свой определенный updateRequestProcessorChain к текущему обработчику запросов /update для вашего экземпляра solr.

Итак, найдите следующее:

  • Переместите <updateRequestProcessorChain> в файл solrconfig.xml.
  • Обновите запись <requestHandler name="/update" class="solr.UpdateRequestHandler"> в файле solrconfig.xml и измените ее так, чтобы она выглядела следующим образом:

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

Затем вы должны выполнить определенную цепочку обновлений и заполнить поле id, когда новые документы будут добавлены в индекс.

Ответ 2

Описанное выше решение может иметь некоторые ограничения, что, если "dest" превышает максимальную длину, потому что конкатенированные поля слишком велики. Существует также еще одно решение с MD5Signature (класс A, способный генерировать сигнатурный String из конкатенации группы заданных полей документа, 128-битный хеш используется для точного обнаружения дубликатов)

<!-- An example dedup update processor that creates the "id" field on the fly 
     based on the hash code of some other fields.  This example has 
     overwriteDupes set to false since we are using the id field as the 
     signatureField and Solr will maintain uniqueness based on that anyway. --> 
<updateRequestProcessorChain name="dedupe"> 
  <processor class="org.apache.solr.update.processor.SignatureUpdateProcessorFactory"> 
    <bool name="enabled">true</bool> 
    <bool name="overwriteDupes">false</bool> 
    <str name="signatureField">id</str> 
    <str name="fields">name,features,cat</str> 
    <str name="signatureClass">org.apache.solr.update.processor.Lookup3Signature</str> 
  </processor> 
  <processor class="solr.LogUpdateProcessorFactory" /> 
  <processor class="solr.RunUpdateProcessorFactory" /> 
</updateRequestProcessorChain> 

Отсюда: http://lucene.472066.n3.nabble.com/Solr-duplicates-detection-td506230.html

Ответ 3

Я хотел бы добавить это как комментарий, но в наши дни невозможно получить кредиты. В любом случае, вот лучшая ссылка: https://wiki.apache.org/solr/Deduplication