Elasticsearch(如下簡稱ES)有個copy_to
的功能,以前在一個項目中用到,感受像是發現了一個神器。這個東西並非像有些人說的是個語法糖。它用好了不但能提升檢索的效率,還能夠簡化查詢語句。app
直接上示例。ui
先看看mapping,code
PUT my_index { "mappings": { "properties": { "first_name": { "type": "text", "copy_to": "full_name" }, "last_name": { "type": "text", "copy_to": "full_name" }, "full_name": { "type": "text" } } } }
first_name和last_name都指定了copy_to
,表示他們這兩個字段的值都會複製到full_name上。寫入兩條文檔看看,文檔
PUT my_index/_doc/1 { "first_name": "John", "last_name": "Smith" } PUT my_index/_doc/2 { "first_name": "Tom", "last_name": "Cruise" }
而後咱們在查詢的時候,就能夠指定從full_name這個字段查詢了,it
GET my_index/_search { "query": { "match": { "full_name": { "query": "John Smith", "operator": "and" } } } }
查詢結果以下:io
"hits" : { "total" : { "value" : 1, "relation" : "eq" }, "max_score" : 1.3862944, "hits" : [ { "_index" : "my_index", "_type" : "_doc", "_id" : "1", "_score" : 1.3862944, "_source" : { "first_name" : "John", "last_name" : "Smith" } } ] }
若是沒有使用copy_to的話,咱們須要指定兩個字段查詢,相似以下的語句:ast
GET my_index/_search { "query": { "bool": { "must": [ {"match": { "first_name": "John" }}, {"match": { "last_name": "Smith" }} ] } } }
兩種方式查詢的結果是同樣的。效率
聊完了基本用法,來看看一些高級的功能。假如說咱們想獲取full_name的內容,有些業務場景下,咱們會須要返回這個字段,怎麼辦呢?其實很簡單,以下所示,咱們在設置mapping的時候加上store:true
便可。原理
PUT my_index { "mappings": { "properties": { "first_name": { "type": "text", "copy_to": "full_name" }, "last_name": { "type": "text", "copy_to": "full_name" }, "full_name": { "type": "text", "store": true } } } }
而後再寫入文檔,咱們能夠經過下面的語句查詢到full_name的內容。進階
GET my_index/_doc/1?stored_fields=full_name
得的結果是:
{ "_index" : "my_index", "_type" : "_doc", "_id" : "1", "_version" : 1, "_seq_no" : 0, "_primary_term" : 1, "found" : true, "fields" : { "full_name" : [ "John", "Smith" ] } }
若是你沒有指定store
爲true,查詢的結果是這樣的:
{ "_index" : "my_index", "_type" : "_doc", "_id" : "1", "_version" : 1, "_seq_no" : 0, "_primary_term" : 1, "found" : true }
再來看另一個問題。把上面的mapping改一下,text改成keyword,以下:
PUT my_index { "mappings": { "properties": { "first_name": { "type": "keyword", "copy_to": "full_name" }, "last_name": { "type": "keyword", "copy_to": "full_name" }, "full_name": { "type": "keyword", "store": true } } } }
而後仍是寫入上面示例的兩條數據。當咱們用通用的查詢語句查詢時發現搜索不到結果了,這是爲啥呢?我這裏先給出解決方案,可是不解釋原理,有興趣的能夠思考下。
用下面兩個查詢語句均可以查詢到結果,你以爲是什麼緣由?
GET my_index/_search { "query": { "bool": { "must": [ {"term": { "first_name": { "value": "John" } }}, {"term": { "last_name": { "value": "Smith" } }} ] } } } GET my_index/_search { "query": { "terms": { "full_name": [ "John", "Smith" ] } } }