Elastic search中使用nested类型的内嵌对象
在大数据的应用环境中,往往使用反范式设计来提高读写性能。
假设我们有个类似简书的系统,系统里有文章,用户也可以对文章进行赞赏。在关系型数据库中,如果按照数据库范式设计,需要两张表:一张文章表和一张赞赏历史记录表,赞赏历史记录表包括了赞赏者姓名和赞赏金额。
在Elastic search中,由于都是json格式存储,则可以在一个index存储系统中的文章及其赞赏记录,这种情况下需要在elastic search中使用nested类型的内嵌对象。因为如果使用数组或者object对象的话,赞赏者姓名和赞赏金额是相互独立的进行存储,不能被正确的关联。
建立index
PUT articles
{
"mappings": {
"doc": {
"properties": {
"payment": {
"type": "nested",
"properties": {
"amount": {
"type": "integer"
},
"name": {
"type": "keyword"
}
}
}
}
}
}
}
这样articles就有了payment这个nested类型的字段,payment里面的对象有amount和name,表示金额和姓名。
产生数据
产生如下数据,表示jack给文章1赞赏了29元,ross给文章1赞赏30元,ross给文章2赞赏31元。
POST articles/doc/1
{
"payment": [
{
"name": "jack",
"amount": 29
},
{
"name": "ross",
"amount": 30
}
]
}
POST articles/doc/2
{
"payment": [
{
"name": "ross",
"amount": 31
}
]
}
根据内嵌对象进行查询
现在想查询ross赞赏过的文章,需要使用nested query
GET articles/_search
{
"query": {
"nested": {
"path": "payment",
"query": {
"term": {
"payment.name": {
"value": "ross"
}
}
}
}
}
}
path表示了nested字段的名称,需要注意的是,查询语句中要指定查询字段的全名,所以赞赏者姓名要用"payment.name"
如果在多个index上进行nested查询,没有nested字段的index会报错,这时可以将ignore_unmapped设置为true
nested对象聚合
如果想查看赞赏的平均金额,需要用nested aggregation
GET articles/_search
{
"size": 0,
"aggs": {
"nested": {
"nested": {
"path": "payment"
},
"aggs": {
"amount_avg": {
"avg": {
"field": "payment.amount"
}
}
}
}
}
}
同样注意要用path指定字段名称。返回的数据中,比普通的聚合查询多了一层嵌套
返回结果为
{
"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
}
}
}
}
nested对象聚合和过滤
如果想看ross赞赏过的总金额,一开始写出query如下
GET articles/_search
{
"size": 0,
"query": {
"nested": {
"path": "payment",
"query": {
"term": {
"payment.name": {
"value": "ross"
}
}
}
}
},
"aggs": {
"nested": {
"nested": {
"path": "payment"
},
"aggs": {
"sum": {
"sum": {
"field": "payment.amount"
}
}
}
}
}
}
此时结果并不是正确的,因为上面的query过滤的是ross赞赏过的文章,下面的聚合操作sum的是文章里所有的赞赏,包括了jack的赞赏。
所以需要在sum聚合操作之前,需要用Filter Aggregation筛选ross的赞赏。
GET articles/_search
{
"size": 0,
"query": {
"nested": {
"path": "payment",
"query": {
"term": {
"payment.name": {
"value": "ross"
}
}
}
}
},
"aggs": {
"payment": {
"nested": {
"path": "payment"
},
"aggs": {
"payer": {
"filter": {
"term": {
"payment.name": {
"value": "ross"
}
}
},
"aggs": {
"sum": {
"sum": {
"field": "payment.amount"
}
}
}
}
}
}
}
}
最外层的query筛选出ross赞赏过的文章。
第一层的aggs表示进行内嵌聚合。
第二层的aggs用Filter Aggregation筛选出表示ross赞赏行为的nested对象。
第三层的aggs进行聚合。
作者:大神带我来搬砖
链接:https://www.jianshu.com/p/d685b7b6c9d1
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
Elastic search中使用nested类型的内嵌对象的更多相关文章
- freemarker 中可以直接使用的内置对象
freemarker 中可以直接使用的内置对象 需要配置一下:springboot中配置 ## Freemarker \u914D\u7F6E ## \u6587\u4EF6\u914D\u7F6E\ ...
- 关于js函数解释(包括内嵌,对象等)
常用写法: function add(a,b) { return a + b; } alert(add(1,2)); // 结果 3 当我们这么定义函数的时候,函数内容会被编译(但不会立即执行,除非我 ...
- elastic search 日期为string类型导致视图无法展示时间的解决办法
尝试将结构化的json数据发送到es(elastic search)上,然后创建视图,这样就能以小时维度查看数据,直接使用post发送到es后,创建索引,结果提示 没有date类型的字段(field) ...
- Elastic Search中Document的CRUD操作
一. 新增Document在索引中增加文档.在index中增加document.ES有自动识别机制.如果增加的document对应的index不存在.自动创建,如果index存在,type不存在自动创 ...
- Elastic Search中filter的理解
在ES中,请求一旦发起,ES服务器是按照请求参数的顺序依次执行具体的搜索过滤逻辑的.如何定制请求体中的搜索过滤条件顺序,是一个经验活.类似query(指search中的query请求参数),也是搜索的 ...
- Elastic Search中mapping的问题
Mapping在ES中是非常重要的一个概念.决定了一个index中的field使用什么数据格式存储,使用什么分词器解析,是否有子字段,是否需要copy to其他字段等.Mapping决定了index中 ...
- JSP中的Java代码和内置对象
一.JSP中的Java代码 (一)JSP页面中有三种方式嵌入java代码: 1.java的表达式 格式:<%= java表达式 %> 2.java的语句 格式:<% java语句&g ...
- Word中高效输入公式:内嵌公式和Mathtype
Word中高效输入公式:内嵌公式和Mathtype 前言:对于理工科学生而言,公式输入必不可缺.LaTeX相比Word,在公式输入及排版方面更强大.但是对于轻量级的任务,用Word而言更加轻便(起码不 ...
- js之数据类型(对象类型——单体内置对象——Math)
Math是一个内置对象,它具有数学常数和函数的属性和方法.Math对象用于执行数学任务,和其它对象不同,Math只是一个静态对象并没有Math()构造函数,实际上,Math()只是一个由js设置的对象 ...
随机推荐
- 创建CUDA项目
输出选择X64 .cu文件属性: 常规-项类型:CUDA C/C++ 项目属性: 平台:活动(x64) CUDA C/C++ - Common-Target Machine Platform: 64- ...
- oozie 启动过程中--- Existing PID file found during start. Removing/clearing stale PID file.
如果oozie使用kill -9 暴力杀死了tomcat,再启动的时候,会出问题,需要删除tomcat的pid文件 彻底停止oozie的tomcat的进程,然后删除pid文件 rm -rf /exp ...
- vue 设置当前页背景色
beforeRouteEnter(to, from, next) { // 添加背景色 document.querySelector('body').setAttribute('style', 'ba ...
- 动软生成器 Liger model生成模板
<#@ template language="c#" HostSpecific="True" #> <#@ output extension= ...
- libkmcuda安装
编译安装 1,前期准备 git clone https://github.com/src-d/kmcuda cd kmcuda/src/ 例如: cmake -DCMAKE_BUILD_TYPE=Re ...
- 并行计算基础(1)(GPU架构介绍)
一.常用术语 Task:任务.可以完整得到结果的一个程序,一个程序段或若干个程序段.例如搬砖. Parallel Task:并行任务.可以并行计算的任务.多个人搬砖. Serial Execution ...
- HDU 6191 Query on A Tree ( 2017广西邀请赛 && 可持久化Trie )
题目链接 题意 : 给你一棵树.树上的每个点都有点权.之后有若干次问询.每次问询给出一个节点编号以及一个整数 X .问你以给出节点为根的子树中哪个节点和 X 异或最大.输出这个值 分析 : 看到这种树 ...
- [NOIP2014普及组T1]珠心算测验 - NTT
求数组有多少个数,恰好等于集合中另外两个(不同的)数之和? 注意到数集比较小,而且涉及到下标的加法,可以很自然地想到卷积 注意减去自己加自己的贡献 真是一道NTT练手好题 #include <i ...
- JavaWeb_(SSH论坛)_三、用户模块
基于SSH框架的小型论坛项目 一.项目入门 传送门 二.框架整合 传送门 三.用户模块 传送门 四.页面显示 传送门 五.帖子模块 传送门 六.点赞模块 传送门 七.辅助模块 传送门 User表 id ...
- hive 分组排序函数 row_number() over(partition by " " order by " "desc
语法:row_number() over (partition by 字段a order by 计算项b desc ) rank --这里rank是别名 partition by:类似hive的建表, ...