使用es操作arrays 和 nested


 
    在es内部 arrays,会被做一些特殊处理,当使用对象类型的arrays时,会造成无法使用对象的多个字段精确定位。
    想要解决这个问题,可以使用nested类型解决这个问题
 
 
arrays相关操作:
        这里我们假设,现在有一个需求,需要记录选修课中,选择某一个老师的学生有哪些。
 
创建索引
curl -XPUT "localhost:9200/test_arrays"
 
为索引创建mapping
curl -XPUT -H "Content-Type: application/json"  "127.0.0.1:9200/test_arrays/_mapping/class" -d'
{
    "properties":{
            "id":{
                "type":"keyword"
            },
            "name":{
                "type":"text"
            },
            "student":{                     #定义数组类型数据
                "properties":{             #以下开始定义数组里每一个字段的类型
                    "name":{
                        "type":"text"
                    },
                    "id":{
                        "type":"keyword"
                    }
                }
            }
    }
}'
 
向索引中添加数据(以数组形式添加)
curl -XPOST -H "Content-Type: application/json"  "127.0.0.1:9200/test_arrays/class" -d'
{
    "id": "1",
    "name":  "Mr Li",
    "student":[{
            "name": "li wu",
            "id": "001"
        },{
            "name": "li si",
            "id": "002"
        }
    ]
}'
 
普通添加数据
curl -XPOST -H "Content-Type: application/json"  "127.0.0.1:9200/test_arrays/class" -d'
{
    "id": "1",
    "name":  "Mr Li",
    "student":{
            "name": "li san",
            "id": "003"
    }
}'
 
查看索引中文档数:
    [root@jiangmin ~]# curl  "127.0.0.1:9200/_cat/indices?v"
    health status index       uuid                   pri rep docs.count docs.deleted store.size pri.store.size
    yellow open   test_arrays YRxATOUES4GkbPDlVXSaHQ   5   1          2            0      8.5kb          8.5kb
    yellow open   kvdata      NHXm9V03Rh6LlRmYKxlR6A   5   1         15            0     60.1kb         60.1kb
    yellow open   twitter     A_QiT7VoQbOBWlbql365rQ   5   1          2            0      9.6kb          9.6kb
    由此可知,添加两次数据,对应两个文档,es中数据以文档形式添加
 
根据学生id查询
curl -XGET -H "Content-Type: application/json"  "127.0.0.1:9200/test_arrays/class/_search" -d'
{
    "query":{
        "bool":{            #指明为布尔查询,可允许再单独的查询中组合任意数量的查询
            "must":{       #布尔查询的三个条件之一,must表明接下来的查询条件是必须符合的
                "match":{
                    "student.id":"001"
                }
            }
        }
    }
}'
 
查询结果
{"took":3,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":1,"max_score":0.2876821,"hits":[{"_index":"test_arrays","_type":"class","_id":"Wxl-VW8B5IaOoVqIepkO","_score":0.2876821,"_source":
{
    "id": "1",
    "name":  "Mr Li",
    "student":[{
            "name": "li wu",
            "id": "001"
        },{
            "name": "li si",
            "id": "002"
        }
    ]
}}]}}[root@jiangmin ~]#
 
