假设Elastic search中一个index存储了系统中的文章及其赞赏记录,赞赏记录中包括赞赏者姓名和赞赏金额,这种情况下需要在elastic search中使用nested类型的内嵌对象.因为如果使用数组或者object对象的话,赞赏者姓名和赞赏金额不能被正确的关联.
1 建立index语句如下
代码语言:javascript复制PUT articles
{
"mappings": {
"doc": {
"properties": {
"payment": {
"type": "nested",
"properties": {
"amount": {
"type": "integer"
},
"name": {
"type": "keyword"
}
}
}
}
}
}
}
这样articles就有了payment这个nested类型的字段,payment里面的对象有amount和name,表示金额和姓名
2 产生如下数据,表示jack给文章1赞赏了29元,ross给文章1赞赏30元,ross给文章2赞赏31元
代码语言:javascript复制POST articles/doc/1
{
"payment": [
{
"name": "jack",
"amount": 29
},
{
"name": "ross",
"amount": 30
}
]
}
POST articles/doc/2
{
"payment": [
{
"name": "ross",
"amount": 31
}
]
}
3 现在想查询ross赞赏过的文章,需要使用nested query
代码语言:javascript复制GET articles/_search
{
"query": {
"nested": {
"path": "payment",
"query": {
"term": {
"payment.name": {
"value": "ross"
}
}
}
}
}
}
path表示了nested字段的名称,需要注意的是,查询语句中要指定查询字段的全名,所以赞赏者姓名要用"payment.name" 如果在多个index上进行nested查询,没有nested字段的index会报错,这时可以将ignore_unmapped设置为true
4 如果想查看赞赏的平均金额,需要用nested aggregation
代码语言:javascript复制GET articles/_search
{
"size": 0,
"aggs": {
"nested": {
"nested": {
"path": "payment"
},
"aggs": {
"amount_avg": {
"avg": {
"field": "payment.amount"
}
}
}
}
}
}
同样注意要用path指定字段名称,返回的数据中,比普通的聚合查询多了一层嵌套 返回结果为
代码语言:javascript复制{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 2,
"max_score": 0,
"hits": []
},
"aggregations": {
"nested": {
"doc_count": 3,
"amount_avg": {
"value": 30
}
}
}
}