elasticsearchelasticsearch

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 、 John2014-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
      }
    }
  }
}
上一篇 下一篇

猜你喜欢

热点阅读