栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

Elasticsearch Nested类型

Elasticsearch Nested类型

概要
在Elasticsearch实战场景中,我们或多或少会遇到嵌套文档的组合形式,反映在ES中称为父子文档。
父子文档的实现,至少包含以下两种方式:
1)父子文档
父子文档在5.X版本中通过parent-child父子type实现,即:1个索引对应多个type;
6.X+版本已经不再支持一个索引多个type,6.X+的父子索引的实现改成Join。
2)Nested嵌套类型

问题引出
示例:

{
  "age": 10,
  "name": "libai",
  "objs": [
    {
      "field1": "aaa1",
      "field2": "bbb"
    },
    {
      "field1": "aaa",
      "field2": "bbb1"
    }
  ]
}

新建索引

PUT /blog_new
{
  "mappings": {
        "properties" : {
        "age" : {
          "type" : "long"
        },
        "name" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "nickname" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "sex" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "objs":{
            "properties" : {
              "field1": {
                "type" :"text"
              },
                "field2": {
                "type" :"text"
              }
            }
        }
      }
  }
}

添加数据

POST /blog_new/_doc/1
{
  "age": 10,
  "name":"libai",
  "objs":
  [{
    "field1": "aaa1",
    "field2": "bbb"
  },
  {
    "field1": "aaa",
    "field2": "bbb1"
  }]
}

查看数据:

GET /blog_new/_search
{
  "query": {
    "match_all":{
      
    }
  }
}

条件查询数据: field1: aaa1 field2: bbb2

GET /blog_new/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match":{
            "objs.field1": "aaa1"
          }
        },
        {
          "match":{
            "objs.field2": "bbb1"
          }
        }
      ]
    }
  }
}}

原因分析
这就是为什么我说:
elasticsearch中的内部对象无法按预期工作
这里的问题是elasticsearch(lucene)使用的库没有内部对象的概念,因此内部对象被扁平化为一个简单的字段名称和值列表。
我们的文档内部存储为:

{
  "name":                   [ "李白" ],
  "age":                    [ 10 ],
  "objs.field1":            [ "aaa1", "bbb" ],
  "objs.field2":            [ "aaa", "bbb1" ]
}

如何解决呢

我们需要更新它的类型为nested。

查询

GET /blog_new/_search
{
  "query": {
    "bool": {
      "must": [
        {
         "nested": {
           "path": "objs",
           "query": {
             "bool": {
               "must": [
                 {
                   "match": {
                     "objs.field1": "aaa1"
                   }
                 }
               ]
             }
           }
         }
        }
      ]
    }
  }
}

GET /blog_new/_search?pretty
{
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "objs",
            "query": {
              "bool": {
                "must": [
                  {
                    "match": {
                      "objs.field1": "aaa1"
                    }
                  },
                  {
                    "match": {
                      "objs.field2": "bbb1"
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

GET /blog_new/_search?pretty
{
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "objs",
            "query": {
              "bool": {
                "must": [
                  {
                    "match": {
                      "objs.field1": "aaa1"
                    }
                  },
                  {
                    "match": {
                      "objs.field2": "bbb"
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}


原理

{
  "name":            [ "李白" ],
  "age":             [ 10 ],
  {
    "objs.field1"::    [ "aaa1"],
    "objs.field2":     [ "bbb" ]
  },
   {
    "objs.field1"::    [ "aaa" ],
    "objs.field2":     [ "bbb1"]
  }
}

Nested类型的作用?
从上一小节,可以清晰的看出nested类型的特别之处。
nested类型是对象数据类型的专用版本,它允许对象数组以可以彼此独立查询的方式进行索引。

4、Nested类型的适用场景

图片来自:rockybean教程

Nested类型的增、删、改、查、聚合操作详解

Nested类型——增

POST /blog_new/_doc/1
{
  "age": 10,
  "name":"libai",
  "objs":
	  [
		  {
		    "field1": "aaa1",
		    "field2": "bbb"
		  },
		  {
		    "field1": "aaa",
		    "field2": "bbb1"
		  }
	  ]
}

仅增加objs一个元素

POST blog_new/_update_by_query
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "libai"
          }
        }
      ]
    }
  },
  "script": {
    "lang": "painless",
    "params": {
      "obj": {
        "field1": "000",
        "field2": "111"
      }
    },
    "source": "ctx._source.objs.add(params.obj)"
  }
}

Nested类型——删
序号为1的评论原来有两条,现在删除field1 =aaa 的数据,删除后objs数为一条。

POST  blog_new/_doc/_update
{
 "script": {
    "lang": "painless",
    "source": "ctx._source.objs.removeIf(it -> it.field1 == 'aaa');"
 }
}

5.3 Nested类型——改

POST blog_new/_update_by_query
{
    "query": {
    "bool": {
      "must": [
        {
         "nested": {
           "path": "objs",
           "query": {
             "bool": {
               "must": [
                 {
                   "match": {
                     "objs.field1": "aaa1"
                   }
                 }
               ]
             }
           }
         }
        }
       
      ]
    }
  },
  "script": {
    "source": "for(e in ctx._source.objs){if (e.field1 == 'aaa1') {e.field1 = 25; e.field2= 'very very good article...';}}" 
  }
}

5.4 Nested类型——查
如前所述,查询评论字段中评论姓名=William并且评论age=34的blog信息。

GET /blog_new/_search
{
  "query": {
    "bool": {
      "must": [
        {
         "nested": {
           "path": "objs",
           "query": {
             "bool": {
               "must": [
                 {
                   "match": {
                     "objs.field1": "aaa1"
                   }
                 }
               ]
             }
           }
         }
        }
      ]
    }
  }
}

5.5 Nested类型——聚合

GET blog_new/_search
{
  "size": 0,
  "aggs": {
    "comm_aggs": {
      "nested": {
        "path": "objs"
      },
      "aggs": {
        "min_age": {
        "cardinality":{"field":"objs.field1.keyword"}
        }
      }
    }
  }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/779771.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号