【问题标题】:Can I create a document with the update API if the document doesn't exist yet如果文档尚不存在,我可以使用更新 API 创建文档吗
【发布时间】:2014-09-21 23:08:13
【问题描述】:

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

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

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

你能给我解释一下吗?

提前致谢!

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    用于批量 API

    bulks.push({
           update: {
                   _index: 'index',
                   _type: 'type',
                  _id: id
                   }
    });
    bulks.push({"doc_as_upsert":true, "doc": your_doc});
    

    【讨论】:

      【解决方案2】:

      这可以使用更新 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
      }
      

      【讨论】:

      • "doc_as_upsert" 救了我的命。非常感谢。
      • 我想根据 name 字段而不是 id 更新记录。那么可以通过 upsert 实现吗?
      • 如何根据条件进行更新插入,例如当颜色不是黑色时进行更新插入?
      【解决方案3】:

      从 elasticsearch-model v0.1.4 开始,不支持 upserts。我可以通过创建custom callback 来解决这个问题。

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

      【讨论】:

        【解决方案4】:

        当您索引文档时(使用 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"
        }'
        

        【讨论】:

        • 我错过了 _create URL 调用。它不像我想的那样需要创建。
        猜你喜欢
        • 2019-08-04
        • 1970-01-01
        • 2021-09-12
        • 2020-05-11
        • 1970-01-01
        • 2017-03-13
        • 2019-06-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多