文档id类型为keyword 性能最高
"query": { "nested": { "path": "user", "query": { } } } # path: nested对象的查询深度 # score_mode: ii.聚合分数计算方式 1.avg (默认):使用所有匹配的子对象的平均相关性得分。 2.max:使用所有匹配的子对象中的最高相关性得分。 3.min:使用所有匹配的子对象中最低的相关性得分。 4.none:不要使用匹配的子对象的相关性分数。该查询为父文档分配得分为0。 5.sum:将所有匹配的子对象的相关性得分相加。
解决方式
1.删除索引 2.重新创建索引, goods_list字段类型设置为:nested # 查询出必须为小米10并且价格为4999的 GET /order/_search { "query": { "bool": { "must": [ { "nested": { "path": "goods_list", "query": { "bool": { "must": [ { "match": { "goods_list.name": "小米10" } }, { "match": { "goods_list.price": 4999 } } ] } } } } ] } } }
省市区查询练习
#1.插入mapping PUT /area { "mappings": { "properties": { "province": { "type": "nested", "properties": { "name": { "type": "text", "analyzer": "ik_max_word" }, "cities": { "type": "nested", "properties": { "name": { "type": "text", "analyzer": "ik_max_word" }, "district": { "type": "nested", "properties": { "name": { "type": "text", "analyzer": "ik_max_word" } } } } } } } } } } #2.插入数据 PUT /area/_doc/1 { "province": { "name": "北京", "cities": [ { "name": "北京市", "district": [ {"name":"丰台区"}, {"name":"海淀区"}, {"name":"朝阳区"}, {"name":"东城区"}, {"name":"西城区"}, {"name":"昌平区"} ] } ] } } PUT /area/_doc/2 { "province": { "name": "河南省", "cities": [ { "name": "郑州市", "district": [ {"name":"金水区"}, {"name":"高新区"}, {"name":"郑东新区"}, {"name":"二七区"}, {"name":"中原区"}, {"name":"惠济区"} ] }, { "name": "鹤壁市", "district": [ {"name":"山城区"}, {"name":"淇滨区"}, {"name":"鹤山区"}, {"name":"朝歌"}, {"name":"浚县"} ] } ] } } PUT /area/_doc/3 { "province": { "name": "台湾省", "cities": [ { "name": "台北市", "district": [ {"name":"中正区"}, {"name":"大同区"}, {"name":"中山区"}, {"name":"万华区"}, {"name":"信义区"}, {"name":"松山区"} ] }, { "name": "高雄", "district": [ {"name":"小港区"}, {"name":"鼓山区"}, {"name":"三民区"} ] } ] } } #3.city为包含北京市 或者 包含淇滨区的 省份信息 GET /area/_search { "query": { "nested": { "path": "province", "query": { "nested": { "path": "province.cities", "query": { "bool": { "should": [ { "term": { "province.cities.name": "北京市" } }, { "nested": { "path": "province.cities.district", "query": { "bool": { "must": [ { "term": { "province.cities.district.name": "淇滨区" } } ] } } } } ] } } } } } } }
PUT /plan_index { "settings": { "number_of_shards": 3, "number_of_replicas": 1 }, "mappings": { "properties": { "plan_id":{ "type": "keyword" }, "plan_name":{ "type": "text", "fields": { "keyword":{ "type" : "keyword", "ignore_above" : 256 } } }, "act_id":{ "type": "keyword" }, "act_name":{ "type": "text", "fields": { "keyword":{ "type" : "keyword", "ignore_above" : 256 } } }, "comment_id":{ "type": "keyword" }, "comment_name":{ "type": "text", "fields": { "keyword":{ "type" : "keyword", "ignore_above" : 256 } } }, "creator":{ "type": "keyword" }, "create_time":{ "type": "date", "format": "yyyy-MM-dd||yyyy-MM-dd HH:mm:ss" }, "plan_join": { "type": "join", "relations": { "plan": ["activity", "book"], "book": "comments" } } } } }
添加父文档数据
#添加父文档数据 PUT /plan_index/_doc/plan-001 { "plan_id": "plan-001", "plan_name": "四月计划", "creator": "huan", "create_time": "2021-04-07 16:27:30", "plan_join": { "name": "plan" } } PUT /plan_index/_doc/plan-002 { "plan_id": "plan-002", "plan_name": "五月计划", "creator": "huan", "create_time": "2021-05-07 16:27:30", "plan_join": "plan" } 注意⚠️: 1.如果是创建父文档,则需要使用 plan_join 指定父文档的关系的名字(此处为plan)。 2.plan_join为创建索引的 mapping时指定join的字段的名字。 3.指定父文档时,plan_join的这2种写法都可以。 # 添加子文档数据 PUT /plan_index/_doc/act-001?routing=plan-001 { "act_id":"act-001", "act_name":"四月第一个活动", "creator":"huan.fu", "plan_join":{ "name":"activity", "parent":"plan-001" } } PUT /plan_index/_doc/book-001?routing=plan-001 { "book_id":"book-001", "book_name":"四月读取的第一本书", "creator":"huan.fu", "plan_join":{ "name":"book", "parent":"plan-001" } } PUT /plan_index/_doc/book-002?routing=plan-001 { "book_id":"book-002", "book_name":"编程珠玑", "creator":"huan.fu", "plan_join":{ "name":"book", "parent":"plan-001" } } PUT /plan_index/_doc/book-003?routing=plan-002 { "book_id":"book-003", "book_name":"java编程思想", "creator":"huan.fu", "plan_join":{ "name":"book", "parent":"plan-002" } } # 理论上 comment 的父文档是 book ,但是此处routing使用 plan 也是可以的。 PUT /plan_index/_doc/comment-001?routing=plan-001 { "comment_id":"comment-001", "comment_name":"这本书还可以", "creator":"huan.fu", "plan_join":{ "name":"comments", "parent":"book-001" } } PUT /plan_index/_doc/comment-002?routing=plan-001 { "comment_id":"comment-002", "comment_name":"值得一读,棒。", "creator":"huan.fu", "plan_join":{ "name":"comments", "parent":"book-001" } } 注意⚠️: 1. routing=plan-001 子文档需要和父档使用相同的路由键 2. "name":"book" 子文档在mapping-join中定义的名字 3. "parent":"plan-001" 父文档id
#返回父文档id是plan-001下的类型为book的所有子文档。 GET /plan_index/_search { "query":{ "parent_id": { "type":"book", "id":"plan-001" } } }
#返回创建者(creator)是huan.fu,并且子文档最少有2个的父文档。 GET /plan_index/_search { "query": { "has_child": { "type": "book", "min_children": 2, "query": { "match": { "creator": "huan.fu" } } } } }
#返回父文档(book)的创建者是huan.fu的所有子文档 GET /plan_index/_search { "query": { "has_parent": { "parent_type": "book", "query": { "match": { "creator":"huan.fu" } } } } }
Nested Object | join |
---|---|
1、文档存储在一起,读取性能高 | 1、父子文档单独存储,互不影响。但是为了维护join的关系,需要占用额外的内容,读取性能略差。 |
2、更新父文档或子文档时,需要更新整个文档。 | 2、父文档和子文档可以单独更新。 |
3、适用于查询频繁,子文档偶尔更新的情况。 | 3、适用于更新频繁的情况,且子文档的数量远远超过父文档的数量。 |