Elasticsearch nested嵌套类型

第一次接触es,感觉啥啥都是懵逼状态,不得不吐槽一下,出了问题网上写的那些文章真的是看不懂,要么代码不全,要么就是各种抄,根本结局不了问题,还是决定自己写一个吧,没准哪天就帮别人节省了时间.
话不多说,这里使用的版本是7.12.1,查看es版本方法:
直接在浏览器访问es端口号就行 ps:搞了一天才发现看的是2.0的api 我吐了
在这里插入图片描述
博主现在查看的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
在这里插入图片描述
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"
                                }
                            ]
                        }
                    ]
                }
            }
        ]
    }
}

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值