普通内部对象

"kibana_sample_data_ecommerce" : {    "mappings" : {      "properties" : {        "category" : {          "type" : "text",          "fields" : {            "keyword" : {              "type" : "keyword"            }          }        },        "currency" : {          "type" : "keyword"        },        "customer_full_name" : {          "type" : "text",          "fields" : {            "keyword" : {              "type" : "keyword",              "ignore_above" : 256            }          }        },        //省略部分        "products" : {!!!!!!!!!!!!!!!!!          "properties" : {            "_id" : {              "type" : "text",              "fields" : {                "keyword" : {                  "type" : "keyword",                  "ignore_above" : 256                }              }            },            "base_price" : {              "type" : "half_float"            },            "base_unit_price" : {              "type" : "half_float"            },

不是期望值

GET kibana_sample_data_ecommerce/_search{  "query": {    "bool": {      "must": [        { "match": { "products.base_price": 24.99 }},        { "match": { "products.sku":"ZO0549605496"}},        {"match": { "order_id": "584677"}}      ]    }  }}

我这里搜索有三个条件,order_id,商品的价格和sku,事实上同时满足这三个条件的文档并不存在(sku=ZO0549605496的商品价格是11.99)。但是结果却返回了一个文档,这是为什么呢?

因为在ES中对于json对象数组的处理是压扁了处理的,比如上面的例子在ES存储的结构是这样的:

{  "order_id":            [ 584677 ],  "products.base_price":    [ 11.99, 24.99... ],  "products.sku": [ ZO0549605496, ZO0299602996 ],  ...}

很明显,这样的结构丢失了商品金额和sku的关联关系。

如果你的业务场景对这个问题不敏感,就可以选择这种方式,因为它足够简单并且效率也比下面两种方案高。

嵌套文档

// mappingPUT test_index{  "mappings": {    "properties": {      "user": {        "type": "nested",          "properties": {            "name":    { "type": "string"  },            "age":     { "type": "short"   }          }      }    }  }}// index dataPUT test_index/_doc/1{  "group" : "root",  "user" : [    {      "name" : "John",      "age" :  30    },    {      "name" : "Alice",      "age" :  28    }  ]}PUT test_index/_doc/2{  "group" : "wheel",  "user" : [    {      "name" : "Tom",      "age" :  33    },    {      "name" : "Jack",      "age" :  25    }  ]}// searchGET test_index/_search{  "query": {    "nested": {      "path": "user",      "query": {        "bool": {          "must": [            { "match": { "user.name": "Tom" }},            { "match": { "user.age":  33 }}           ]        }      }    }  }}// result{  "took" : 1,  "timed_out" : false,  "_shards" : {    "total" : 1,    "successful" : 1,    "skipped" : 0,    "failed" : 0  },  "hits" : {    "total" : {      "value" : 1,      "relation" : "eq"    },    "max_score" : 2.2039728,    "hits" : [      {        "_index" : "test_index",        "_type" : "_doc",        "_id" : "2",        "_score" : 2.2039728,        "_source" : {          "group" : "wheel",          "user" : [            {              "name" : "Tom",              "age" : 33            },            {              "name" : "Jack",              "age" : 25            }          ]        }      }    ]  }}

缺点

GET _cat/indices?v

是不是很奇怪问啥文档的数量是6而不是2呢?这是因为nested子文档在ES内部其实也是独立的lucene文档,只是我们在查询的时候,ES内部帮我们做了join处理。最终看起来好像是一个独立的文档一样。

那可想而知同样的条件下,这个性能肯定不如普通内部对象的方案。在实际的业务应用中要根据实际情况决定是否选择这种方案。

嵌套文档聚合

在查询的时候,我们使用 nested 查询 就可以获取嵌套对象的信息。同理, nested 聚合允许我们对嵌套对象里的字段进行聚合操作。

GET /my_index/blogpost/_search{  "size" : 0,  "aggs": {    "comments": {       "nested": {        "path": "comments"      },      "aggs": {        "by_month": {          "date_histogram": {             "field":    "comments.date",            "interval": "month",            "format":   "yyyy-MM"          },          "aggs": {            "avg_stars": {              "avg": {                 "field": "comments.stars"              }            }          }        }      }    }  }}// result..."aggregations": {  "comments": {     "doc_count": 4,      "by_month": {        "buckets": [           {              "key_as_string": "2014-09",              "key": 1409529600000,              "doc_count": 1,               "avg_stars": {                 "value": 4              }           },           {              "key_as_string": "2014-10",              "key": 1412121600000,              "doc_count": 3,               "avg_stars": {                 "value": 2.6666666666666665              }           }        ]     }  }}...总共有4个 comments 对象 :1个对象在9月的桶里,3个对象在10月的桶里。

TODO

例如,我们要基于评论者的年龄找出评论者感兴趣 tags 的分布。 comment.age 是一个嵌套字段,但 tags 在根文档中:

reverse_nested

父子文档

假如我需要更新文档的group属性的值,需要重新索引这个文档。尽管嵌套的user对象我不需要更新,他也随着主文档一起被重新索引了。

使用场景:一个子文档可以属于多个主文档的场景,用nested无法实现。

// my_join_field是给我们的父子文档关系的名字,这个可以自定义。join关键字表示这是一个父子文档关系,接下来relations里面表示question是父,answer是子。PUT my_index{  "mappings": {    "properties": {      "my_id": {        "type": "keyword"      },      "my_join_field": {         "type": "join",        "relations": {          "question": "answer"         }      }    }  }}// 索引父文档,"name": "question"表示插入的是父文档。PUT my_index/_doc/1{  "my_id": "1",  "text": "This is a question",  "my_join_field": {    "name": "question"   }}PUT my_index/_doc/2{  "my_id": "2",  "text": "This is another question",  "my_join_field": {    "name": "question"  }}// 索引子文档,routing和parent要一致PUT my_index/_doc/3?routing=1{  "my_id": "3",  "text": "This is an answer",  "my_join_field": {    "name": "answer",     "parent": "1"   }}PUT my_index/_doc/4?routing=2{  "my_id": "4",  "text": "This is another1 answer",  "my_join_field": {    "name": "answer",    "parent": "2"  }}// searchGET my_index/_search{  "query": {    "match_all": {}  },  "sort": ["my_id"]}// 查询父文档 根据子文档条件POST my_index/_search{  "query": {    "has_child": {      "type": "answer",      "query": {        "match": {          "text": "answer"        }      }    }  }}// 查询子文档 根据父文档条件POST my_index/_search{  "query": {    "has_parent": {      "parent_type": "question",      "query": {        "match": {          "text": "question"        }      }    }  }}// 查询子文档 根据父id条件POST my_index/_search{  "query": {    "parent_id": {       "type": "answer",      "id": "1"    }

总的来说,

嵌套对象通过冗余数据来提高查询性能,适用于读多写少的场景

父子文档类似关系型数据库中的关联关系,适用于写多的场景,减少了文档修改的范围。

参考

https://segmentfault.com/a/1190000022161752

https://www.elastic.co/guide/en/elasticsearch/reference/7.9/query-dsl-parent-id-query.html

kibana创建es索引_es 索引数据创建mapping 普通内部对象 嵌套文档 父子文档创建和查询...相关推荐

  1. in 用不用索引_MySQL 索引最佳实践之问题反馈

    我之前发布的 PPT -- <MySQL 索引最佳实践>中,有很多人提了很多问题,我没有时间一一回答,于是我决定把这些问题集中在一起进行回答. 问:我们团队中的一人想要使用 bigint ...

  2. ElasticSearch(四):ES nested嵌套文档与父子文档处理

    对于复杂的嵌套字段处理使用nested来避免数据扁平化处理,使用数据如下: PUT /user_index {"mappings": {"properties" ...

  3. es 创建索引_es的基本原理和操作文档

    来源:https://blog.csdn.net/wanbf123/article/details/81504097 一.背景知识 1.搜索的分类 我们想要寻找某些信息的时候,一般会直接去百度.谷歌. ...

  4. es为mysql创建索引_ES(ElasticSearch) 索引创建

    环境:ES 6.2.2 os:Centos  7 kibana:6.2.2 介绍 索引是ElasticSearch存放数据的地方,可以理解为关系型数据库中的一个数据库.事实上,我们的数据被存储和索引在 ...

  5. es的基本操作(创建索引,添加数据,删除数据,判断索引是否存在)

    1.创建索引+ik分词器 /*** 创建es索引* $indexName 索引名称*/public function createEsIndex($indexName){$esClient = $th ...

  6. kibana创建es索引_java操作es动态创建索引(按月生成),索引类型,索引别名

    第一步:判断索引是否存在: //判断索引是否已经存在String indexName = Constans.ES_INDEX_TIME+"_"+DateUtils.getDateS ...

  7. java 索引实现,Java创建ES索引实现

    标签:public   text   cluster   frame   put   elastics   sea   min   user 1.pom.xml文件 org.springframewo ...

  8. logstash读取kafka所有topics 自动创建es 索引

    logstash读取kafka的topics,根据内容提取指定字段然后自动创建es索引. input {   kafka{      bootstrap_servers => "192 ...

  9. sql优化之:数据库索引创建原则,or/in/union与索引优化,聚集索引/非聚集索引/联合索引/索引覆盖,MySQL冗余数据的三种方案,MySQL双主一致性架构优化(来源:架构师之路)

    一.一些常见的SQL实践 (1)负向条件查询不能使用索引 select * from order where status!=0 and stauts!=1 not in/not exists都不是好 ...

最新文章

  1. 如何理解Eating这个词?云原生与微服务专场介绍
  2. Mac系统容易忽视但很实用的命令整理
  3. springboot——概述
  4. SQL Server中的零碎数据库还原
  5. iOS中常见的设计模式(MVC/单例/委托/观察者)
  6. 从mediaserver入手快速理解binder机制(最简单理解binder)
  7. Android水平仪实训报告,测量实训报告范文3篇
  8. 字符串通配符(递归)
  9. Java使用百度翻译api
  10. 项目实训12——解析建表的SQL语句
  11. 将读书笔记自动生成思维导图(Markdown)
  12. BT软件系统包含哪些部分?BT技术如何突破运营商的封锁?
  13. 星星之火OIer:C++大纲
  14. The Balance POJ - 2142
  15. 多线程与高并发day04
  16. 久坐伤腰!这款德国3D美臀坐垫,分散身体压力,保护腰椎尾椎。
  17. 影院活动管理系统--测试与部署阶段.
  18. 动态规划与最长重复子串 LRS and Dynamic Programming
  19. 谁能淘汰微信?除了它还有谁?
  20. Ubuntu常用工具安装方法及地址

热门文章

  1. EAS 表格、查询方案存储表
  2. Java基础知识之数组的初始化和基本操作
  3. 蓝桥杯51单片机之串口通信发送接收信息【单片机开发初学者串口必会】
  4. Python之网络编程(实现一个多用户同时在线的FTP用户管理程序)
  5. Python一句话实现秦九韶算法快速计算多项式的值
  6. 使用Python分析最新2000封电子邮件的时间分布
  7. 全国计算机等级考试二级Python考试大纲预测和分析
  8. 妙用Python集合求解啤酒问题(携程2016笔试题)
  9. 5渲染判断_Vue页面渲染中key的应用实例教程
  10. Python中map的使用方法