嵌套类型查询、父子级关系查询
一、嵌套查询
1、测试数据: 不手动设置索引类型,全部使用dynamic_mapping
1 PUT /order/_doc/1 2 { 3 "order_name": "扫地机器人订单", 4 "desc": "shouji zhong de zhandouji", 5 "goods_count": 2, 6 "total_price": 12699, 7 "goods_list": [ 8 { 9 "name": "小米扫地机器人", 10 "price": 1999 11 }, 12 { 13 "name": "洗碗机", 14 "price": 4999 15 } 16 ] 17 }
如果直接使用bool查询name为小米扫地机器人,价格为4999的数据。按理说不会有数据,但是结果会查询出数据。
1 GET order/_search 使用此查询会查询出结果,但这很明显不是我们想要的 2 { 3 "query": { 4 "bool": { 5 "must": [ 6 { 7 "match": { 8 "goods_list.name": "洗碗机" 9 } 10 }, 11 { 12 "match": { 13 "goods_list.price": "1999" 14 } 15 } 16 ] 17 } 18 } 19 }
是因为goods_list字段使用了dynamic_mapping,没有设置为nested类型。es底层会将goods_list中name字段所有值放到一个数组中,price字段的所有值放到一个数组中,从而失去了一对一的关系。最终导致可以查出数据。
解决办法:
1 PUT order 2 { 3 "mappings": { 4 "properties": { 5 "goods_list": { 6 "type": "nested", 7 "properties": { 8 "name": { 9 "type": "text", 10 "analyzer": "ik_max_word", 11 "fields": { 12 "keyword": { 13 "type": "keyword", 14 "ignore_above": 256 15 } 16 } 17 } 18 } 19 } 20 } 21 } 22 }
设置nested后再进行查询:
1 GET /order/_search 2 { 3 "query": { 4 "nested": { 5 "path": "goods_list", 6 "query": { 7 "bool": { 8 "must": [ 9 { 10 "match": { 11 "goods_list.name": "小米10" 12 } 13 }, 14 { 15 "match": { 16 "goods_list.price": 4999 17 } 18 } 19 ] 20 } 21 } 22 } 23 } 24 }
二、父子级关系
1、设置join的mapping
1 PUT msb_depart 2 { 3 "mappings": { 4 "properties": { 5 "msb_join_field": { 6 "type": "join", join表示存在父子级关系 7 "relations": { 该字段指定父级与子级,键值对中key为父级,value为子级 8 "depart": "employee" depart为父级,employee为子级 9 } 10 }, 11 "my_id": { 12 "type": "keyword" 13 } 14 } 15 } 16 }
2、插入父级数据
1 #部门 2 PUT msb_depart/_doc/1 3 { 4 "my_id": 1, 5 "name":"教学部", 6 "msb_join_field":{ 7 "name":"depart" 8 } 9 } 10 PUT msb_depart/_doc/2 11 { 12 "my_id": 2, 13 "name":"咨询部", 14 "msb_join_field":{ 15 "name":"depart" 16 } 17 }
3、插入子级数据
1 # 路由值是强制性的,因为父文档和子文档必须在同一个分片上建立索引 2 PUT msb_depart/_doc/3?routing=1&refresh 3 { 4 "my_id": 3, 5 "name":"马老师", 6 "msb_join_field":{ 7 "name":"employee", 8 "parent":1 9 } 10 } 11 PUT msb_depart/_doc/4?routing=1&refresh 12 { 13 "my_id": 4, 14 "name":"周老师", 15 "msb_join_field":{ 16 "name":"employee", 17 "parent":1 18 } 19 } 20 PUT msb_depart/_doc/5?routing=1&refresh 21 { 22 "my_id": 5, 23 "name":"静静", 24 "msb_join_field":{ 25 "name":"employee", 26 "parent":2 27 } 28 } 29 PUT msb_depart/_doc/6?routing=1&refresh 30 { 31 "my_id": 6, 32 "name":"球球", 33 "msb_join_field":{ 34 "name":"employee", 35 "parent":2 36 } 37 } 38 PUT msb_depart/_doc/7?routing=1&refresh 39 { 40 "my_id": 7, 41 "name":"琪琪", 42 "msb_join_field":{ 43 "name":"employee", 44 "parent":2 45 } 46 }
4、查询所有的部门
1 GET msb_depart/_search 2 { 3 "query": { 4 "has_child": { has_child:有孩子说明是父亲,has_parent:有父亲说明是孩子 5 "type": "employee", 6 "query": { 7 "match_all": {} 8 } 9 } 10 } 11 }
5、搜索周老师所在的部门
1 GET msb_depart/_search 2 { 3 "query": { 4 "has_child": { 5 "type": "employee", 6 "query": { 7 "match": { 8 "name.keyword": "周老师" 9 } 10 } 11 } 12 } 13 }
6、搜索咨询部所有的老师
1 GET msb_depart/_search 2 { 3 "query": { 4 "has_parent": { 5 "parent_type": "depart", 6 "query": { 7 "match": { 8 "name.keyword": "咨询部" 9 } 10 } 11 } 12 } 13 }
7、搜索部门id为2的部门员工
1 GET msb_depart/_search 2 { 3 "query": { 4 "parent_id":{ 5 "type":"employee", 6 "id":2 7 } 8 } 9 }