我有以下形式的文件:
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