ES宽表查询常见问题,本帖指的是想关联的子文档集合,以属性的形式嵌套在我们的父文档中:
直接创建索引
PUT my-index-000001
插入文档
PUT my-index-000001/_doc/1
{
"group" : "fans",
"user" : [
{
"first" : "John",
"last" : "Smith"
},
{
"first" : "Alice",
"last" : "White"
}
]
}
执行布尔查询:
GET my-index-000001/_search
{
"query": {
"bool": {
"must": [
{ "match": { "user.first": "Alice" }},
{ "match": { "user.last": "Smith" }}
]
}
}
}
很明显不应该命中,然而
出现这种原因是因为user默认是普通对象,在没有声明的情况下,会变成平铺式,所以就绕过了这个查询的联合match
怎么避免呢,可以使用es的特性指定对象是nested。
# 测试多表
DELETE my-index-000001
# 重建索引
PUT my-index-000001
{
"mappings": {
"properties": {
"user": {
"type": "nested"
}
}
}
}
#插入数据
PUT my-index-000001/_doc/1
{
"group" : "fans",
"user" : [
{
"first" : "John",
"last" : "Smith"
},
{
"first" : "Alice",
"last" : "White"
}
]
}
测试使用原来的语句终于不会被绕过去了,但是修改成user.last改成"White"也不行,其实是其有自己特定的语法:
GET my-index-000001/_search
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "user",
"query": {
"bool": {
"must": [
{ "match": { "user.first": "Alice" }},
{"match": {"user.last": "White"}}
]
}
}
}
}
]
}
}
}
结果:
而last使用Smith是不行,修复问题了
#使用nested
GET my-index-000001/_search
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "user",
"query": {
"bool": {
"must": [
{ "match": { "user.first": "Alice" }},
{"match": {"user.last": "Smith"}}
]
}
}
}
}
]
}
}
}