【问题标题】:How can I do Solr Delta Import without update whole document?如何在不更新整个文档的情况下进行 Solr Delta Import?
【发布时间】:2018-01-03 23:15:41
【问题描述】:

我想做 Solr Delta Import,但我不想更新整个文档。有没有一种方法可以指示 solr 在进行增量导入时仅更新某些字段?

【问题讨论】:

  • @MatsLindh 不,原子更新和就地更新是不同的概念。自 Solr 6.5 起,就地更新仅适用于整数字段。在幕后原子更新重新索引整个文档,所以这个答案stackoverflow.com/questions/21006045/… 是绝对错误的。
  • 是的,我知道它们是不同的概念。然而,发送的 消息 是相同的,因此,指示 DIH 生成与完整插入相比执行更新的消息的方式应该相同。发生原子更新还是就地更新取决于您在帖子中提供的参数顺序 - 但这只是配置,而不是如何使 DIH 进行实际的就地更新。关于如何使 DIH 执行此操作的链接答案在哪些方面是错误的?

标签: solr in-place


【解决方案1】:

理论

此功能称为in-place update。仅当要更新的字段满足以下条件时,才会执行就地更新:

  • 非索引 (indexed="false")
  • 非存储 (stored="false")
  • 单值(multiValued="false")
  • 数字 docValues (docValues="true") 字段

换句话说,此功能基于特殊的数据结构DocValues,因此您无法在不重新索引整个文档的情况下更新非 DocValues 字段。您可以在以下 jira 问题中阅读有关可更新 DocValue 的更多详细信息:

练习

这是一个通过 SolrJ 的示例:

HttpSolrClient client = new HttpSolrClient("http://localhost:8983/solr");
SolrInputDocument doc = new SolrInputDocument();
doc.addField("id","1");
Map<String,Object> fields = new HashMap<>();
fields.put("inc", "-1");
doc.addField("count", fields);
client.add(doc); 
client.close();

或通过 CURL:

curl http://localhost:8983/solr/library/update -d '
[
 {"id"         : "1",
  "count"     : {"inc":"-1"}
 }
]'

其中字段计数声明为:

<field name="count" type="int" indexed="false" stored="false" docValues="true"/>

请注意,如果字段配置错误,将应用“原子更新”。

“原子更新”

您可以不受"Atomic Updates" 的任何限制“更新”文档中的任何字段。原子更新实际上并不进行就地更新——它删除旧文档,然后索引一个新文档,并一次性应用更新。在后台,它要求架构中的所有字段都必须配置为已存储,并将字段复制为未存储(请记住嵌套文档),并尝试从存储的字段中重建整个文档。如果出现任何错误配置,您将丢失大部分文档,而不会发出任何通知。一般来说,原子更新有以下缺点:

  • 重新索引整个文档并将它们传递给所有分析链会消耗大量 CPU 周期
  • 通过存储原始文档数据来增加索引大小
  • 新索引段被创建,旧文档在现有段中被标记为已删除,导致段合并策略启动并使用额外的 CPU 并增加 I/O 压力
  • 最重要的是,必须在提交使更改可见后重新打开搜索。这会擦除所有累积的过滤器缓存、文档缓存和查询结果缓存
  • 索引提交,使更改可见,在将其他段添加到索引时擦除过滤器和字段缓存;
  • 在块索引结构的情况下,必须重新索引整个文档块,从而显着增加开销

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-20
    • 2011-04-21
    • 1970-01-01
    • 1970-01-01
    • 2020-10-18
    相关资源
    最近更新 更多