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