Solr原子更新删除以前的更新

时间:2017-02-01 16:31:25

标签: solr lucene solrj

我正在运行Solr 5.3.1并且我想更新我的Solr索引,例如"将字段x设置为' foo'字段y就像' * bar'"。但Solr似乎不具备通过查询进行更新的能力。所以我使用SolrJ来实现这一目的。

逻辑是向Solr发出查询以获取我想要更新的结果,然后使用Atomic Update(请参阅http://yonik.com/solr/atomic-updates/)更新单个文档。

我的代码看起来像

public void updateDocsByQuery(String queryStr, String fieldName, String fieldValue) 
        throws Exception {

    SolrDocumentList docList = fetchDocsByQuery(queryStr, "id" , 5000);

    if (!docList.isEmpty()) {
        Collection<SolrInputDocument> docs = new ArrayList<>();

        for (int i=0; i<docList.size(); i++) {
            SolrDocument doc = docList.get(i);
            String id = (String) doc.getFieldValue("id");

            SolrInputDocument inputDoc = new SolrInputDocument();
            inputDoc.addField("id", id);
            Map<String, Object> fieldMod = new HashMap<>(1);
            fieldMod.put("set", fieldValue);
            inputDoc.addField(fieldName, fieldMod);

            docs.add(inputDoc);

        }                       

        client.add(docs);
        client.commit();
    }               
}

我使用Atomic Update获得了非常奇怪的行为。只有docList中的最后一个文档获得带有值的更新,其余文档将被删除。如果我使用不同的查询再次运行此代码,则上次运行中更新的文档也将被删除,同样,只有列表中的最后一个文档会更新。

有没有人理解这种奇怪的行为?

我的架构是

  <schema name="MySchema" version="1.5">
<fields>
    <field name="_version_" type="long" indexed="true" stored="true"/>
    <field name="id" type="string" indexed="true" stored="true"  required="true" multiValued="false" />  

    <field name="title" type="text_en" indexed="true" stored="true" multiValued="false" termVectors="true" termPositions="true" termOffsets="true"   />
    <field name="subject" type="text_en" indexed="true" stored="true"/>
    <field name="author" type="text_en" indexed="true" stored="true"/>
    <field name="keywords" type="text_en" indexed="true" stored="true"/>
    <field name="category" type="text_en" indexed="true" stored="true"/>
    <field name="suggested_links" type="string" indexed="true" stored="true" />
    <field name="resourcename" type="string" indexed="true" stored="true" docValues="true" />
    <field name="resource_names" type="string" indexed="true" stored="true" multiValued="true" docValues="true" />
    <field name="content_type" type="string" indexed="true" stored="true"  docValues="true"/>
    <field name="last_modified" type="date" indexed="true" stored="true"/>
    <field name="source_group" type="string" indexed="true" stored="true" />

    <!-- Main body of document -->
    <field name="content" type="text_en" indexed="true" stored="true" termVectors="true" termPositions="true" termOffsets="true"   />

    <!-- catchall field, containing all other searchable text fields (implemented via copyField further on in this schema  -->
    <field name="text" type="text_en" indexed="true" stored="false" multiValued="true"  />

<!-- holds Solr dedupe hash code -->
<field name="dedupeSignatureField" type="string" indexed="true" stored="true" multiValued="false" /> 

 <!-- copy fields to search by default in our catch-all field, 'text' -->

 <copyField source="title" dest="text"/> 
 <copyField source="subject" dest="text"/>
     <copyField source="author" dest="text"/> 
     <copyField source="keywords" dest="text"/> 
     <copyField source="content" dest="text"/> 

</fields>

<uniqueKey>id</uniqueKey>

<types>

    <fieldType name="string" class="solr.StrField" sortMissingLast="true" />
    <fieldType name="date" class="solr.TrieDateField" precisionStep="0" positionIncrementGap="0"/>
    <fieldType name="long" class="solr.TrieLongField" precisionStep="0" positionIncrementGap="0"/>
    <fieldType name="text_en" class="solr.TextField" positionIncrementGap="100">
        <analyzer type="index">
            <tokenizer class="solr.StandardTokenizerFactory"/>
            <filter class="solr.StopFilterFactory"
                ignoreCase="true"
                words="lang/stopwords_en.txt"
                />
            <filter class="solr.LowerCaseFilterFactory"/>
            <filter class="solr.EnglishPossessiveFilterFactory"/>
            <filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
            <filter class="solr.PorterStemFilterFactory"/>
          </analyzer>
          <analyzer type="query">
            <tokenizer class="solr.StandardTokenizerFactory"/>
            <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
            <filter class="solr.StopFilterFactory"
                ignoreCase="true"
                words="lang/stopwords_en.txt"
                />
            <filter class="solr.LowerCaseFilterFactory"/>
            <filter class="solr.EnglishPossessiveFilterFactory"/>
            <filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
            <filter class="solr.PorterStemFilterFactory"/>
        </analyzer>
     </fieldType> 
</types>

    在这里输入代码

1 个答案:

答案 0 :(得分:0)

在Solr 5.4.0上工作时我也遇到了这个问题。只有docList中的最后一个文档用于更新值,其余文档被删除。

我的解决方案,在您的代码中替换:

Microsoft Visual Studio Offline

inputDoc.addField("id", id);

保持其余代码不变。