我有以下形式的文件:

curl -XPOST localhost:9200/books/book/1 -d '{
    "user_id": 1,
    "pages": [ {"page_id": 1, "count": 1}, {"page_id": 2, "count": 3}]
}

现在,假设用户再次读取了页面1,所以我想增加计数。该文档应成为:
{
   "user_id": 1,
   "pages": [ {"page_id": 1, "count": 2}, {"page_id": 2, "count": 3}]
}

但是,如何使用if变量来更新列表元素呢?

Elasticsearch中的一个简单更新示例如下:
curl -XPOST localhost:9200/books/book/2 -d '{
   "user_id": 1,
   "pages": {
   "page_1": 1,
   "page_2": 2
   }
}'

curl -XPOST localhost:9200/books/book/2/_update -d '
{
    "script": "ctx._source.pages.page_1+=1"
}'

该文档现在变为:
{
  "user_id": 1,
  "pages": {
      "page_1": 1,
      "page_2": 2
}

但是,这种更简单的doc格式将page_id声明为字段,因此id本身充当了字段。同样,与该字段关联的值也没有实际定义。因此,这不是一个很好的解决方案。

无论如何,对于如何相应地更新数组有任何想法,或者对数据的结构有任何想法,将是很棒的。

注意:使用ES 1.4.4,还需要将script.disable_dynamic: false添加到elasticsearch.yml文件中。

最佳答案

假设我正确理解了您的问题,则可能会使用parent/child关系。

为了测试它,我设置了一个带有"user"父级和"page"子级的索引,如下所示:

PUT /test_index
{
   "settings": {
      "number_of_shards": 1
   },
   "mappings": {
      "user": {
         "_id": {
            "path": "user_id"
         },
         "properties": {
            "user_id": {
               "type": "integer"
            }
         }
      },
      "page": {
         "_parent": {
            "type": "user"
         },
         "_id": {
            "path": "page_id"
         },
         "properties": {
            "page_id": {
               "type": "integer"
            },
            "count": {
               "type": "integer"
            }
         }
      }
   }
}

(我在"path"中使用了"_id"参数,因为它使索引的冗余度降低了; ES文档说在ES 1.5中不推荐使用 path ,但他们没有说要用什么替换它。)

然后索引了一些文档:
POST /test_index/_bulk
{"index":{"_type":"user"}}
{"user_id":1}
{"index":{"_type":"page","_parent":1}}
{"page_id":1,"count":1}
{"index":{"_type":"page","_parent":1}}
{"page_id":2,"count":1}

现在,我可以使用scripted partial update来增加"count"page字段。由于父/子关系,我必须使用parent parameter告诉ES如何路由请求。
POST /test_index/page/2/_update?parent=1
{
   "script": "ctx._source.count+=1"
}

现在,如果我搜索该文档,我将看到它已按预期进行了更新:
POST /test_index/page/_search
{
    "query": {
        "term": {
           "page_id": {
              "value": "2"
           }
        }
    }
}
...
{
   "took": 3,
   "timed_out": false,
   "_shards": {
      "total": 1,
      "successful": 1,
      "failed": 0
   },
   "hits": {
      "total": 1,
      "max_score": 1,
      "hits": [
         {
            "_index": "test_index",
            "_type": "page",
            "_id": "2",
            "_score": 1,
            "_source": {
               "page_id": 2,
               "count": 2
            }
         }
      ]
   }
}

这里的代码都放在一个地方:

http://sense.qbox.io/gist/9c977f15b514ec251aef8e84e9510d3de43aef8a

10-07 18:58
查看更多