1. 程式人生 > >Elasticsearch增刪改查 之 —— mget多文件查詢

Elasticsearch增刪改查 之 —— mget多文件查詢

之前說過了針對單一文件的增刪改查,基本也算是達到了一個基本資料庫的功能。本篇主要描述的是多文件的查詢,通過這個查詢語法,可以根據多個文件的查詢條件,返回多個文件集合。
更多內容可以參考我整理的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
    }
  } ]
}