note
- 干货 | Elasticsearch Nested类型深入详解
- elasticsearch(lucene)使用的库没有内部对象的概念,因此内部对象被扁平化为一个简单的字段名称和值列表。
- 为了解决这个问题,需要用到 nested,nested对象会被作为隐式对象处理。其内容不会被扁平化处理。
- 关联 doc 必须保存于同一个分片,所以在构建 index的时候,需要添加 routing=parent_id 参数
demo
nested
DELETE /netest_index PUT /netest_index { "mappings": { "properties": { "title":{ "type":"text" }, "comments": { "type": "nested", "properties": { "name":{ "type":"text" }, "comment":{ "type":"text" } } } } } } POST /netest_index/_doc/1 { "title":"es", "comments":[ { "name": "zhengcj", "count": 6 }, { "name":"dongyc", "count":1 } ] } POST /netest_index/_doc/2 { "title":"java", "comments": [ { "name": "zhengcj", "count": 6 }, { "name":"ljr", "count":2 } ] } GET /netest_index/_search { "query": { "nested" : { "path" : "comments", "query" : { "bool" : { "must" : [ { "match" : {"comments.name" : "zhengcj"} }, { "range" : {"comments.count" : {"gte" : 6}} } ] } }, "score_mode" : "avg" } } } POST netest_index/_update/1 { "script": { "lang": "painless", "source": "ctx._source.comments.removeIf(it->it.name=='dongyc')" } } POST /netest_index/_update/1 { "script":{ "source": "for(e in ctx._source.comments){if(e.name=='zhengcj'){e.count+=1;}}" } } GET /netest_index/_search { "size": 0, "aggs":{ "nested_aggs":{ "nested":{ "path":"comments" }, "aggs":{ "min_count":{ "min":{ "field":"comments.count" } } } } } } join/has_parent/has_child
init data
DELETE stack_overflow PUT stack_overflow { "mappings": { "properties": { "join": { "type": "join", "relations": { "question": "answer" } }, "key":{ "type": "keyword" }, "view_count":{ "type":"integer" } } } } PUT stack_overflow/_doc/1 { "join": { "name": "question" }, "body": "<p>I have Windows 2003 server and i bought a new Windows 2008 server...", "title": "Whats the best way to file transfer my site from server to a newer one?", "tags": [ "windows-server-2003", "windows-server-2008", "file-transfer" ], "key":"2003-2008", "view_count":10 } PUT stack_overflow/_doc/2 { "join": { "name": "question" }, "body": "ELK body", "title": "ELK", "tags": [ "es", "kibana", "logstash" ], "key":"ELK", "view_count":2 } # 必须包含 routing=n,关联 doc 必须保存于同一个分片 PUT stack_overflow/_doc/11?routing=1 { "join": { "name": "answer", "parent": "1" }, "owner": { "location": "Norfolk, United Kingdom", "display_name": "Sam", "id": 48 }, "body": "<p>Unfortunately you're pretty much limited to FTP...", "creation_date": "2009-05-04T13:45:37.030", "key":"FTP", "view_count":3 } PUT stack_overflow/_doc/12?routing=1&refresh { "join": { "name": "answer", "parent": "1" }, "owner": { "location": "Norfolk, United Kingdom", "display_name": "Troll", "id": 49 }, "body": "<p>Use Linux...", "creation_date": "2009-05-05T13:45:37.030", "key":"Linux", "view_count":4 } PUT stack_overflow/_doc/21?routing=2 { "join": { "name": "answer", "parent": "2" }, "owner": { "location": "Norfolk, United Kingdom", "display_name": "Sam", "id": 48 }, "body": "this is answer to es in body", "creation_date": "2009-05-04T13:45:37.030", "key":"es", "view_count":5 } join
查询一个人回答过问题的标签,即这个人关注的问题
POST stack_overflow/_search?size=0 { "aggs": { "top-names": { "terms": { "field": "owner.display_name.keyword", "size": 10 }, "aggs": { "to-questions": { "parent": { "type": "answer" }, "aggs": { "top-tags": { "terms": { "field": "tags.keyword", "size": 10 } } } } } } } } has_parent
根据 parent是否满足条件,返回child
GET /stack_overflow/_search { "query": { "has_parent": { "parent_type": "question", "query": { "term": { "key": { "value": "ELK" } } } } } } GET /stack_overflow/_search { "query": { "has_parent": { "parent_type": "question", "score":true, "query": { "function_score": { "script_score": { "script": "_score * doc['view_count'].value+1" } } } } } } has_child
根据 child是否满足条件,返回parent
GET /stack_overflow/_search { "query": { "has_child": { "type": "answer", "query": { "match_all": {} }, "max_children": 5, "min_children": 2, "score_mode": "min" } } } 文章来源: https://blog.csdn.net/weixin_43834662/article/details/97266631