如果文档尚不存在,是否可以使用更新API创建文档

时间:2014-07-30 10:33:29

标签: elasticsearch

我有一个非常简单的问题:

我想将多个文档更新为elasticsearch。有时文件已经存在但有时却不存在。我不想使用get请求来检查文档的存在(这会降低我的性能)。我想直接使用我的更新请求来直接索引文档,如果它还不存在的话。

我知道在更新文档时我们可以使用upsert创建一个不存在的字段,但这不是我想要的。如果文档不存在,我想索引该文档。我不知道upsert是否可以做到这一点。

你能给我一些解释吗?

提前致谢!

4 个答案:

答案 0 :(得分:44)

使用update api可以做到这一点。它确实要求您定义每个文档的id,因为更新api需要文档的id来确定它的存在。

给定使用以下文档创建的索引:

PUT /cars/car/1 
{ "color": "blue", "brand": "mercedes" }
PUT /cars/car/2
{ "color": "blue", "brand": "toyota" }

我们可以使用更新api通过以下api调用获得您想要的upsert功能。

POST /cars/car/3/_update
{
    "doc": {
        "color" : "brown",
        "brand" : "ford"
    },
    "doc_as_upsert" : true
}

此api调用会将文档添加到索引中,因为它不存在。

更改汽车颜色后第二次运行呼叫,将更新文档,而不是创建新文档。

POST /cars/car/3/_update
{
    "doc": {
        "color" : "black",
        "brand" : "ford"
    },
    "doc_as_upsert" : true
}

答案 1 :(得分:5)

当您索引文档(使用PUT调用)时,

AFAIK,现有版本将被更新版本替换。如果文档不存在,则会创建它。在ElasticSearch中无需区分INSERT和UPDATE。

更新:根据documentation,如果您使用op_type = create或索引调用的特殊_create版本,则对已存在的文档的任何调用都将失败。

来自文档的引用:

Here is an example of using the op_type parameter:

$ curl -XPUT 'http://localhost:9200/twitter/tweet/1?op_type=create' -d '{
    "user" : "kimchy",
    "post_date" : "2009-11-15T14:12:12",
    "message" : "trying out Elasticsearch"
}'
Another option to specify create is to use the following uri:

$ curl -XPUT 'http://localhost:9200/twitter/tweet/1/_create' -d '{
    "user" : "kimchy",
    "post_date" : "2009-11-15T14:12:12",
    "message" : "trying out Elasticsearch"
}'

答案 2 :(得分:1)

批量API使用

function onOpen(e) {
    SpreadsheetApp.getUi().createAddonMenu()
      .addItem('Start syncing', 'start')
      .addItem('Stop syncing', 'removeAllTriggers')
      .addToUi();
}

答案 3 :(得分:0)

elasticsearch-model v0.1.4开始,不支持upsert。我能够通过创建custom callback来解决这个问题。

after_commit on: :update do
    begin
        __elasticsearch__.update_document
    rescue Elasticsearch::Transport::Transport::Errors::NotFound
        __elasticsearch__.index_document
    end
end