温馨提示:本文翻译自stackoverflow.com,查看原文请点击:indexing - Partial updates in Solr/Lucene documents
indexing lucene solr

indexing - Solr / Lucene文档中的部分更新

发布于 2020-04-18 13:16:51

最近,我们开始研究Solr部分索引更新。

用于全部和部分更新的API看起来相似。代替

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

你必须写

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

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

实际发生的情况:

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

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

我在邮件列表中发现了一些旧讨论,有人说这是预期的行为,您需要存储所有字段,依此类推。我们不想存储所有字段。“存储的”属性设计用于需要从Solr响应到调用者的情况下返回的字段。我们只需要较小的元信息作为响应,从而使存储的所有字段看起来像是一种过大的杀伤力。

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

关于此主题的讨论:

查看更多

提问者
AdamSkywalker
被浏览
48
MatsLindh 2020-02-05 17:47

您的观察是正确的-这就是行为。原因是某些因素可能取决于其他字段(copyField例如,通过指令),如何合并字段(位置增量等),这就是为什么只能对存储的字段进行部分更新的原因-文档只需加载,就可以处理该特定字段的值,然后再次为其建立索引。

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

有解决的办法,而如果你的领域填补了一系列的条件一个就地更新,可以代替执行的这就是您要的。

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

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

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

  • 是非索引(indexed =“ false”),非存储(stored =“ false”),单值(multiValued =“ false”)数字docValues(docValues =“ true”)字段;
  • 所述版本字段也是非索引,非存储单值docValues字段; 和,
  • 更新字段的复制目标(如果有)也是非索引,未存储的单值数字docValues字段。

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