一、出现的问题
这里有个教师索引teacher,其mapping信息如下
{
"properties": {
"name": {
"type": "keyword"
},
"age": {
"type": "integer"
},
"students": {
"properties": {
"name": {
"type": "keyword"
},
"age": {
"type": "integer"
}
}
}
}
}
新插入两条数据
{{es-host}}/teacher/_doc
{
"name": "张三",
"age": 34,
"students":[
{
"name": "小明",
"age": 13
},
{
"name": "小红",
"age": 14
}
]
}
{
"name": "李四",
"age": 35,
"students":[
{
"name": "小明",
"age": 14
},
{
"name": "小红",
"age": 13
}
]
}
张三老师和李四老师都有小明和小红两个学生,但是并非同一个人,其年龄是相反的,现在我想查询:姓名为小明,年龄14岁的学生,他的老师叫什么名字,查询方式如下:
{{es-host}}/teacher/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"students.name": "小明"
}
},
{
"term": {
"students.age": 14
}
}
]
}
}
}
查询结果如下:
{
"took": 15,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 1.2292043,
"hits": [
{
"_index": "teacher",
"_type": "_doc",
"_id": "edDrDYgBF_FDuIInec6p",
"_score": 1.2292043,
"_source": {
"name": "张三",
"age": 34,
"students": [
{
"name": "小明",
"age": 13
},
{
"name": "小红",
"age": 14
}
]
}
},
{
"_index": "teacher",
"_type": "_doc",
"_id": "etDrDYgBF_FDuIIn-84N",
"_score": 1.2292043,
"_source": {
"name": "李四",
"age": 35,
"students": [
{
"name": "小明",
"age": 14
},
{
"name": "小红",
"age": 13
}
]
}
}
]
}
}
可以看到,竟然把两个老师都查询出来了
二、如何解决
- 在创建mapping的时候将数据结构定义为nested类型
- 查询的时候使用nested查询
1. 创建nested类型
{{es-host}}/teacher/_mapping
{
"properties": {
"name": {
"type": "keyword"
},
"age": {
"type": "integer"
},
"students": {
"type": "nested",
"properties": {
"name": {
"type": "keyword"
},
"age": {
"type": "integer"
}
}
}
}
}
2. 再次查询为空
新增之前的那两条数据之后,再次查询
{{es-host}}/teacher/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"students.name": "小明"
}
},
{
"term": {
"students.age": 14
}
}
]
}
}
}
发现结果是空的
{
"took": 7,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 0,
"relation": "eq"
},
"max_score": null,
"hits": []
}
}
这是因为mapping定义是nested类型了,就必须使用nested查询方式
3. nested查询
{{es-host}}/teacher/_search
使用nested查询方式再次查询,查询句式
{
"query": {
"nested": {
"path": "students",
"query": {
//原来的query
}
}
}
}
其中的path指的是声明为nested类型的字段的path。
{
"query": {
"nested": {
"path": "students",
"query": {
"bool": {
"must": [
{
"term": {
"students.name": "小明"
}
},
{
"term": {
"students.age": 14
}
}
]
}
}
}
}
}
这时候就能查询出来结果了
{
"took": 8,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 1.6931472,
"hits": [
{
"_index": "teacher",
"_type": "_doc",
"_id": "fNAGDogBF_FDuIInL856",
"_score": 1.6931472,
"_source": {
"name": "李四",
"age": 35,
"students": [
{
"name": "小明",
"age": 14
},
{
"name": "小红",
"age": 13
}
]
}
}
]
}
}
正是我想要的查询结果
注意:本文归作者所有,未经作者允许,不得转载