[英]index Elasticsearch document with existing “id” field
我有一些要使用现有的唯一“ id”字段索引到Elasticsearch中的文档。 我从REST api端点( eg.: http://some.url/api/products)
获取的文档( eg.: http://some.url/api/products)
没有特定顺序,并且如果Elasticsearch中已经存在带有_id的文档,则应该更新该文档并为其重新编制索引。
如果在Elasticsearch中不存在带有_id的文档,我想创建一个新文档,然后如果与Elasticsearch中的现有文档匹配,则更新一个文档。
这可以通过以下方式完成:
PUT products/product/un1qu3-1d-b718-105973677e95 { "id": "un1qu3-1d-b718-105973677e95", "state": "packaged" }
基本思想是使用提供的“ id”字段来创建或更新文档。 从文档字段中提取_id似乎已弃用( link )。 但是,使用kibana dev工具,邮递员或cURL请求,可以非常轻松地手动完成带有“ id”字段的文档的索引/重新索引。 我想以编程方式实现通过此api端点收到的文档的(重新)索引。
是否有可能通过logstash或简单的cronjob来实现? Elasticsearch是否为此提供任何功能? 还是我需要编写一些自定义后端来实现这一目标?
我想到了:
1)使用文档的“ id”字段将文档编入Elasticsearch或
2)找到一个Elasticsearch查询,该查询首先使用特定的“ id”字段搜索文档,然后更新文档。
我无法找到这两种方法的解决方案,也不知道好的方法会是什么样子。
谁能为我指出实现此目标的正确方向,提出更好的方法或提供解决方案?
任何帮助,不胜感激!
更新
我借助公认的答案解决了这个问题。 我用Logstash的Http_poller输入插件,这篇文章: https://www.elastic.co/blog/new-way-to-ingest-part-1
这elastic.co问题: https://discuss.elastic.co/t/upsert-with-logstash/59116
目前,我的logstash输出如下所示:
output {
elasticsearch {
index => "products"
document_type => "product"
pipeline => "rename_id"
document_id => "%{id}"
doc_as_upsert => true
action => "update"
}
更新2
为了完整起见,我添加了“ rename_id”管道
{
"rename_id": {
"description": "_description",
"processors": [
{
"set": {
"field": "_id",
"value": "{{id}}"
}
}
]
}
}
它是这样工作的! 非常感谢!
彼得,
如果我理解正确,您想将文档提取到弹性搜索中,将来这些文档会进行一些更新吗?
如果是这样,-将您的文档主键用作弹性文档的ID。 -您可以使用更新后的值提取整个文档,elastic将用新文档替换以前的文档。 给定的主键是相同的。 具有相同ID的旧文档将被删除。
我们将这种方法用于搜索数据。
您可以使用摄取管道从正文中提取ID,并使用_create
端点仅在不存在文档的情况下创建文档。 小注释:如果可以在客户端上指定id,则索引会更快,因为添加管道会增加一定的开销。
PUT _ingest/pipeline/my_pipeline
{
"description": "_description",
"processors": [
{
"set": {
"field": "_id",
"value": "{{id}}"
}
}
]
}
PUT twitter/tweet/1?op_type=create&pipeline=my_pipeline
{
"foo" : "bar",
"id" : "123"
}
GET twitter/tweet/123
# this call will fail
PUT twitter/tweet/1?op_type=create&pipeline=my_pipeline
{
"foo" : "bar",
"id" : "123"
}
您可以使用脚本来UPSERT(更新或插入)您的文档
PUT /products/product/un1qu3-1d-b718-105973677e95/_update
{
"script": {
"inline": "ctx._source.state = \"packaged\"",
"lang": "painless"
},
"upsert": {
"id": "un1qu3-1d-b718-105973677e95",
"state": "packaged"
}
}
在上面的查询中,找到_id =“ un1qu3-1d-b718-105973677e95”的文档(如果能够找到任何文档,则它将状态更新为“已打包”),否则创建带有“ id”和“ state”字段的新文档可以插入任意多个字段)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.