我有三种类型的文件:请求,工作和驱动程序。请求和工作之间存在父/子关系,工作和驱动程序之间存在父/子关系。这个查询:
`GET batch-val-weekly-2015-02-v1/driver/_search
{
"query": {
"match_all": {}
},
"fields": ["_parent"]
}`
返回文档列表。父字段存在于每个字段中,并提供相应作业文档的ID。但是这个查询:
'GET batch-val-weekly-2015-02-v1/job/_search
{
"query": {
"has_child": {
"type": "driver",
"query": {
"match_all": {}
}
}
}
}'
不返回任何命中。我也没有从has_parent查询中获取任何命中。
编辑:Elasticsearch deeper level Parent-child relationship (grandchild)回答了这个问题。请参阅下面的解释。
答案 0 :(得分:0)
当我取出"driver"
类型的属性"driver"
时,它似乎工作正常。如果这是一个错误,那么删除它似乎解决了这个问题。更具体地说,首先我创建索引(注意"driver"
定义与上面发布的内容的区别):
DELETE /test_index
PUT /test_index
{
"mappings": {
"request": {
"_all": {
"enabled": false
},
"_timestamp": {
"enabled": true
}
},
"job": {
"_all": {
"enabled": false
},
"_timestamp": {
"enabled": true
},
"_parent": {
"type": "request"
}
},
"driver": {
"_all": {
"enabled": false
},
"_parent": {
"type": "job"
},
"properties": {
"rules": {
"type": "nested"
}
}
}
}
}
添加三个相互关联的文档:
PUT /test_index/_bulk
{"index": {"_index": "test_index", "_type": "request", "_id": 1}}
{}
{"index": {"_index": "test_index", "_type": "job", "_id": 1, "_parent":1}}
{}
{"index": {"_index": "test_index", "_type": "driver", "_id": 1, "_parent":1}}
{}
第一个查询有效:
POST /test_index/driver/_search
{
"query": {
"match_all": {}
},
"fields": [
"_parent"
]
}
...
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "test_index",
"_type": "driver",
"_id": "1",
"_score": 1,
"fields": {
"_parent": "1"
}
}
]
}
}
第二个查询有效:
POST /test_index/job/_search
{
"query": {
"has_child": {
"type": "driver",
"query": {
"match_all": {}
}
}
}
}
...
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "test_index",
"_type": "job",
"_id": "1",
"_score": 1,
"_source": {}
}
]
}
}
以下是我使用的代码:
http://sense.qbox.io/gist/602af489fbfb6595c65cd27cff7a1926642ea205
答案 1 :(得分:0)
事实证明,has_parent和has_child查询有两代以上的问题。那是因为这些查询依赖于父和子在同一个分片上。默认情况下,使用其ID将文档路由到分片(有关此here的更多信息)。建立父子关系时,子文档将根据其父 ID进行路由,以确保它们最终位于同一个分片上。
因此,如果您有三代人 - 父母,子女,孙子女 - 那么孩子们就会使用父母的身份证进行路由,而孙子女则使用孩子的身份证进行路由。但孩子们没有使用他们自己的身份证路由,他们使用父母的身份证路由;所以孙子们最终没有找到正确的分片,并且has_parent / has_child查询找不到它们。
解决这个问题的方法是根据父母的ID路由孙子孙女。这是可配置的,请参阅Elasticsearch路由文档here。您还可以通过Java API设置自定义路由。这就是我所做的,它解决了这个问题。
查看此stackoverflow答案以获取更多信息:Elasticsearch deeper level Parent-child relationship (grandchild)