Solr/Lucene 文档中的部分更新

Partial updates in Solr/Lucene documents

最近我们开始探索 Solr 部分索引更新。

API 完整和部分更新看起来相似。而不是

doc.addField("location", "UK")
solrClient.add(doc)

你必须写

doc.addField("location", map("set", "Germany"))
solrClient.add(doc)

我期望发生的事情:solr 将更新字段 "location"

的倒排索引

实际发生了什么:

结果,所有未存储的字段都丢失了。

我在邮件列表中发现了一些旧的讨论,人们说这是预期的行为,您需要存储所有字段等等。我们不想存储所有字段。 "Stored" 属性 专为需要从 Solr 返回给调用者的字段而设计。我们只需要响应中的小元信息,使存储的所有字段看起来有点矫枉过正。

问题是 - 为什么 solr/lucene 执行所有这些步骤来执行部分更新?以我的理解,每个字段在其自己的文件中都有自己的倒排索引,因此应该可以独立更新字段。从实际情况来看,solr/lucene 无法更新单个字段的索引,我找不到原因。

关于这个话题的讨论:

你的观察是正确的——这就是行为。原因是有些因素可能取决于其他字段(例如,通过 copyField 指令),字段如何合并(位置增量等),这就是为什么部分更新只能使用存储字段 - 只需加载文档,操作该特定字段的值,然后再次编制索引。

这些字段没有自己的索引文件 - 它是完整索引的一组文件,索引只是附加的 - 文档不会在此索引中就地更改(因此文档只是标记为已删除,然后将新文档附加到索引)。当您在索引上 运行 optimize 时,索引将被重写,但不存在已删除的文档。

有办法解决这个问题,如果您的字段满足一组条件an in-place update can be performed instead。这可以满足您的要求。

In-place updates are very similar to atomic updates; in some sense, this is a subset of atomic updates. In regular atomic updates, the entire document is reindexed internally during the application of the update. However, in this approach, only the fields to be updated are affected and the rest of the documents are not reindexed internally. Hence, the efficiency of updating in-place is unaffected by the size of the documents that are updated (i.e., number of fields, size of fields, etc.). Apart from these internal differences, there is no functional difference between atomic updates and in-place updates.

但是,这些要求可能与您的用例不匹配 - 即它们必须是非索引的和数字的(因为它是后台中的 docValue 被替换,而不是索引中的内容 - 通常这个操作不可能 - 索引仅附加):

An atomic update operation is performed using this approach only when the fields to be updated meet these three conditions:

  • are non-indexed (indexed="false"), non-stored (stored="false"), single valued (multiValued="false") numeric docValues (docValues="true") fields;
  • the version field is also a non-indexed, non-stored single valued docValues field; and,
  • copy targets of updated fields, if any, are also non-indexed, non-stored single valued numeric docValues fields.

To use in-place updates, add a modifier to the field that needs to be updated. The content can be updated or incrementally increased.