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"

                      }

                    }

                  }

                }

              }

            }

          }

        }

      }

    }

  • 相关阅读:
    搭建博客
    开发常用的工具函数
    堆内存和栈内存及C++内存分配
    nuxt本机运行,如何用ip访问,localhost也可以访问?
    vue封装一个左滑删除的组件
    vue封装一个swiper组件
    YAPI安装google的cross-request插件
    vue项目中如何封装api,使请求方法清晰,适合协作开发
    axios封装一个请求本地数据的方法
    nuxt中vuex如何模块化分
  • 原文地址:https://www.cnblogs.com/jiahaoJAVA/p/11058403.html
Copyright © 2011-2022 走看看