当前位置: 代码迷 >> 综合 >> Elasticsearch nested嵌套类型
  详细解决方案

Elasticsearch nested嵌套类型

热度:42   发布时间:2023-10-09 06:47:02.0

第一次接触es,感觉啥啥都是懵逼状态,不得不吐槽一下,出了问题网上写的那些文章真的是看不懂,要么代码不全,要么就是各种抄,根本结局不了问题,还是决定自己写一个吧,没准哪天就帮别人节省了时间.
话不多说,这里使用的版本是7.12.1,查看es版本方法:
直接在浏览器访问es端口号就行 ps:搞了一天才发现看的是2.0的api 我吐了
Elasticsearch nested嵌套类型
博主现在查看的api是7.14版本的(直接看最新的了)
为什么要用nested嵌套结构呢?具体可以看官网的解释,这里就不在多做赘述了:
https://www.elastic.co/guide/en/elasticsearch/reference/7.14/nested.html

简单来说就是需要一个多层嵌套的对象结构,例如:
公司下面有部门员工,员工下面有所属项目,都是一对多的关系,后面的代码也是使用的这个逻辑(可能有点不太合理,但是大致是这么个意思)

公司:
____部门名称
____部门员工:
________id
________姓名
________年龄
________所属项目:
____________项目名称

直接上代码

1.声明结构

PUT  localhost:9200/test_mapping7{
    "mappings": {
    "properties":{
    "group": {
    "type": "text"},"user":{
    "type": "nested",  //嵌套类型type应为nested"properties":{
    "id": {
    "type": "keyword"},"name":{
    "type": "text"},"age":{
     "type": "short"},"project":{
    "type": "nested","properties":{
    "name": {
    "type": "text"}}}}}}      }    
}

nested类型结构的属性应用properties表示,以下是官网api
Elasticsearch nested嵌套类型
2.声明成功后我们可以查询一下声明的结构

GET localhost:9200/test_mapping7?pretty  //pretty是输出json格式化后的数据{
                                                    "test_mapping7" : {
                                "aliases" : {
     },                             "mappings" : {
                                   "properties" : {
                               "group" : {
                                  "type" : "text"                        },                                       "user" : {
                                   "type" : "nested",                     "properties" : {
                           "age" : {
                                "type" : "short"                   },                                   "id" : {
                                 "type" : "keyword"                 },                                   "name" : {
                               "type" : "text"                    },                                   "project" : {
                            "type" : "nested",                 "properties" : {
                       "name" : {
                           "type" : "text"                }                                }                                  }                                    }                                      }                                        }                                          },                                           "settings" : {
                                   "index" : {
                                    "routing" : {
                                "allocation" : {
                           "include" : {
                            "_tier_preference" : "data_content"}                                    }                                      },                                       "number_of_shards" : "1",                "provided_name" : "test_mapping7",       "creation_date" : "1630464120543",       "number_of_replicas" : "1",              "uuid" : "stKB9OdESUmnqJwBKOK-pQ",       "version" : {
                                "created" : "7120199"                  }                                        }                                          }                                            }                                              
}                                                

3.插入数据
重点: 插入数据这块必须在index名后面加上/_doc/ , 本身这里应该是设置type的字段,但是在实际插入数据时,用自定义的stu,class等都会报错,难道只能插入doc类型? ps:正常猜想是在mapping中没有设置最外层的type,但是实际操作时声明type会报错

POST localhost:9200/test_mapping7/_doc/1 {
    "group": "研发","user":[{
    "id": 1,"name": "zhangsan","age": 12,"project":[{
    "name": "pro1"}]},{
    "id": 2,"name": "lisi","age": 15,"project":[{
    "name": "pro12"}]}]
}result:{
    "_index": "test_mapping7","_type": "_doc","_id": "2","_version": 1,"result": "created","_shards": {
    "total": 1,"successful": 1,"failed": 0},"_seq_no": 1,"_primary_term": 1
}

再插入一条

POST localhost:9200/test_mapping7/_doc/2{
    "group": "市场","user":[{
    "id": 3,"name": "xiaomei","age": 21,"project":[{
    "name": "pro3"}]},{
    "id": 4,"name": "xiaoxue","age": 25,"project":[{
    "name": "pro4"}]}]
}result:{
    "_index": "test_mapping7","_type": "_doc","_id": "2","_version": 1,"result": "created","_shards": {
    "total": 2,"successful": 1,"failed": 0},"_seq_no": 1,"_primary_term": 1
}

查询一下插入的数据

GET localhost:9200/test_mapping7/_search?pretty{
                                             "took" : 3,                             "timed_out" : false,                    "_shards" : {
                               "total" : 1,                          "successful" : 1,                     "skipped" : 0,                        "failed" : 0                          },                                      "hits" : {
                                  "total" : {
                               "value" : 2,                        "relation" : "eq"                   },                                    "max_score" : 1.0,                    "hits" : [                            {
                                       "_index" : "test_mapping7",       "_type" : "_doc",                 "_id" : "1",                      "_score" : 1.0,                   "_source" : {
                         "group" : "研发",                 "user" : [                      {
                                 "id" : 1,                   "name" : "zhangsan",        "age" : 12,                 "project" : [               {
                             "name" : "pro1"         }                         ]                           },                            {
                                 "id" : 2,                   "name" : "lisi",            "age" : 14,                 "project" : [               {
                             "name" : "pro12"        }                         ]                           }                             ]                               }                                 },                                  {
                                       "_index" : "test_mapping7",       "_type" : "_doc",                 "_id" : "2",                      "_score" : 1.0,                   "_source" : {
                         "group" : "市场",                 "user" : [                      {
                                 "id" : 3,                   "name" : "xiaomei",         "age" : 21,                 "project" : [               {
                             "name" : "pro3"         }                         ]                           },                            {
                                 "id" : 4,                   "name" : "xiaoxue",         "age" : 25,                 "project" : [               {
                             "name" : "pro4"         }                         ]                           }                             ]                               }                                 }                                   ]                                     }                                       
}                                         

4.查询

首先查询一下name=zhangsan的index

GET localhost:9200/test_mapping7/_search{
    "query": {
    "nested":{
    "path": "user","query": {
    "bool":{
    "must": [{
    "match": {
    "user.name":"zhangsan"}}]}}}}
}result:{
    "took": 2,"timed_out": false,"_shards": {
    "total": 1,"successful": 1,"skipped": 0,"failed": 0},"hits": {
    "total": {
    "value": 1,"relation": "eq"},"max_score": 1.2039728,"hits": [{
    "_index": "test_mapping7","_type": "_doc","_id": "1","_score": 1.2039728,"_source": {
    "group": "研发","user": [{
    "id": 1,"name": "zhangsan","age": 12,"project": [{
    "name": "pro1"}]},{
    "id": 2,"name": "lisi","age": 14,"project": [{
    "name": "pro12"}]}]}}]}
}

可以看到直接返回了整个doc1对象,符合预期结果

那么我们如果查询条件是project.name=pro4呢?划重点
nested.path必须是从外层开始写: user.project,不可以直接写project
match条件也要从最外层开始写 user.project.name=pro4,不可以直接写project.name=pro4

POST localhost:9200/test_mapping7/_search{
    "query": {
    "nested":{
    "path": "user.project","query": {
    "bool":{
    "must": [{
    "match": {
    "user.project.name":"pro4"}}]}}}}
}result:{
    "took": 2,"timed_out": false,"_shards": {
    "total": 1,"successful": 1,"skipped": 0,"failed": 0},"hits": {
    "total": {
    "value": 1,"relation": "eq"},"max_score": 1.2039728,"hits": [{
    "_index": "test_mapping7","_type": "_doc","_id": "2","_score": 1.2039728,"_source": {
    "group": "市场","user": [{
    "id": 3,"name": "xiaomei","age": 21,"project": [{
    "name": "pro3"}]},{
    "id": 4,"name": "xiaoxue","age": 25,"project": [{
    "name": "pro4"}]}]}}]}
}

成功命中
未完待续,欢迎补充指正

  相关解决方案