Rest 使用现有“索引”索引Elasticsearch文档;id";领域
我有一些文档要索引到Elasticsearch中,其中包含一个唯一的“id”字段。 我从REST api端点Rest 使用现有“索引”索引Elasticsearch文档;id";领域,rest,
elasticsearch,indexing,cron,logstash,Rest,
elasticsearch,Indexing,Cron,Logstash,我有一些文档要索引到Elasticsearch中,其中包含一个唯一的“id”字段。 我从REST api端点获取一组文档(例如:http://some.url/api/products)没有特定顺序,如果Elasticsearch中已存在具有_id的文档,则应更新并重新编制文档索引 如果Elasticsearch中不存在具有_id的文档,我想创建一个新文档,然后更新一个文档(如果它与Elasticsearch中的现有文档匹配) 这可以通过以下方式实现: PUT products/product/
获取一组文档(例如:http://some.url/api/products)
没有特定顺序,如果Elasticsearch中已存在具有_id的文档,则应更新并重新编制文档索引
如果Elasticsearch中不存在具有_id的文档,我想创建一个新文档,然后更新一个文档(如果它与Elasticsearch中的现有文档匹配)
这可以通过以下方式实现:
PUT products/product/un1qu3-1d-b718-105973677e95
{
“id”:“un1qu3-1d-b718-105973677e95”,
“状态”:“打包”
}
基本思想是使用提供的“id”字段创建或更新文档。从文档字段提取_id似乎已被弃用()。但是,使用kibana开发工具、postman或cURL请求,可以非常轻松地手动完成带有“id”字段的文档的索引/重新索引。
我希望以编程方式实现通过此api端点接收的文档的(重新)索引
是否可以通过logstash或简单的cronjob实现这一点?Elasticsearch是否为此提供了任何功能?或者我需要编写一些自定义后端来实现这一点
我想到的是:
1) 使用我的文档的“id”字段将文档索引到Elasticsearch中,或
2) 查找Elasticsearch查询,该查询首先搜索具有特定“id”字段的文档,然后更新文档
我无法找到任何一种方法的解决方案,也不知道一个好的方法会是什么样子
有谁能为我指出如何实现这一目标的正确方向、提出更好的方法或提供解决方案
非常感谢任何帮助
更新
我在公认答案的帮助下解决了这个问题。我使用了Logstash,Http_轮询器输入插件,本文: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”管道
它是这样工作的!
非常感谢 彼得
如果我理解正确,您希望将您的文档吸收到弹性搜索中,并在将来对这些文档进行一些更新
如果是这样的话,
-使用文档主键作为弹性文档的id。
-您可以使用更新的值接收整个文档,elastic将用新文档替换以前的文档。给定的主键是相同的。具有相同id的旧文档将被删除
我们对搜索数据使用这种方法。您可以使用摄取管道从正文中提取id,而
\u 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"
}
您可以使用脚本向上插入(更新或插入)文档
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”的文档
如果它能够找到任何文档,那么它将把state更新为“packated”,否则将创建一个具有字段“id”和“state”的新文档(您可以插入任意多的字段) 我的设置的问题是,当我从api端点接收文档时,我不知道文档的“Id”字段。所以我不能预先说明。这是一个第三方api端点,我对它没有任何影响。到目前为止,我还没有听说过Elasticsearchs\u ingest和pipeline。非常感谢,我一定会试一试的。目前,一定的开销还可以。我不完全理解的是
在客户端指定id是什么意思。作为补充说明,我对获取文档的第三方api端点没有任何影响,因此我事先不知道“id”字段@alr@Peter计划您的文档的唯一标识是什么?如何知道是否要更新elasticsearch中的现有文档?如果知道唯一标识符,则可以将其用作文档的id。
PUT /products/product/un1qu3-1d-b718-105973677e95/_update
{
"script": {
"inline": "ctx._source.state = \"packaged\"",
"lang": "painless"
},
"upsert": {
"id": "un1qu3-1d-b718-105973677e95",
"state": "packaged"
}
}