当前位置: 首页 > news >正文

门户网站服务范围做暧暖ox网站

门户网站服务范围,做暧暖ox网站,前端刚毕业开多少工资,关闭WordPress文章摘要在这之前#xff0c;本书致力于搜索。 通过搜索#xff0c;如果我们有一个查询并且希望找到匹配这个查询的文档集#xff0c;就好比在大海捞针。 通过聚合#xff0c;我们会得到一个数据的概览。我们需要的是分析和总结全套的数据而不是寻找单个文档#xff1a; 在大海里…在这之前本书致力于搜索。 通过搜索如果我们有一个查询并且希望找到匹配这个查询的文档集就好比在大海捞针。 通过聚合我们会得到一个数据的概览。我们需要的是分析和总结全套的数据而不是寻找单个文档 在大海里有多少针针的平均长度是多少按照针的制造商来划分针的长度中位值是多少每月加入到海中的针有多少 聚合也可以回答更加细微的问题 你最受欢迎的针的制造商是什么这里面有异常的针么 聚合允许我们向数据提出一些复杂的问题。虽然功能完全不同于搜索但它使用相同的数据结构。这意味着聚合的执行速度很快并且就像搜索一样几乎是实时的。 这对报告和仪表盘是非常强大的。你可以实时显示你的数据让你立即回应而不是对你的数据进行汇总 需要一周时间去运行的 Hadoop 任务 您的报告随着你的数据变化而变化而不是预先计算的、过时的和不相关的。 最后聚合和搜索是一起的。 这意味着你可以在单个请求里同时对相同的数据进行搜索/过滤和分析。并且由于聚合是在用户搜索的上下文里计算的你不只是显示四星酒店的数量而是显示匹配查询条件的四星酒店的数量。 聚合是如此强大以至于许多公司已经专门为数据分析建立了大型 Elasticsearch 集群。 高阶概念 类似于 DSL 查询表达式聚合也有 可组合 的语法独立单元的功能可以被混合起来提供你需要的自定义行为。这意味着只需要学习很少的基本概念就可以得到几乎无尽的组合。 要掌握聚合你只需要明白两个主要的概念 桶Buckets 满足特定条件的文档的集合 指标Metrics 对桶内的文档进行统计计算 这就是全部了每个聚合都是一个或者多个桶和零个或者多个指标的组合。翻译成粗略的SQL语句来解释吧 SELECT COUNT(color) FROM table GROUP BY color COUNT(color) 相当于指标。GROUP BY color 相当于桶。 桶在概念上类似于 SQL 的分组GROUP BY而指标则类似于 COUNT() 、 SUM() 、 MAX() 等统计方法。 让我们深入这两个概念 并且了解和这两个概念相关的东西。 桶 桶 简单来说就是满足特定条件的文档的集合 一个雇员属于 男性 桶或者 女性 桶奥尔巴尼属于 纽约 桶日期2014-10-28属于 十月 桶 当聚合开始被执行每个文档里面的值通过计算来决定符合哪个桶的条件。如果匹配到文档将放入相应的桶并接着进行聚合操作。 桶也可以被嵌套在其他桶里面提供层次化的或者有条件的划分方案。例如辛辛那提会被放入俄亥俄州这个桶而 整个 俄亥俄州桶会被放入美国这个桶。 Elasticsearch 有很多种类型的桶能让你通过很多种方式来划分文档时间、最受欢迎的词、年龄区间、地理位置等等。其实根本上都是通过同样的原理进行操作基于条件来划分文档。 指标 桶能让我们划分文档到有意义的集合但是最终我们需要的是对这些桶内的文档进行一些指标的计算。分桶是一种达到目的的手段它提供了一种给文档分组的方法来让我们可以计算感兴趣的指标。 大多数 指标 是简单的数学运算例如最小值、平均值、最大值还有汇总这些是通过文档的值来计算。在实践中指标能让你计算像平均薪资、最高出售价格、95%的查询延迟这样的数据。 桶和指标的组合 聚合 是由桶和指标组成的。 聚合可能只有一个桶可能只有一个指标或者可能两个都有。也有可能有一些桶嵌套在其他桶里面。例如我们可以通过所属国家来划分文档桶然后计算每个国家的平均薪酬指标。 由于桶可以被嵌套我们可以实现非常多并且非常复杂的聚合 通过国家划分文档桶然后通过性别划分每个国家桶然后通过年龄区间划分每种性别桶最后为每个年龄区间计算平均薪酬指标 最后将告诉你每个 国家, 性别, 年龄 组合的平均薪酬。所有的这些都在一个请求内完成并且只遍历一次数据 尝试聚合 我们可以用以下几页定义不同的聚合和它们的语法 但学习聚合的最佳途径就是用实例来说明。 一旦我们获得了聚合的思想以及如何合理地嵌套使用它们那么语法就变得不那么重要了。 聚合的桶操作和度量的完整用法可以在 Elasticsearch 参考 中找到。本章中会涵盖其中很多内容但在阅读完本章后查看它会有助于我们对它的整体能力有所了解。 所以让我们先看一个例子。我们将会创建一些对汽车经销商有用的聚合数据是关于汽车交易的信息车型、制造商、售价、何时被出售等。 首先我们批量索引一些数据 POST /cars/_bulk { index: {}} { price : 10000, color : red, make : honda, sold : 2014-10-28 } { index: {}} { price : 20000, color : red, make : honda, sold : 2014-11-05 } { index: {}} { price : 30000, color : green, make : ford, sold : 2014-05-18 } { index: {}} { price : 15000, color : blue, make : toyota, sold : 2014-07-02 } { index: {}} { price : 12000, color : green, make : toyota, sold : 2014-08-19 } { index: {}} { price : 20000, color : red, make : honda, sold : 2014-11-05 } { index: {}} { price : 80000, color : red, make : bmw, sold : 2014-01-01 } { index: {}} { price : 25000, color : blue, make : ford, sold : 2014-02-12 }有了数据开始构建我们的第一个聚合。汽车经销商可能会想知道哪个颜色的汽车销量最好用聚合可以轻易得到结果用 terms 桶操作 GET /cars/_search {size: 0,aggs: {popular_colors: {terms: {field: color.keyword}}} }“size”: 0: 这个参数指示Elasticsearch不返回搜索结果文档因为我们只对文档进行聚合统计而不需要实际文档内容。因此将搜索结果的大小设置为0。聚合操作被置于顶层参数 aggs 之下如果你愿意完整形式 aggregations 同样有效。然后可以为聚合指定一个我们想要名称本例中是 popular_colors 。最后定义单个桶的类型 terms 。“field”: “color.keyword”: 这里指定了聚合应该基于哪个字段进行。 “.keyword” 是指定的字段类型它告诉Elasticsearch使用未分词的精确值进行聚合。通常当您想要对关键字类型的字段执行聚合时应该使用 “.keyword”。在这个查询中使用了 “terms” 聚合类型是因为我们想要对指定字段的值进行分桶以便统计每个唯一值的数量。对于汽车颜色这样的情况我们希望知道每种颜色出现的次数而 “terms” 聚合正是用来实现这个目的的。 而不同于其他聚合类型如 “avg”、“sum”、“min”、“max” 等它们是用来对数值型数据进行聚合操作的。而 “terms” 聚合则专门用于处理文本类型的字段将文本字段的值进行分组统计每个不同值的出现次数。在实际应用中常常用于分析文本数据的分布情况比如用户的地理位置、产品的类别、标签等。 聚合是在特定搜索结果背景下执行的 这也就是说它只是查询请求的另外一个顶层参数例如使用 /_search 端点。 聚合可以与查询结对但我们会晚些在 限定聚合的范围Scoping Aggregations 中来解决这个问题。 然后我们为聚合定义一个名字名字的选择取决于使用者响应的结果会以我们定义的名字为标签这样应用就可以解析得到的结果。 随后我们定义聚合本身在本例中我们定义了一个单 terms 桶。 这个 terms 桶会为每个碰到的唯一词项动态创建新的桶。 因为我们告诉它使用 color 字段所以 terms 桶会为每个颜色动态创建新桶。 让我们运行聚合并查看结果 {took: 2,timed_out: false,_shards: {total: 1,successful: 1,skipped: 0,failed: 0},hits: {total: {value: 8,relation: eq},max_score: null,hits: []},aggregations: {popular_colors: {doc_count_error_upper_bound: 0,sum_other_doc_count: 0,buckets: [{key: red,doc_count: 4},{key: blue,doc_count: 2},{key: green,doc_count: 2}]}} }因为我们设置了 size 参数所以不会有 hits 搜索结果返回。popular_colors 聚合是作为 aggregations 字段的一部分被返回的。每个桶的 key 都与 color 字段里找到的唯一词对应。它总会包含 doc_count 字段告诉我们包含该词项的文档数量。每个桶的数量代表该颜色的文档数量。 响应包含多个桶每个对应一个唯一颜色例如红 或 绿。每个桶也包括 聚合进 该桶的所有文档的数量。例如有四辆红色的车。 前面的这个例子完全是实时执行的一旦文档可以被搜到它就能被聚合。这也就意味着我们可以直接将聚合的结果源源不断的传入图形库然后生成实时的仪表盘。 不久你又销售了一辆银色的车我们的图形就会立即动态更新银色车的统计信息。 瞧这就是我们的第一个聚合 添加度量指标 前面的例子告诉我们每个桶里面的文档数量这很有用。但通常我们的应用需要提供更复杂的文档度量。 例如每种颜色汽车的平均价格是多少 为了获取更多信息我们需要告诉 Elasticsearch 使用哪个字段计算何种度量。 这需要将度量 嵌套 在桶内 度量会基于桶内的文档计算统计结果。 让我们继续为汽车的例子加入 average 平均度量 GET /cars/_search {size: 0,aggs: {colors: {terms: {field: color.keyword},aggs: {avg_price: {avg: {field: price}}}}} }为度量新增 aggs 层。为度量指定名字 avg_price 。最后为 price 字段定义 avg 度量。 正如所见我们用前面的例子加入了新的 aggs 层。这个新的聚合层让我们可以将 avg 度量嵌套置于 terms 桶内。实际上这就为每个颜色生成了平均价格。 正如 颜色 的例子我们需要给度量起一个名字 avg_price 这样可以稍后根据名字获取它的值。最后我们指定度量本身 avg 以及我们想要计算平均值的字段 price {took: 1,timed_out: false,_shards: {total: 1,successful: 1,skipped: 0,failed: 0},hits: {total: {value: 8,relation: eq},max_score: null,hits: []},aggregations: {colors: {doc_count_error_upper_bound: 0,sum_other_doc_count: 0,buckets: [{key: red,doc_count: 4,avg_price: {value: 32500}},{key: blue,doc_count: 2,avg_price: {value: 20000}},{key: green,doc_count: 2,avg_price: {value: 21000}}]}} }响应中的新字段 avg_price 。 尽管响应只发生很小改变实际上我们获得的数据是增长了。之前我们知道有四辆红色的车现在红色车的平均价格是 $32500 美元。这个信息可以直接显示在报表或者图形中。 嵌套桶 在我们使用不同的嵌套方案时聚合的力量才能真正得以显现。 在前例中我们已经看到如何将一个度量嵌入桶中它的功能已经十分强大了。 但真正令人激动的分析来自于将桶嵌套进 另外一个桶 所能得到的结果。 现在我们想知道每个颜色的汽车制造商的分布 GET /cars/_search {size: 0,aggs: {colors: {terms: {field: color.keyword},aggs: {avg_price: {avg: {field: price}},make: {terms: {field: make.keyword}}}}} }注意前例中的 avg_price 度量仍然保持原位。另一个聚合 make 被加入到了 color 颜色桶中。这个聚合是 terms 桶它会为每个汽车制造商生成唯一的桶。 这里发生了一些有趣的事。 首先我们可能会观察到之前例子中的 avg_price 度量完全没有变化还在原来的位置。 一个聚合的每个 层级 都可以有多个度量或桶 avg_price 度量告诉我们每种颜色汽车的平均价格。它与其他的桶和度量相互独立。 这对我们的应用非常重要因为这里面有很多相互关联但又完全不同的度量需要收集。聚合使我们能够用一次数据请求获得所有的这些信息。 另外一件值得注意的重要事情是我们新增的这个 make 聚合它是一个 terms 桶嵌套在 colors 、 terms 桶内。这意味着它会为数据集中的每个唯一组合生成 color 、 make 元组。 让我们看看返回的响应为了简单我们只显示部分结果 aggregations: {colors: {doc_count_error_upper_bound: 0,sum_other_doc_count: 0,buckets: [{key: red,doc_count: 4,avg_price: {value: 32500},make: {doc_count_error_upper_bound: 0,sum_other_doc_count: 0,buckets: [{key: honda,doc_count: 3},{key: bmw,doc_count: 1}]}},正如期望的那样新的聚合嵌入在每个颜色桶中。现在我们看见按不同制造商分解的每种颜色下车辆信息。最终我们看到前例中的 avg_price 度量仍然维持不变。 响应结果告诉我们以下几点 红色车有四辆。红色车的平均售价是 $32500 美元。其中三辆是 Honda 本田制造一辆是 BMW 宝马制造。 最后的修改 让我们回到话题的原点在进入新话题之前对我们的示例做最后一个修改 为每个汽车生成商计算最低和最高的价格 GET /cars/_search {size : 0,aggs: {colors: {terms: {field: color.keyword},aggs: {avg_price: { avg: { field: price }},make : {terms : {field : make.keyword},aggs : { min_price : { min: { field: price} }, max_price : { max: { field: price} } }}}}} }我们需要增加另外一个嵌套的 aggs 层级。然后包括 min 最小度量。以及 max 最大度量。 得到以下输出只显示部分结果 aggregations: {colors: {doc_count_error_upper_bound: 0,sum_other_doc_count: 0,buckets: [{key: red,doc_count: 4,avg_price: {value: 32500},make: {doc_count_error_upper_bound: 0,sum_other_doc_count: 0,buckets: [{key: honda,doc_count: 3,max_price: {value: 20000},min_price: {value: 10000}},{key: bmw,doc_count: 1,max_price: {value: 80000},min_price: {value: 80000}}]}},min 和 max 度量现在出现在每个汽车制造商 make 下面。 有了这两个桶我们可以对查询的结果进行扩展并得到以下信息 有四辆红色车。红色车的平均售价是 $32500 美元。其中三辆红色车是 Honda 本田制造一辆是 BMW 宝马制造。最便宜的红色本田售价为 $10000 美元。最贵的红色本田售价为 $20000 美元。 条形图 聚合还有一个令人激动的特性就是能够十分容易地将它们转换成图表和图形。本章中 我们正在通过示例数据来完成各种各样的聚合分析最终我们将会发现聚合功能是非常强大的。 直方图 histogram 特别有用。 它本质上是一个条形图如果有创建报表或分析仪表盘的经验那么我们会毫无疑问的发现里面有一些图表是条形图。 创建直方图需要指定一个区间如果我们要为售价创建一个直方图可以将间隔设为 20,000。这样做将会在每个 $20,000 档创建一个新桶然后文档会被分到对应的桶中。 对于仪表盘来说我们希望知道每个售价区间内汽车的销量。我们还会想知道每个售价区间内汽车所带来的收入可以通过对每个区间内已售汽车的售价求和得到。 可以用 histogram 和一个嵌套的 sum 度量得到我们想要的答案 GET /cars/_search {size: 0,aggs: {price: {histogram: {field: price,interval: 20000},aggs: {revenue: {sum: {field: price}}}}} }histogram 桶要求两个参数一个数值字段以及一个定义桶大小间隔。sum 度量嵌套在每个售价区间内用来显示每个区间内的总收入。 如我们所见查询是围绕 price 聚合构建的它包含一个 histogram 桶。它要求字段的类型必须是数值型的同时需要设定分组的间隔范围。 间隔设置为 20,000 意味着我们将会得到如 [0-19999, 20000-39999, …] 这样的区间。 接着我们在直方图内定义嵌套的度量这个 sum 度量它会对落入某一具体售价区间的文档中 price 字段的值进行求和。 这可以为我们提供每个售价区间的收入从而可以发现到底是普通家用车赚钱还是奢侈车赚钱。 响应结果如下 aggregations: {price: {buckets: [{key: 0,doc_count: 3,revenue: {value: 37000}},{key: 20000,doc_count: 4,revenue: {value: 95000}},结果很容易理解不过应该注意到直方图的键值是区间的下限。键 0 代表区间 0-19999 键 20000 代表区间 20000-39999 等等。 当然我们可以为任何聚合输出的分类和统计结果创建条形图而不只是 直方图 桶。让我们以最受欢迎 10 种汽车以及它们的平均售价、标准差这些信息创建一个条形图。 我们会用到 terms 桶和 extended_stats 度量 GET /cars/_search {size: 0,aggs: {makes: {terms: {field: make.keyword,size: 10},aggs: {stats: {extended_stats: {field: price}}}}} }aggregations: {makes: {doc_count_error_upper_bound: 0,sum_other_doc_count: 0,buckets: [{key: honda,doc_count: 3,stats: {count: 3,min: 10000,max: 20000,avg: 16666.666666666668,sum: 50000,sum_of_squares: 900000000,variance: 22222222.22222221,variance_population: 22222222.22222221,variance_sampling: 33333333.333333313,std_deviation: 4714.045207910315,std_deviation_population: 4714.045207910315,std_deviation_sampling: 5773.502691896256,std_deviation_bounds: {upper: 26094.757082487296,lower: 7238.5762508460375,upper_population: 26094.757082487296,lower_population: 7238.5762508460375,upper_sampling: 28213.67205045918,lower_sampling: 5119.661282874156}}},上述代码会按受欢迎度返回制造商列表以及它们各自的统计信息。我们对其中的 stats.avg 、 stats.count 和 stats.std_deviation 信息特别感兴趣并用 它们计算出标准差 std_err std_deviation / count创建图表如图 Figure 36, “Average price of all makes, with error bars” 。 按时间统计 如果搜索是在 Elasticsearch 中使用频率最高的那么构建按时间统计的 date_histogram 紧随其后。 为什么你会想用 date_histogram 呢 假设你的数据带时间戳。 无论是什么数据Apache 事件日志、股票买卖交易时间、棒球运动时间只要带有时间戳都可以进行 date_histogram 分析。当你的数据有时间戳你总是想在 时间 维度上构建指标分析 今年每月销售多少台汽车这只股票最近 12 小时的价格是多少我们网站上周每小时的平均响应延迟时间是多少 虽然通常的 histogram 都是条形图但 date_histogram 倾向于转换成线状图以展示时间序列。 许多公司用 Elasticsearch 仅仅 只是为了分析时间序列数据。 date_histogram 分析是它们最基本的需要。 date_histogram 与 通常的 histogram 类似。 但不是在代表数值范围的数值字段上构建 buckets而是在时间范围上构建 buckets。 因此每一个 bucket 都被定义成一个特定的日期大小 (比如 1个月 或 2.5 天 )。 可以用通常的 histogram 进行时间分析吗 从技术上来讲是可以的。 通常的 histogram bucket桶是可以处理日期的。 但是它不能自动识别日期。 而用 date_histogram 你可以指定时间段如 1 个月 它能聪明地知道 2 月的天数比 12 月少。 date_histogram 还具有另外一个优势即能合理地处理时区这可以使你用客户端的时区进行图标定制而不是用服务器端时区。 通常的 histogram 会把日期看做是数字这意味着你必须以微秒为单位指明时间间隔。另外聚合并不知道日历时间间隔使得它对于日期而言几乎没什么用处。 我们的第一个例子将构建一个简单的折线图来回答如下问题 每月销售多少台汽车 GET /cars/_search {size: 0,aggs: {sales: {date_histogram: {field: sold,calendar_interval: month,format: yyyy-MM-dd}}} }时间间隔要求是日历术语 (如每个 bucket 1 个月)。我们提供日期格式以便 buckets 的键值便于阅读。 我们的查询只有一个聚合每月构建一个 bucket。这样我们可以得到每个月销售的汽车数量。 另外还提供了一个额外的 format 参数以便 buckets 有 “好看的” 键值。 然而在内部日期仍然是被简单表示成数值。这可能会使得 UI 设计者抱怨因此可以提供常用的日期格式进行格式化以更方便阅读。 结果既符合预期又有一点出人意料看看你是否能找到意外之处 aggregations: {sales: {buckets: [{key_as_string: 2014-01-01,key: 1388534400000,doc_count: 1},{key_as_string: 2014-02-01,key: 1391212800000,doc_count: 1},{key_as_string: 2014-03-01,key: 1393632000000,doc_count: 0},{key_as_string: 2014-04-01,key: 1396310400000,doc_count: 0},{key_as_string: 2014-05-01,key: 1398902400000,doc_count: 1},{key_as_string: 2014-06-01,key: 1401580800000,doc_count: 0},{key_as_string: 2014-07-01,key: 1404172800000,doc_count: 1},{key_as_string: 2014-08-01,key: 1406851200000,doc_count: 1},{key_as_string: 2014-09-01,key: 1409529600000,doc_count: 0},{key_as_string: 2014-10-01,key: 1412121600000,doc_count: 1},{key_as_string: 2014-11-01,key: 1414800000000,doc_count: 2}]}}聚合结果已经完全展示了。正如你所见我们有代表月份的 buckets每个月的文档数目以及美化后的 key_as_string 。 返回空 Buckets 注意到结果末尾处的奇怪之处了吗 是的结果没错。 我们的结果少了一些月份 date_histogram 和 histogram 一样默认只会返回文档数目非零的 buckets。 这意味着你的 histogram 总是返回最少结果。通常你并不想要这样。对于很多应用你可能想直接把结果导入到图形库中而不想做任何后期加工。 事实上即使 buckets 中没有文档我们也想返回。可以通过设置两个额外参数来实现这种效果 GET /cars/_search {size: 0,aggs: {sales: {date_histogram: {field: sold,calendar_interval: month,format: yyyy-MM-dd,min_doc_count: 1,extended_bounds: {min: 2014-01-01,max: 2014-12-31}}}} }min_doc_count 这个参数如果为0强制返回空 buckets。如果为1doc_count小于1的桶就被过滤掉了。extended_bounds 这个参数强制返回整年。 aggregations: {sales: {buckets: [{key_as_string: 2014-01-01,key: 1388534400000,doc_count: 1},{key_as_string: 2014-02-01,key: 1391212800000,doc_count: 1},{key_as_string: 2014-05-01,key: 1398902400000,doc_count: 1},{key_as_string: 2014-07-01,key: 1404172800000,doc_count: 1},{key_as_string: 2014-08-01,key: 1406851200000,doc_count: 1},{key_as_string: 2014-10-01,key: 1412121600000,doc_count: 1},{key_as_string: 2014-11-01,key: 1414800000000,doc_count: 2}]}}“min_doc_count”: 0, “extended_bounds”: { “min”: “2014-01-01”, “max”: “2014-12-31” } 这两个参数会强制返回一年中所有月份的结果而不考虑结果中的文档数目。 min_doc_count 非常容易理解它强制返回所有 buckets即使 buckets 可能为空。 extended_bounds 参数需要一点解释。 min_doc_count 参数强制返回空 buckets但是 Elasticsearch 默认只返回你的数据中最小值和最大值之间的 buckets。 因此如果你的数据只落在了 4 月和 7 月之间那么你只能得到这些月份的 buckets可能为空也可能不为空。因此为了得到全年数据我们需要告诉 Elasticsearch 我们想要全部 buckets 即便那些 buckets 可能落在最小日期 之前 或 最大日期 之后 。没有数据的那些月份也会新增一个doc_count0的桶。 extended_bounds 参数正是如此。一旦你加上了这两个设置你可以把得到的结果轻易地直接插入到你的图形库中从而得到类似 Figure 37, “汽车销售时间图” 的图表。 扩展例子 正如我们已经见过很多次buckets 可以嵌套进 buckets 中从而得到更复杂的分析。 作为例子我们构建聚合以便按季度展示所有汽车品牌总销售额。同时按季度、按每个汽车品牌计算销售总额以便可以找出哪种品牌最赚钱 GET /cars/_search {size : 0,aggs: {sales: {date_histogram: {field: sold,calendar_interval: quarter, format: yyyy-MM-dd,min_doc_count : 0,extended_bounds : {min : 2014-01-01,max : 2014-12-31}},aggs: {per_make_sum: {terms: {field: make.keyword},aggs: {sum_price: {sum: { field: price } }}},total_sum: {sum: { field: price } }}}} }注意我们把时间间隔从 month 改成了 quarter 。计算每种品牌的总销售金额。也计算所有全部品牌的汇总销售金额。 得到的结果截去了一大部分如下 aggregations: {sales: {buckets: [{key_as_string: 2014-01-01,key: 1388534400000,doc_count: 2,per_make_sum: {doc_count_error_upper_bound: 0,sum_other_doc_count: 0,buckets: [{key: bmw,doc_count: 1,sum_price: {value: 80000}},{key: ford,doc_count: 1,sum_price: {value: 25000}}]},total_sum: {value: 105000}},我们把结果绘成图得到如 Figure 38, “按品牌分布的每季度销售额” 所示的总销售额的折线图和每个品牌每季度的柱状图。 潜力无穷 这些很明显都是简单例子但图表聚合其实是潜力无穷的。 如 Figure 39, “Kibana—​用聚合构建的实时分析面板” 展示了 Kibana 中用各种聚合构建的面板。 因为聚合的实时性类似这样的面板很容易查询、操作和交互。这使得它们成为需要分析数据又不会构建 Hadoop 作业的非技术人员的理想工具。 当然为了构建类似 Kibana 这样的强大面板你可能需要更深的知识比如基于范围、过滤以及排序的聚合。 范围限定的聚合 所有聚合的例子到目前为止你可能已经注意到我们的搜索请求省略了一个 query 。 整个请求只不过是一个聚合。 聚合可以与搜索请求同时执行但是我们需要理解一个新概念 范围 。 默认情况下聚合与查询是对同一范围进行操作的也就是说聚合是基于我们查询匹配的文档集合进行计算的。 让我们看看第一个聚合的示例 GET /cars/_search {size : 0,aggs : {colors : {terms : {field : color.keyword}}} }我们可以看到聚合是隔离的。现实中Elasticsearch 认为 “没有指定查询” 和 “查询所有文档” 是等价的。前面这个查询内部会转化成下面的这个请求 GET /cars/_search {size: 0,query: {match_all: {}},aggs: {colors: {terms: {field: color.keyword}}} }因为聚合总是对查询范围内的结果进行操作的所以一个隔离的聚合实际上是在对 match_all 的结果范围操作即所有的文档。 一旦有了范围的概念我们就能更进一步对聚合进行自定义。我们前面所有的示例都是对 所有 数据计算统计信息的销量最高的汽车所有汽车的平均售价最佳销售月份等等。 利用范围我们可以问“福特在售车有多少种颜色”诸如此类的问题。可以简单的在请求中加上一个查询本例中为 match 查询 GET /cars/_search {query: {match: {make: ford}},aggs: {colors: {terms: {field: color.keyword}}} }因为我们没有指定 “size” : 0 所以搜索结果和聚合结果都被返回了 {took: 0,timed_out: false,_shards: {total: 1,successful: 1,skipped: 0,failed: 0},hits: {total: {value: 2,relation: eq},max_score: 1.2809337,hits: [{_index: cars,_id: WVEUw44BZKfEnzIxjV7V,_score: 1.2809337,_source: {price: 30000,color: green,make: ford,sold: 2014-05-18}},{_index: cars,_id: XlEUw44BZKfEnzIxjV7V,_score: 1.2809337,_source: {price: 25000,color: blue,make: ford,sold: 2014-02-12}}]},aggregations: {colors: {doc_count_error_upper_bound: 0,sum_other_doc_count: 0,buckets: [{key: blue,doc_count: 1},{key: green,doc_count: 1}]}} }全局桶 通常我们希望聚合是在查询范围内的但有时我们也想要搜索它的子集而聚合的对象却是 所有 数据。 例如比方说我们想知道福特汽车与 所有 汽车平均售价的比较。我们可以用普通的聚合查询范围内的得到第一个信息然后用 全局 桶获得第二个信息。 全局 桶包含 所有 的文档它无视查询的范围。因为它还是一个桶我们可以像平常一样将聚合嵌套在内 GET /cars/_search {size: 0,query: {match: {make: ford}},aggs: {single_avg_price: {avg: {field: price}},all: {global: {},aggs: {avg_price: {avg: {field: price}}}}} }aggs 1 聚合操作在查询范围内例如所有文档匹配 ford “global”: {} 全局桶没有参数。aggs 2 聚合操作针对所有文档忽略汽车品牌。 {took: 2,timed_out: false,_shards: {total: 1,successful: 1,skipped: 0,failed: 0},hits: {total: {value: 2,relation: eq},max_score: null,hits: []},aggregations: {all: {doc_count: 8,avg_price: {value: 26500}},single_avg_price: {value: 27500}} }single_avg_price 度量计算是基于查询范围内所有文档即所有 福特 汽车。avg_price 度量是嵌套在 全局 桶下的这意味着它完全忽略了范围并对所有文档进行计算。聚合返回的平均值是所有汽车的平均售价。 如果能一直坚持读到这里应该知道我们有个真言尽可能的使用过滤器。它同样可以应用于聚合在下一章中我们会展示如何对聚合结果进行过滤而不是仅对查询范围做限定。 过滤和聚合 聚合范围限定还有一个自然的扩展就是过滤。因为聚合是在查询结果范围内操作的任何可以适用于查询的过滤器也可以应用在聚合上。 过滤 如果我们想找到售价在 $10,000 美元之上的所有汽车同时也为这些车计算平均售价 可以简单地使用一个 constant_score 查询和 filter 约束 GET cars/_search {size: 0,query: {constant_score: {filter: {range: {price: {gte: 10000}}}}},aggs: {single_avg_price: {avg: {field: price}}} }{took: 0,timed_out: false,_shards: {total: 1,successful: 1,skipped: 0,failed: 0},hits: {total: {value: 8,relation: eq},max_score: null,hits: []},aggregations: {single_avg_price: {value: 26500}} }这正如我们在前面章节中讨论过那样从根本上讲使用 non-scoring 查询和使用 match 查询没有任何区别。查询包括了一个过滤器返回一组文档的子集聚合正是操作这些文档。使用 filtering query 会忽略评分并有可能会缓存结果数据等等。 过滤桶 但是如果我们只想对聚合结果过滤怎么办 假设我们正在为汽车经销商创建一个搜索页面 我们希望显示用户搜索的结果但是我们同时也想在页面上提供更丰富的信息包括与搜索匹配的上个月度汽车的平均售价。 这里我们无法简单的做范围限定因为有两个不同的条件。搜索结果必须是 ford 但是聚合结果必须满足 ford AND sold now - 1M 。 为了解决这个问题我们可以用一种特殊的桶叫做 filter 注过滤桶 。 我们可以指定一个过滤桶当文档满足过滤桶的条件时我们将其加入到桶内。 查询结果如下 GET /cars/_search {size : 0,query:{match: {make: ford}},aggs:{recent_sales: {filter: { range: {sold: {from: now-1M}}},aggs: {average_price:{avg: {field: price }}}}} }使用 过滤 桶在 查询 范围基础上应用过滤器。avg 度量只会对 ford 和上个月售出的文档计算平均售价。 aggregations: {recent_sales: {doc_count: 1,average_price: {value: 30000}}}因为 filter 桶和其他桶的操作方式一样所以可以随意将其他桶和度量嵌入其中。所有嵌套的组件都会 “继承” 这个过滤这使我们可以按需针对聚合过滤出选择部分。 后过滤器 目前为止我们可以同时对搜索结果和聚合结果进行过滤不计算得分的 filter 查询以及针对聚合结果的一部分进行过滤 filter 桶。 我们可能会想“只过滤搜索结果不过滤聚合结果呢” 答案是使用 post_filter 。 它是接收一个过滤器的顶层搜索请求元素。这个过滤器在查询 之后 执行这正是该过滤器的名字的由来它在查询之后 post 执行。正因为它在查询之后执行它对查询范围没有任何影响所以对聚合也不会有任何影响。 我们可以利用这个行为对查询条件应用更多的过滤器而不会影响其他的操作就如 UI 上的各个分类面。让我们为汽车经销商设计另外一个搜索页面这个页面允许用户搜索汽车同时可以根据颜色来过滤。颜色的选项是通过聚合获得的 GET /cars/_search {query: {match: {make: ford}},aggs: {all_colors: {terms: {field: color.keyword}}},post_filter: {term: {color.keyword: green}} }post_filter 元素是 top-level 而且仅对命中结果进行过滤。 {took: 2,timed_out: false,_shards: {total: 1,successful: 1,skipped: 0,failed: 0},hits: {total: {value: 2,relation: eq},max_score: 1.3291358,hits: [{_index: cars,_id: WVEUw44BZKfEnzIxjV7V,_score: 1.3291358,_source: {price: 30000,color: green,make: ford,sold: 2014-05-18}},{_index: cars,_id: 21GFw44BZKfEnzIxPWJm,_score: 1.3291358,_source: {price: 30000,color: green,make: ford,sold: 2024-05-18}}]},aggregations: {all_colors: {doc_count_error_upper_bound: 0,sum_other_doc_count: 0,buckets: [{key: blue,doc_count: 2},{key: green,doc_count: 2}]}} }只对 hits 搜索结果有影响而对 aggs 聚合结果没有任何影响。 查询 部分找到所有的 ford 汽车然后用 terms 聚合创建一个颜色列表。因为聚合对查询范围进行操作颜色列表与福特汽车有的颜色相对应。 最后 post_filter 会过滤搜索结果只展示绿色 ford 汽车。这在查询执行过 后 发生所以聚合不受影响。 这通常对 UI 的连贯一致性很重要可以想象用户在界面商选择了一类颜色比如绿色期望的是搜索结果已经被过滤了而 不是 过滤界面上的选项。如果我们应用 filter 查询界面会马上变成 只 显示 绿色 作为选项这不是用户想要的 性能考虑Performance consideration 当你需要对搜索结果和聚合结果做不同的过滤时你才应该使用 post_filter 有时用户会在普通搜索使用 post_filter 。 不要这么做 post_filter 的特性是在查询 之后 执行任何过滤对性能带来的好处比如缓存都会完全失去。 在我们需要不同过滤时 post_filter 只与聚合一起使用。 小结 选择合适类型的过滤如搜索命中、聚合或两者兼有通常和我们期望如何表现用户交互有关。选择合适的过滤器或组合取决于我们期望如何将结果呈现给用户。 在 filter 过滤中的 non-scoring 查询同时影响搜索结果和聚合结果。filter 桶影响聚合。post_filter 只影响搜索结果。 多桶排序 多值桶 terms 、 histogram 和 date_histogram 动态生成很多桶。 Elasticsearch 是如何决定这些桶展示给用户的顺序呢 内置排序 默认的桶会根据 doc_count 降序排列。这是一个好的默认行为因为通常我们想要找到文档中与查询条件相关的最大值售价、人口数量、频率。但有些时候我们希望能修改这个顺序不同的桶有着不同的处理方式。 GET /cars/_search {size : 0,aggs : {colors : {terms : {field : color.keyword,order: {_count : asc }}}} }用关键字 _count 我们可以按 doc_count 值的升序排序。 我们为聚合引入了一个 order 对象 它允许我们可以根据以下几个值中的一个值进行排序 aggregations: {colors: {doc_count_error_upper_bound: 0,sum_other_doc_count: 0,buckets: [{key: blue,doc_count: 4},{key: green,doc_count: 4},{key: red,doc_count: 8}]}}_count 按文档数排序。对 terms 、 histogram 、 date_histogram 有效。 _term 按词项的字符串值的字母顺序排序。只在 terms 内使用。 _key 按每个桶的键值数值排序理论上与 _term 类似。 只在 histogram 和 date_histogram 内使用。 按度量排序 有时我们会想基于度量计算的结果值进行排序。 在我们的汽车销售分析仪表盘中我们可能想按照汽车颜色创建一个销售条状图表但按照汽车平均售价的升序进行排序。 我们可以增加一个度量再指定 order 参数引用这个度量即可 GET /cars/_search {size: 0,aggs: {colors: {terms: {field: color.keyword,order: {avg_price: asc}},aggs: {avg_price: {avg: {field: price}}}}} }计算每个桶的平均售价。桶按照计算平均值的升序排序。 aggregations: {colors: {doc_count_error_upper_bound: 0,sum_other_doc_count: 0,buckets: [{key: blue,doc_count: 4,avg_price: {value: 20000}},{key: green,doc_count: 4,avg_price: {value: 21000}},{key: red,doc_count: 8,avg_price: {value: 32500}}]}}我们可以采用这种方式用任何度量排序只需简单的引用度量的名字。不过有些度量会输出多个值。 extended_stats 度量是一个很好的例子它输出好几个度量值。 如果我们想使用多值度量进行排序 我们只需以关心的度量为关键词使用点式路径 GET /cars/_search {size : 0,aggs : {colors : {terms : {field : color.keyword,order: {stats.variance : asc }},aggs: {stats: {extended_stats: {field: price}}}}} }使用 . 符号根据感兴趣的度量进行排序。 在上面这个例子中我们按每个桶的方差来排序所以这种颜色售价方差最小的会排在结果集最前面。 基于“深度”度量排序 在前面的示例中度量是桶的直接子节点。平均售价是根据每个 term 来计算的。 在一定条件下我们也有可能对 更深 的度量进行排序比如孙子桶或从孙桶。 我们可以定义更深的路径将度量用尖括号 嵌套起来像这样 my_bucketanother_bucketmetric 。 需要提醒的是嵌套路径上的每个桶都必须是 单值 的。 filter 桶生成 一个单值桶所有与过滤条件匹配的文档都在桶中。 多值桶如terms 动态生成许多桶无法通过指定一个确定路径来识别。 目前只有三个单值桶 filter 、 global 和 reverse_nested 。让我们快速用示例说明创建一个汽车售价的直方图但是按照红色和绿色不包括蓝色车各自的方差来排序 GET /cars/_search {size : 0,aggs : {colors : {histogram : {field : price,interval: 20000,order: {red_green_carsstats.variance : asc }},aggs: {red_green_cars: {filter: { terms: {color: [red, green]}}, aggs: {stats: {extended_stats: {field : price}} }}}}} }按照嵌套度量的方差对桶的直方图进行排序。因为我们使用单值过滤器 filter 我们可以使用嵌套排序。按照生成的度量对统计结果进行排序。 本例中可以看到我们如何访问一个嵌套的度量。 stats 度量是 red_green_cars 聚合的子节点而 red_green_cars 又是 colors 聚合的子节点。 为了根据这个度量排序我们定义了路径 red_green_carsstats.variance 。我们可以这么做因为 filter 桶是个单值桶。
http://www.pierceye.com/news/480447/

