elasticsearch的嵌套查询nested
2022-02-25 本文已影响0人
virtual灬zzZ
基于es7,kibana7

如果一条记录中有多个评论,记录视为对象,评论也视为对象,我们使用以下语句插入语句,默认的,不预先进行mapping设置。
#####数组属性嵌套关键!!!!!使用nested
PUT /nested_test/_doc/1
{
"title": "Nest eggs",
"body": "Making your money work...",
"tags": [ "cash", "shares" ],
"comments": [
{
"name": "John Smith",
"comment": "Great article",
"age": 28,
"stars": 4,
"date": "2014-09-01"
},
{
"name": "Alice White",
"comment": "More like this please",
"age": 31,
"stars": 5,
"date": "2014-10-22"
}
]
}
GET /nested_test/_mapping
之后查询,
GET /nested_test/_doc/_search
{
"query":{
"bool":{
"must":[
{"match":{"comments.name":"alice"}},
{"match":{"comments.age":28}}
]
}
}
}
可见居然是有记录被搜索出来的,但alice的age是31的,为何如此?
因为es底层放置数据是这样的:
{
"title": [ eggs, nest ],
"body": [ making, money, work, your ],
"tags": [ cash, shares ],
"comments.name": [ alice, john, smith, white ],
"comments.comment": [ article, great, like, more, please, this ],
"comments.age": [ 28, 31 ],
"comments.stars": [ 4, 5 ],
"comments.date": [ 2014-09-01, 2014-10-22 ]
}
Alice
和 31 、John
和2014-09-01
之间的相关性信息不再存在。虽然object
类型 (参见 内部对象) 在存储 单一对象 时非常有用,但对于对象数组的搜索而言,毫无用处。嵌套对象 就是来解决这个问题的。将
comments
字段类型设置为nested
,每一个嵌套对象都会被索引为一个 隐藏的独立文档 ,解析如下:
{
"comments.name": [ john, smith ],
"comments.comment": [ article, great ],
"comments.age": [ 28 ],
"comments.stars": [ 4 ],
"comments.date": [ 2014-09-01 ]
}
{
"comments.name": [ alice, white ],
"comments.comment": [ like, more, please, this ],
"comments.age": [ 31 ],
"comments.stars": [ 5 ],
"comments.date": [ 2014-10-22 ]
}
{
"title": [ eggs, nest ],
"body": [ making, money, work, your ],
"tags": [ cash, shares ]
}
可见2个comment被分割成2个对象了,title这些称谓父文档。
于是先删除改索引,重新建:
DELETE /nested_test
PUT /nested_test
{
"mappings": {
"properties": {
"title":{"type":"text"},
"body":{"type":"text"},
"comments": {
"type": "nested",
"properties": {
"name": {
"type": "text"
},
"comment": {
"type": "text"
},
"age": {
"type": "short"
},
"stars": {
"type": "short"
},
"date": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
}
}
}
}
}
}
GET /nested_test/_mapping
PUT /nested_test/_doc/1
{
"title": "Nest eggs",
"body": "Making your money work...",
"tags": [ "cash", "shares" ],
"comments": [
{
"name": "John Smith",
"comment": "Great article",
"age": 28,
"stars": 4,
"date": "2014-09-01"
},
{
"name": "Alice White",
"comment": "More like this please",
"age": 31,
"stars": 5,
"date": "2014-10-22"
}
]
}
再执行查询:
GET /nested_test/_doc/_search
{
"query":{
"match":{
"tags":"cash"
}
}
}
#####嵌套查询与嵌套聚合
GET /nested_test/_doc/_search
{
"query": {
"bool": {
"must": {
"nested": {
"path": "comments",
"query": {
"bool": {
"must": [
{
"match": {
"comments.name": "john"
}
},
{
"match": {
"comments.age": 28
}
}
]
}
}
}
}
}
},
"aggs": {
"mycomments": {
"nested": {
"path": "comments"
},
"aggs": {
"totalComStar": {
"sum": {
"field": "comments.stars"
}
}
}
}
}
}
结果为:
#! [types removal] Specifying types in search requests is deprecated.
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.6931472,
"hits" : [
{
"_index" : "nested_test",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.6931472,
"_source" : {
"title" : "Nest eggs",
"body" : "Making your money work...",
"tags" : [
"cash",
"shares"
],
"comments" : [
{
"name" : "John Smith",
"comment" : "Great article",
"age" : 28,
"stars" : 4,
"date" : "2014-09-01"
},
{
"name" : "Alice White",
"comment" : "More like this please",
"age" : 31,
"stars" : 5,
"date" : "2014-10-22"
}
]
}
}
]
},
"aggregations" : {
"mycomments" : {
"doc_count" : 2,
"totalComStar" : {
"value" : 9.0
}
}
}
}