之前說過了針對單一文檔的增刪改查,基本也算是達到了一個基本數據庫的功能。本篇主要描述的是多文檔的查詢,通過這個查詢語法,可以根據多個文檔的查詢條件,返回多個文檔集合。
更多內容可以參考我整理的ELK文檔教程
multi Get
多字段查詢可以設置多個文檔查詢條件,每個查詢條件在結構上都比較類似:
curl 'localhost:9200/_mget' -d '{
"docs" : [
{
"_index" : "test",
"_type" : "type",
"_id" : "1"
},
{
"_index" : "test",
"_type" : "type",
"_id" : "2"
}
]
}'
當然,在查詢條件中,body中_index字段也可以放在查詢字符串中:
curl 'localhost:9200/test/_mget' -d '{
"docs" : [
{
"_type" : "type",
"_id" : "1"
},
{
"_type" : "type",
"_id" : "2"
}
]
}'
對於type也是一樣:
curl 'localhost:9200/test/type/_mget' -d '{
"docs" : [
{
"_id" : "1"
},
{
"_id" : "2"
}
]
}'
如果索引和類型都放在查詢URL中,那么字段ID就可以放在一個數組中:
curl 'localhost:9200/test/type/_mget' -d '{
"ids" : ["1", "2"]
}'
type可選
mget查詢中類型type是可選的。如果設置_all或者不設置,就會匹配所有的類型,那么僅僅會返回第一個匹配的文檔。
但是如果沒有設置type,然后查詢的id里面又出現兩個一樣的id,就會返回第一次匹配的文檔兩次:
curl 'localhost:9200/test/_mget' -d '{
"ids" : ["1", "1"]
}'
因此如果想要查詢到不同類型的id,就需要指定類型名稱:
GET /test/_mget/
{
"docs" : [
{
"_type":"typeA",
"_id" : "1"
},
{
"_type":"typeB",
"_id" : "1"
}
]
}
_source過濾
默認_source
字段會返回所有的內容,你也可以通過_source
進行過濾。比如使用_source
,_source_include
,_source_exclude
.
比如:
curl 'localhost:9200/_mget' -d '{
"docs" : [
{
"_index" : "test",
"_type" : "type",
"_id" : "1",
"_source" : false
},
{
"_index" : "test",
"_type" : "type",
"_id" : "2",
"_source" : ["field3", "field4"]
},
{
"_index" : "test",
"_type" : "type",
"_id" : "3",
"_source" : {
"include": ["user"],
"exclude": ["user.location"]
}
}
]
}'
Fields過濾
與其他的普通查詢差不多,mget查詢也支持Fields過濾。
curl 'localhost:9200/_mget' -d '{
"docs" : [
{
"_index" : "test",
"_type" : "type",
"_id" : "1",
"fields" : ["field1", "field2"]
},
{
"_index" : "test",
"_type" : "type",
"_id" : "2",
"fields" : ["field3", "field4"]
}
]
}'
也可以在URL中的查詢字符串中設置默認的過濾,然后在Body中進行特殊的修改:
curl 'localhost:9200/test/type/_mget?fields=field1,field2' -d '{
"docs" : [
{
"_id" : "1"
},
{
"_id" : "2",
"fields" : ["field3", "field4"]
}
]
}'
id1的文檔就會返回field1和field2,id2的文檔就會返回field3和field4.
路由
在mget查詢中也會涉及到路由的問題。可以在url中設置默認的路由,然后在Body中修改:
curl 'localhost:9200/_mget?routing=key1' -d '{
"docs" : [
{
"_index" : "test",
"_type" : "type",
"_id" : "1",
"_routing" : "key2"
},
{
"_index" : "test",
"_type" : "type",
"_id" : "2"
}
]
}'
在上面的例子中,test/type/1
按照key2
這個路由鎖定分片進行查詢;test/type/2
按照key1
這個路由鎖定分片進行查詢。
實際演練
首先創建兩個文檔:
curl -XPOST localhost:9200/test/_mget?pretty -d '{"ids":["1"]}'
curl -XPOST localhost:9200/test/testb/1?pretty -d '{"name":"b","age":122}'
如果不指定type,那么返回的僅僅是一個最先匹配的結果:
$ curl -XPOST localhost:9200/test/_mget?pretty -d '{"ids":["1"]}' {
"docs" : [ {
"_index" : "test",
"_type" : "testb",
"_id" : "1",
"_version" : 2,
"found" : true,
"_source" : {
"name" : "b",
"age" : 122
}
} ]
}
如果指定了重復的id,則返回的是多次第一次匹配的文檔:
$ curl -XPOST localhost:9200/test/_mget?pretty -d '{"ids":["1","1"]}' {
"docs" : [ {
"_index" : "test",
"_type" : "testb",
"_id" : "1",
"_version" : 2,
"found" : true,
"_source" : {
"name" : "b",
"age" : 122
}
}, {
"_index" : "test",
"_type" : "testb",
"_id" : "1",
"_version" : 2,
"found" : true,
"_source" : {
"name" : "b",
"age" : 122
}
} ]
}
如果指定了類型,再去查詢,則返回的是各自的id:
$ curl -XPOST localhost:9200/test/_mget?pretty -d '{"docs":[{"_type":"testa","_id":"1"},{"_type":"testb","_id":"1"}]}'
{
"docs" : [ {
"_index" : "test",
"_type" : "testa",
"_id" : "1",
"_version" : 1,
"found" : true,
"_source" : {
"name" : "a",
"age" : 31
}
}, {
"_index" : "test",
"_type" : "testb",
"_id" : "1",
"_version" : 2,
"found" : true,
"_source" : {
"name" : "b",
"age" : 122
}
} ]
}