相关文章:

  • vue做直播网站上海最繁华的五个区
  • 做网站和微信小程序电子商务网站建设与管理的背景
  • 做网站国内阿里云虚拟主机多少钱东莞常平中学高中部
  • 用.net做购物网站灵山建设局网站
  • 烟台网站设计制作公司电话python购物网站开发流程
  • 医疗网站怎么做seo怎样通过网址浏览自己做的网站
  • 湖北现代城市建设集团网站wordpress用户头像插件
  • 徐州双语网站制作响应式网站开发pdf
  • 怎么做建设网站公司创建一个网站多少钱
  • 好看的扁平化网站wordpress插件编写
  • 深圳网站设计模板ps可以做网站动态图
  • 微信网站制作入门网站开发实施方案进度
  • 网站用户界面设计国内网站建设最好公司
  • 运城做网站费用高吗高端模板建站
  • 凡客诚品网站设计合肥网红打卡地
  • 淘宝网站代理怎么做的广西送变电建设公司铁塔厂网站
  • 自媒体网站开发网站的推广方式包括
  • 教育做的比较好的网站有哪些网站的建设及维护
  • dw设计做网站案例建设网站杭州
  • 做网站认证对网站有什么好处广西网站建设开发团队
  • 建一个网站需要哪些知识无锡大型互联网公司
  • 餐饮公司 网站建设做网站一年大概的盈利
  • 做金融怎么进基金公司网站免费行情软件网站游戏
  • 网站推广解释创立一个网站要多少钱
  • 绍兴专业网站建设公司大型网站建设哪家好
  • 天河网站设计响应式视频网站模板
  • 网站制作老了手机网站模板开发
  • 哪家网站建设比较好海拉尔建网站
  • 丹东网站推广海南行指专业网站开发
  • 网站如何调用手机淘宝做淘宝客中国企业网站查询