簡體   English   中英

使用現有的“ id”字段索引Elasticsearch文檔

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM