zoukankan      html  css  js  c++  java
  • Elasticsearch深入9

    bucket与metric两个核心概念

    两个核心概念:bucket和metric

    bucket:一个数据分组

    city name

    北京 小李
    北京 小王
    上海 小张
    上海 小丽
    上海 小陈

    基于city划分buckets

    划分出来两个bucket,一个是北京bucket,一个是上海bucket

    北京bucket:包含了2个人,小李,小王
    上海bucket:包含了3个人,小张,小丽,小陈

    按照某个字段进行bucket划分,那个字段的值相同的那些数据,就会被划分到一个bucket中

    有一些mysql的sql知识的话,聚合,首先第一步就是分组,对每个组内的数据进行聚合分析,分组,就是我们的bucket

    metric:对一个数据分组执行的统计

    当我们有了一堆bucket之后,就可以对每个bucket中的数据进行聚合分词了,比如说计算一个bucket内所有数据的数量,或者计算一个bucket内所有数据的平均值,最大值,最小值

    metric,就是对一个bucket执行的某种聚合分析的操作,比如说求平均值,求最大值,求最小值

    select count(*)
    from access_log
    group by user_id

    bucket:group by user_id --> 那些user_id相同的数据,就会被划分到一个bucket中
    metric:count(*),对每个user_id bucket中所有的数据,计算一个数量

    hitogram按价格区间统计电视销量和销售额

    histogram:类似于terms,也是进行bucket分组操作,接收一个field,按照这个field的值的各个范围区间,进行bucket分组操作

    "histogram":{
    "field": "price",
    "interval": 2000
    },

    interval:2000,划分范围,0~2000,2000~4000,4000~6000,6000~8000,8000~10000,buckets

    去根据price的值,比如2500,看落在哪个区间内,比如2000~4000,此时就会将这条数据放入2000~4000对应的那个bucket中

    bucket划分的方法,terms,将field值相同的数据划分到一个bucket中

    bucket有了之后,一样的,去对每个bucket执行avg,count,sum,max,min,等各种metric操作,聚合分析

    {
        "size":0,
        "aggs":{
            "price":{
                "histogram":{
                    "field":"price",
                    "interval":2000
                },
                "aggs":{
                    "revenue":{
                        "sum":{
                            "field":"price"
                        }
                    }
                }
            }
        }
    }

    bucket,分组操作,histogram,按照某个值指定的interval,划分一个一个的bucket

    date histogram,按照我们指定的某个date类型的日期field,以及日期interval,按照一定的日期间隔,去划分bucket

    date interval = 1m,

    2017-01-01~2017-01-31,就是一个bucket
    2017-02-01~2017-02-28,就是一个bucket

    然后会去扫描每个数据的date field,判断date落在哪个bucket中,就将其放入那个bucket

    2017-01-05,就将其放入2017-01-01~2017-01-31,就是一个bucket

    min_doc_count:即使某个日期interval,2017-01-01~2017-01-31中,一条数据都没有,那么这个区间也是要返回的,不然默认是会过滤掉这个区间的
    extended_bounds,min,max:划分bucket的时候,会限定在这个起始日期,和截止日期内

    GET /tvs/sales/_search
    {
        "size":0,
        "aggs":{
            "sales":{
                "date_histogram":{
                    "field":"sold_date",
                    "interval":"month",
                    "format":"yyyy-MM-dd",
                    "min_doc_count":0,
                    "extended_bounds":{
                        "min":"2016-01-01",
                        "max":"2017-12-31"
                    }
                }
            }
        }
    }

    基于nested object实现博客与评论嵌套关系

    1、做一个实验,引出来为什么需要nested object

     冗余数据方式的来建模,其实用的就是object类型,我们这里又要引入一种新的object类型,nested object类型

     博客,评论,做的这种数据模型

     PUT /website/blogs/6

    {

      "title": "花无缺发表的一篇帖子",

      "content":  "我是花无缺,大家要不要考虑一下投资房产和买股票的事情啊。。。",

      "tags":  [ "投资", "理财" ],

      "comments": [

        {

          "name":    "小鱼儿",

          "comment": "什么股票啊?推荐一下呗",

          "age":     28,

          "stars":   4,

          "date":    "2016-09-01"

        },

        {

          "name":    "黄药师",

          "comment": "我喜欢投资房产,风,险大收益也大",

          "age":     31,

          "stars":   5,

          "date":    "2016-10-22"

        }

      ]

    }

    被年龄是28岁的黄药师评论过的博客,搜索

    GET /website/blogs/_search

    {

      "query": {

        "bool": {

          "must": [

            { "match": { "comments.name": "黄药师" }},

            { "match": { "comments.age":  28      }}

          ]

        }

      }

    }

    {

      "took": 102,

      "timed_out": false,

      "_shards": {

        "total": 5,

        "successful": 5,

        "failed": 0

      },

      "hits": {

        "total": 1,

        "max_score": 1.8022683,

        "hits": [

          {

            "_index": "website",

            "_type": "blogs",

            "_id": "6",

            "_score": 1.8022683,

            "_source": {

              "title": "花无缺发表的一篇帖子",

              "content": "我是花无缺,大家要不要考虑一下投资房产和买股票的事情啊。。。",

              "tags": [

                "投资",

                "理财"

              ],

              "comments": [

                {

                  "name": "小鱼儿",

                  "comment": "什么股票啊?推荐一下呗",

                  "age": 28,

                  "stars": 4,

                  "date": "2016-09-01"

                },

                {

                  "name": "黄药师",

                  "comment": "我喜欢投资房产,风,险大收益也大",

                  "age": 31,

                  "stars": 5,

                  "date": "2016-10-22"

                }

              ]

            }

          }

        ]

      }

    }

    结果是。。。好像不太对啊???

    object类型数据结构的底层存储。。。

     {

      "title":            [ "花无缺", "发表", "一篇", "帖子" ],

      "content":             [ "我", "是", "花无缺", "大家", "要不要", "考虑", "一下", "投资", "房产", "买", "股票", "事情" ],

      "tags":             [ "投资", "理财" ],

      "comments.name":    [ "小鱼儿", "黄药师" ],

      "comments.comment": [ "什么", "股票", "推荐", "我", "喜欢", "投资", "房产", "风险", "收益", "大" ],

      "comments.age":     [ 28, 31 ],

      "comments.stars":   [ 4, 5 ],

      "comments.date":    [ 2016-09-01, 2016-10-22 ]

    }

    object类型底层数据结构,会将一个json数组中的数据,进行扁平化

     所以,直接命中了这个document,name=黄药师,age=28,正好符合

     2、引入nested object类型,来解决object类型底层数据结构导致的问题

     修改mapping,将comments的类型从object设置为nested

     PUT /website

    {

      "mappings": {

        "blogs": {

          "properties": {

            "comments": {

              "type": "nested",

              "properties": {

                "name":    { "type": "string"  },

                "comment": { "type": "string"  },

                "age":     { "type": "short"   },

                "stars":   { "type": "short"   },

                "date":    { "type": "date"    }

              }

            }

          }

        }

      }

    }

    {

      "comments.name":    [ "小鱼儿" ],

      "comments.comment": [ "什么", "股票", "推荐" ],

      "comments.age":     [ 28 ],

      "comments.stars":   [ 4 ],

      "comments.date":    [ 2014-09-01 ]

    }

    {

      "comments.name":    [ "黄药师" ],

      "comments.comment": [ "我", "喜欢", "投资", "房产", "风险", "收益", "大" ],

      "comments.age":     [ 31 ],

      "comments.stars":   [ 5 ],

      "comments.date":    [ 2014-10-22 ]

    }

    {

      "title":            [ "花无缺", "发表", "一篇", "帖子" ],

      "body":             [ "我", "是", "花无缺", "大家", "要不要", "考虑", "一下", "投资", "房产", "买", "股票", "事情" ],

      "tags":             [ "投资", "理财" ]

    }

    再次搜索,成功了。。。

     GET /website/blogs/_search

    {

      "query": {

        "bool": {

          "must": [

            {

              "match": {

                "title": "花无缺"

              }

            },

            {

              "nested": {

                "path": "comments",

                "query": {

                  "bool": {

                    "must": [

                      {

                        "match": {

                          "comments.name": "黄药师"

                        }

                      },

                      {

                        "match": {

                          "comments.age": 28

                        }

                      }

                    ]

                  }

                }

              }

            }

          ]

        }

      }

    }

    score_mode:max,min,avg,none,默认是avg

     如果搜索命中了多个nested document,如何讲个多个nested document的分数合并为一个分数

    聚合数据分析的需求1:按照评论日期进行bucket划分,然后拿到每个月的评论的评分的平均值

     GET /website/blogs/_search

    {

      "size": 0,

      "aggs": {

        "comments_path": {

          "nested": {

            "path": "comments"

          },

          "aggs": {

            "group_by_comments_date": {

              "date_histogram": {

                "field": "comments.date",

                "interval": "month",

                "format": "yyyy-MM"

              },

              "aggs": {

                "avg_stars": {

                  "avg": {

                    "field": "comments.stars"

                  }

                }

              }

            }

          }

        }

      }

    }

    聚合数据分析的需求2:按发表人年龄划分tags的统计

    GET /website/blogs/_search

    {

      "size": 0,

      "aggs": {

        "comments_path": {

          "nested": {

            "path": "comments"

          },

          "aggs": {

            "group_by_comments_age": {

              "histogram": {

                "field": "comments.age",

                "interval": 10

              },

              "aggs": {

                "reverse_path": {

                  "reverse_nested": {},//可以使用comments外的filed今天聚合操作

                  "aggs": {

                    "group_by_tags": {

                      "terms": {

                        "field": "tags.keyword"

                      }

                    }

                  }

                }

              }

            }

          }

        }

      }

    }

  • 相关阅读:
    统计nginx日志里访问次数最多的前十个IP
    while 格式化输出 运算符 字符编码
    Python 软件安装
    Python 基础
    Typora 基础的使用方法
    Django ORM (四) annotate,F,Q 查询
    Django 惰性机制
    Django ORM (三) 查询,删除,更新操作
    Django ORM (二) 增加操作
    Django ORM (一) 创建数据库和模型常用的字段类型参数及Field 重要参数介绍
  • 原文地址:https://www.cnblogs.com/jiahaoJAVA/p/11058403.html
Copyright © 2011-2022 走看看