根据学生姓名查询
curl -XGET -H "Content-Type: application/json"  "127.0.0.1:9200/test_arrays/class/_search" -d'
{
    "query":{
        "bool":{                #指明为布尔查询,可允许再单独的查询中组合任意数量的查询
            "must":{           #布尔查询的三个条件之一,must表明接下来的查询条件是必须符合的
                "match":{
                    "student.name": "li wu"
                }
            }
        }
    }
}'
查询结果:
{"took":1,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":2,"max_score":0.68324494,"hits":[{"_index":"test_arrays","_type":"class","_id":"Wxl-VW8B5IaOoVqIepkO","_score":0.68324494,"_source":
{
    "id": "1",
    "name":  "Mr Li",
    "student":[{
            "name": "li wu",
            "id": "001"
        },{
            "name": "li si",
            "id": "002"
        }
    ]
}},{"_index":"test_arrays","_type":"class","_id":"XBl_VW8B5IaOoVqI75nt","_score":0.2876821,"_source":
{
    "id": "1",
    "name":  "Mr Li",
    "student":{
            "name": "li san",
            "id": "003"
    }
}}]}}[root@jiangmin ~]#
 
 
根据学生姓名和id查询(由arrays引起的错误查询---如果需要解决这个问题使用嵌套对象nested)
curl -XGET -H "Content-Type: application/json"  "127.0.0.1:9200/test_arrays/class/_search" -d'
{
    "query":{
        "bool":{              #指明为布尔查询,可允许再单独的查询中组合任意数量的查询
            "must": [        #布尔查询的三个条件之一,must表明接下来的查询条件是必须符合的
                {
                    "match":{
                        "student.id": "002"
                    }
                },
                {
                    "match":{
                        "student.name": "li wu"
                    }
                }              
            ]
        }
    }
}'
 
获得结果如下:
{"took":1,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":1,"max_score":0.970927,"hits":[{"_index":"test_arrays","_type":"class","_id":"Wxl-VW8B5IaOoVqIepkO","_score":0.970927,"_source":
{
    "id": "1",
    "name":  "Mr Li",
    "student":[{
            "name": "li wu",
            "id": "001"
        },{
            "name": "li si",
            "id": "002"
        }
    ]
}}]}}[root@jiangmin ~]#
 
根据之前的操作可知,并不存在学生为002,名字为li wu的学生。 由于数组在存储时,按照如下形式存储。
 "student.id": [ "001", "002", "003"]
 "student.name": ["li wu", "li si", "li san"]
分词的时候,会按照这种顺序,将id和name中的值,随机组合。
数组中的查询条件不能相互组合
这种错误,只有使用nested对象类型才能解决
 
 

 
nested相关操作:
创建索引
curl -XPUT "localhost:9200/test_nested"
 
为索引创建mapping
curl -XPUT -H "Content-Type: application/json"  "127.0.0.1:9200/test_nested/_mapping/class" -d'
{
    "properties":{
            "id":{
                "type":"keyword"
            },
            "name":{
                "type":"text"
            },
            "student":{                     #定义数组类型数据
                "type":"nested",         #定义nested类型
                "properties":{             #以下开始定义数组里每一个字段的类型
                    "name":{
                        "type":"text"
                    },
                    "id":{
                        "type":"keyword"
                    }
                }
            }
    }
}'
 
重复以上操作添加数据:
提交测试数据
curl -XPOST -H "Content-Type: application/json"  "127.0.0.1:9200/test_nested/class" -d'
{
    "id": "1",
    "name":  "Mr Li",
    "student":[{
            "name": "li wu",
            "id": "001"
        },{
            "name": "li si",
            "id": "002"
        }
    ]
}'
 
查询非法数据
curl -XGET -H "Content-Type: application/json"  "127.0.0.1:9200/test_nested/class/_search" -d'
{
    "query":{
        "bool":{             
            "must": [        
                {
                    "match":{
                        "student.id": "002"
                    }
                },
                {
                    "match":{
                        "student.name": "li wu"
                    }
                }              
            ]
        }
    }
}'
 
获得结果无法查询
{"took":1,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":0,"max_score":null,"hits":[]}}
 
查询正确数据
 
这个验证有点问题,暂时不做处理,需要说明的是,nested类型的查询操作,与普通的查询操作不一样
 
curl -XGET -H "Content-Type: application/json"  "127.0.0.1:9200/test_nested/class/_search" -d'
{
    "query":{
        "nested":{
            "path":"student",
            "query":{
                    "bool":{             
                        "must": [        
                            {
                                "match":{
                                    "student.id": "002"
                                }
                            },
                            {
                                "match":{
                                    "student.name": "li si"
                                }
                            }              
                        ]
                    }
            }
        }
    }
}'
 
 
 
 
 
 
 
 
 
 
 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM