Solr/Lucene 文档中的部分更新

Ada*_*ker 5 lucene indexing solr

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

完整更新和部分更新的 API 看起来很相似。代替

doc.addField("location", "UK")
solrClient.add(doc)
Run Code Online (Sandbox Code Playgroud)

你必须写

doc.addField("location", map("set", "Germany"))
solrClient.add(doc)
Run Code Online (Sandbox Code Playgroud)

我期望发生什么:solr 将更新字段“location”的倒排索引

实际发生的情况:

  • solr 加载文档的存储字段
  • 应用给定的文档更新
  • 通过id删除文档
  • 将文档写入索引

结果,所有非存储字段都会丢失。

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

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

关于该主题的讨论:

Mat*_*ndh 5

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

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

有一种方法可以解决这个问题,如果您的字段满足一组条件则可以执行就地更新。这就是你所要求的。

就地更新与原子更新非常相似;从某种意义上说,这是原子更新的子集。在常规原子更新中,整个文档在应用更新期间会在内部重新索引。然而,在这种方法中,只有要更新的字段受到影响,其余文档不会在内部重新索引。因此,就地更新的效率不受更新文档的大小(即字段数量、字段大小等)的影响。除了这些内部差异之外,原子更新和就地更新之间没有功能差异。

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

仅当要更新的字段满足以下三个条件时,才使用此方法执行原子更新操作:

  • 是非索引 (indexed="false")、非存储 (stored="false")、单值 (multiValued="false") 数字 docValues (docValues="true") 字段;
  • version字段也是一个非索引、非存储的单值 docValues 字段;和,
  • 更新字段的复制目标(如果有)也是非索引、非存储的单值数字 docValues 字段。

要使用就地更新,请向需要更新的字段添加修饰符。内容可以更新或增量增加。