在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"
}
}
]
}
}
}
}
}'