如何在没有更新整个文档的情况下进行Solr Delta Import?

时间:2018-01-03 23:15:42

标签: solr in-place

我想做Solr Delta Import,但我不想更新整个文档。有没有办法可以指示solr在进行delta导入时只更新某个字段?

1 个答案:

答案 0 :(得分:0)

理论

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

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

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

实践

以下是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压力
  • 最重要的是,在提交更改后,必须重新打开搜索。这将擦除所有累积的过滤器缓存,文档缓存和查询结果缓存
  • 索引提交,使更改可见,擦除过滤器和字段缓存,因为其他段已添加到索引中;
  • 在块索引结构的情况下,必须重新索引文档的整个块,显着增加开销