我正在尝试使用多个值查询嵌套属性。
这是一个更清晰的例子。
使用嵌套字段创建索引
curl -X DELETE "http://localhost:9200/testing_nested_query/"
curl -X POST "http://localhost:9200/testing_nested_query/" -d '{
"mappings": {
"class": {
properties: {
title: {"type": "string"},
"students": {
"type": "nested",
"properties": {
"name": {"type": "string"}
}
}
}
}
}
}'
添加一些值
curl -XPUT 'http://localhost:9200/testing_nested_query/class/1' -d '{
"title": "class1",
"students": [{"name": "john"},{"name": "jack"},{"name": "jim"}]
}'
curl -XPUT 'http://localhost:9200/testing_nested_query/class/2' -d '{
"title": "class2",
"students": [{"name": "john"},{"name": "chris"},{"name": "alex"}]
}'
查询john所在的所有类(按预期命中2次)
curl -XGET 'http://localhost:9200/testing_nested_query/class/_search' -d '{
"query": {
"nested": {
"path":"students",
"query": {
"bool": {
"must": [
{"match": {"students.name": "john"}}
]
}
}
}
}
}'
查询john和jack参加的课程(0结果而不是1)
curl -XGET 'http://localhost:9200/testing_nested_query/class/_search' -d '{
"query": {
"nested": {
"path":"students",
"query": {
"bool": {
"must": [
{"match": {"students.name": "john"}},
{"match": {"students.name": "jack"}}
]
}
}
}
}
}'
我尝试过使用匹配和过滤器,但我永远无法让查询返回预期值。
答案 0 :(得分:22)
只需要稍微改变一下:
{
"query": {
"bool": {
"must": [
{
"nested": {
"path":"students",
"query": {
"bool": {
"must": [
{"match": {"name": "john"}}
]
}
}
}
},
{
"nested": {
"path":"students",
"query": {
"bool": {
"must": [
{"match": {"name": "jack"}}
]
}
}
}
}
]
}
}
}
<强>为什么吗
基本上,在嵌套查询中,查询和过滤器在一个嵌套文档上集体执行 - 在您的情况下是一个名称。因此,您的查询会获取每个嵌套文档,并尝试同时查找name
等于john
和jack
的每个文档 - 这是不可能的。
我的查询尝试查找索引文档,其中一个嵌套文档的name
等于john
,另一个嵌套文档的name
等于jack
。所以基本上一个嵌套查询尝试完全匹配一个嵌套文档。
要证明我的建议,试试这个:
使用与您相同的映射创建相同的索引
**然后索引以下文件**
curl -XPUT 'http://localhost:9200/testing_nested_query/class/1' -d '{
"title": "class1",
"students": [{"name": "john", "age": 4},{"name": "jack", "age": 1},{"name": "jim", "age": 9}]
}'
curl -XPUT 'http://localhost:9200/testing_nested_query/class/2' -d '{
"title": "class1",
"students": [{"name": "john", "age": 5},{"name": "jack", "age": 4},{"name": "jim", "age": 9}]
}'
现在执行以下查询:
{
"query": {
"nested": {
"path":"students",
"query": {
"bool": {
"must": [
{"match": {"name": "john"}},
{"match": {"age": 4}}
]
}
}
}
}
}
根据您的期望,这应该匹配2个文件,但它实际上只匹配一个。因为只有一个嵌套文档,name
等于john
而age
等于4
。
希望有所帮助。
答案 1 :(得分:2)
你也可以采取以下方式。你不需要在嵌套块中再次重复bool,因为在该块中只有一个匹配,你可以在没有bool的情况下进行术语匹配
{
"query": {
"bool": {
"must": [{
"nested": {
"path": "students",
"query": {
{
"term": {
"name": "john"
}
}
}
}
}, {
"nested": {
"path": "students",
"query": {
{
"term": {
"name": "jack"
}
}
}
}
}]
}
}
}