• Elasticsearch中object类型与nested类型之间的区别


    一、区别:

    1、默认情况下ES会把JSON对象直接映射为object类型,只有手动设置才会映射为nested类型

    2、object类型可以直接使用普通的逗号(.)查询,比如"term": {"inspector.id": {"value": "1222"}}

    3、nested类型的查询需要使用nested查询:"nested": {"path": "inspector","query": {"exists": {"field": "inspector.id"}}}

    4、两种查询方式不兼容,如果大家想做改动的话,需要对java程序进行修改,风险比较大。

    5、注意object类型的数组,查询的时候,结果可能是你不想要的值

    二、ES对object类型进行索引的过程:

    1、原始文档内容:

    1. {
    2. "tweet": "Elasticsearch is very flexible",
    3. "user": {
    4. "id": "@johnsmith",
    5. "gender": "male",
    6. "age": 26,
    7. "name": {
    8. "full": "John Smith",
    9. "first": "John",
    10. "last": "Smith"
    11. }
    12. }
    13. }

    2、映射为object类型

    Elasticsearch 会动态监测新的对象域并映射它们为 object类型,在 properties 属性下列出内部域:

    1. {
    2. "gb": {
    3. "tweet": {
    4. "properties": {
    5. "tweet": { "type": "string" },
    6. "user": {
    7. "type": "object",
    8. "properties": {
    9. "id": { "type": "string" },
    10. "gender": { "type": "string" },
    11. "age": { "type": "long" },
    12. "name": {
    13. "type": "object",
    14. "properties": {
    15. "full": { "type": "string" },
    16. "first": { "type": "string" },
    17. "last": { "type": "string" }
    18. }
    19. }
    20. }
    21. }
    22. }
    23. }
    24. }
    25. }

    从上面的映射我们可以看到user 和 name 字段都被映射为"type":"object"

    3、object的索引:

    Lucene 不理解内部对象。 Lucene 文档是由一组键值对列表组成的。为了能让 Elasticsearch 有效地索引对象,对其进行了扁平化处理,它把我们的文档转化成这样:

    1. {
    2. "tweet": [elasticsearch, flexible, very],
    3. "user.id": [@johnsmith],
    4. "user.gender": [male],
    5. "user.age": [26],
    6. "user.name.full": [john, smith],
    7. "user.name.first": [john],
    8. "user.name.last": [smith]
    9. }

    4、object类型的查询:

    使用全路径进行查询 (例如, user.name.first )

    5、object数组的索引:

     假设我们有个 followers 数组:

    1. {
    2. "followers": [
    3. { "age": 35, "name": "Mary White"},
    4. { "age": 26, "name": "Alex Jones"},
    5. { "age": 19, "name": "Lisa Smith"}
    6. ]
    7. }

    这个文档会像我们之前描述的那样被扁平化处理,结果如下所示:

    1. {
    2. "followers.age": [19, 26, 35],
    3. "followers.name": [alex, jones, lisa, smith, mary, white]
    4. }

    {age: 35} 和 {name: Mary White} 之间的相关性已经丢失了,因为每个多值域只是一包无序的值,而不是有序数组。于是我们不能得到一个准确的答案:“是否有一个26岁 名字叫 Alex Jones 的追随者?” 嵌套对象 就是来解决这个问题的。

    三、ES对nested类型进行索引的过程:

    1、原始文档内容:

    1. PUT /my_index/blogpost/1
    2. {
    3. "title": "Nest eggs",
    4. "body": "Making your money work...",
    5. "tags": [ "cash", "shares" ],
    6. "comments": [
    7. {
    8. "name": "John Smith",
    9. "comment": "Great article",
    10. "age": 28,
    11. "stars": 4,
    12. "date": "2014-09-01"
    13. },
    14. {
    15. "name": "Alice White",
    16. "comment": "More like this please",
    17. "age": 31,
    18. "stars": 5,
    19. "date": "2014-10-22"
    20. }
    21. ]
    22. }

    2、映射为nested类型并索引:

    将 comments 字段类型设置为 nested 而不是 object 后,每一个嵌套对象都会被索引为一个 隐藏的独立文档 ,举例如下:

    1. {
    2. "comments.name": [ john, smith ],
    3. "comments.comment": [ article, great ],
    4. "comments.age": [ 28 ],
    5. "comments.stars": [ 4 ],
    6. "comments.date": [ 2014-09-01 ]
    7. }
    8. {
    9. "comments.name": [ alice, white ],
    10. "comments.comment": [ like, more, please, this ],
    11. "comments.age": [ 31 ],
    12. "comments.stars": [ 5 ],
    13. "comments.date": [ 2014-10-22 ]
    14. }
    15. {
    16. "title": [ eggs, nest ],
    17. "body": [ making, money, work, your ],
    18. "tags": [ cash, shares ]
    19. }

    在独立索引每一个嵌套对象后,对象中每个字段的相关性得以保留。我们查询时,也仅仅返回那些真正符合条件的文档。

    3、注意事项

    3.1、由于嵌套文档直接存储在文档内部,查询时嵌套文档和根文档联合成本很低,速度和单独存储几乎一样。

    3.2、嵌套文档是隐藏存储的,我们不能直接获取。如果要增删改一个嵌套对象,我们必须把整个文档重新索引才可以。

    3.3、查询的时候返回的是整个文档,而不是嵌套文档本身

    4、nested类型的查询:

    由于嵌套对象 被索引在独立隐藏的文档中,我们无法直接查询它们。 相应地,我们必须使用 nested 查询 去获取它们:

    1. GET /my_index/blogpost/_search
    2. {
    3. "query": {
    4. "bool": {
    5. "must": [
    6. {
    7. "match": {
    8. "title": "eggs"
    9. }
    10. },
    11. {
    12. "nested": {
    13. "path": "comments",
    14. "query": {
    15. "bool": {
    16. "must": [
    17. {
    18. "match": {
    19. "comments.name": "john"
    20. }
    21. },
    22. {
    23. "match": {
    24. "comments.age": 28
    25. }
    26. }
    27. ]
    28. }
    29. }
    30. }
    31. }
    32. ]
    33. }}}

  • 相关阅读:
    nested字段聚合
    【Python&GIS】解决GIS属性表、矢量字段乱码,中文乱码
    08-prometheus监控的告警通知-alertmanager组件工具
    当多条折线数据渲染在一个echarts里,这些折线的x轴数据是不统一的,处理方法
    PMP机构哪家强?这个机构对比测评告诉你!!!
    SimpleDateFormat 线程安全问题修复方案
    第2-3-4章 上传附件的接口开发-文件存储服务系统-nginx/fastDFS/minio/阿里云oss/七牛云oss
    FastGateway 发布v0.0.0.5
    mysql中的case when 与 if else
    cx3588 Recovery HDMI 没显示
  • 原文地址:https://blog.csdn.net/duzm200542901104/article/details/125879476