索引Elasticsearch文档,包含现有的" id"领域

时间:2017-07-10 17:44:57

标签: rest elasticsearch indexing cron logstash

我有一些文档,我想用Elasticsearch索引到现有的唯一" id"领域。 我从REST api端点( 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)。但是使用" id"对文档进行索引/重新索引。使用kibana dev工具,邮递员或cURL请求,可以非常轻松地手动完成字段。 我希望通过此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}}"
        }
      }
    ]
  }
}

这样就行了! 非常感谢!

3 个答案:

答案 0 :(得分:1)

彼得,

如果我理解正确,您希望将文档摄取为弹性搜索,并且将来会对这些文档进行一些更新吗?

如果是这样的话, - 使用您的文档主键作为弹性文档的ID。 - 您可以使用更新的值来摄取整个文档,弹性将使用新文档替换以前的文档。鉴于主键是相同的。具有相同ID的旧文档将被删除。

我们将此方法用于搜索数据。

答案 1 :(得分:0)

您可以使用摄取管道从正文中提取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"
}

答案 2 :(得分:0)

您可以使用脚本来UPSERT(更新或插入)您的文档

// sortedParentList = List(Children(Atticus,9.48D), Children(Halls,9379.40D), Children(Aurilius,1100.75D))

以上查询使用_id =“un1qu3-1d-b718-105973677e95”查找文档 如果它能够找到任何文档,那么它将更新状态为“打包”,否则创建一个带有字段“id”和“state”的新文档(您可以根据需要插入任意数量的字段)。