Elasticsearch-如何控制存儲和索引文檔(_source、_all)
_source:可以在索引中存儲文檔。
_all:可以在單個字段上索引所有內容。
1. 存儲原有內容的_source
_source字段按照原有格式來存儲原有的文檔。這一點可以看到匹配某個搜索的文檔,而不僅僅是他們的ID。
_source字段的enabled可以設置為true或者false,來指定是否需要存儲原始的文檔。默認情況下是true,在很多情況下,設置為true還是非常有用的,因為_source的存在允許使用其他重要的ES特性。(由於很多功能都依賴於_source,而且從空間和性能的角度來看存儲的成本相對低廉,在版本2.0中將無法再關閉_source選項。)
為了理解這個字段是如何工作的,來看下當檢索某篇之前索引的文檔時,ES通常返回什么:
(1) 先索引一篇文檔
curl -XPUT 'localhost:9200/music/album/5?pretty' -d '{ "name":"七里香", "date":"2004-08-03", "songs":["七里香","擱淺"] }'
(2) 檢索
FengZhendeMacBook-Pro:cv FengZhen$ curl 'localhost:9200/music/album/5?pretty'
{
"_index" : "music",
"_type" : "album",
"_id" : "5",
"_version" : 1,
"found" : true,
"_source" : {
"name" : "七里香",
"date" : "2004-08-03",
"songs" : [ "七里香", "擱淺" ]
}
}
搜索的同時,會獲得_source的JSON,因為這是默認設置會返回的內容。
2. 僅僅返回源文檔的某些字段
當檢索或者搜索某篇文檔的時候,可以要求ES只返回特定的字段,而不是整個_source.一種實現的方法是在fields參數中提供用逗號分隔的字段列表。如下
FengZhendeMacBook-Pro:cv FengZhen$ curl -XGET 'localhost:9200/music/album/5?pretty&fields=name'
{
"_index" : "music",
"_type" : "album",
"_id" : "5",
"_version" : 1,
"found" : true,
"fields" : {
"name" : [ "七里香" ]
}
}
如果_source已經被存儲,ES從那里獲取所需的字段。也可以通過設置store選項為yes來存儲個別的字段。舉個例子,如果只需要存儲test_name字段,映射如下
curl -XPUT 'localhost:9200/music/_mapping/test' -d '{ "test":{ "properties":{ "test_name":{ "type":"string", "store":"yes" } } } }'
向ES請求特定的字段時,這樣做可能會很有幫助,原因是相對於檢索整個_source然后再抽取而言,檢索單一的存儲字段要更快一些,尤其是在文檔很大的時候。
注意:當存儲單獨的字段時,應該考慮到存儲的越多,索引越大。更大的索引經常意味着更慢的索引和搜索速度。
就其內部來看,_source只是另一個Lucene中的存儲字段。ES將原始的JSON存儲於其中,然后按需抽取字段。
3. 索引一切的_all
_all是索引所有的信息。當搜索_all字段的時候,ES將在不考慮是哪個字段匹配成功的情況下,返回命中的文檔。當用戶不知道在哪里查詢某些內容的時候,這一點非常有用。
從URI上運行搜索時如果不指定字段名稱,系統默認情況下將會在_all上搜索:
curl 'localhost:9200/music/album/_search?pretty' -d '{ "query":{ "query_string":{ "query":"八度空間" } } }'
如果總是在特定的字段上搜索,可以通過設置enabled為false來關閉_all:
"events":{ "_all":{"enabled":false} }
如此設置會使得索引的規模變得更小,而且索引操作變得更快。
默認情況下,include_in_all隱式的設置為true,每個字段都會包含在_all之中。可以使用這個選項來控制哪些字段被_all包含,而哪些不被_all包含。
(1).將test_date字段設置為不在_all中
curl -XPUT 'localhost:9200/music/_mapping/test' -d '{ "test":{ "properties":{ "test_date":{ "type":"date", "include_in_all":false } } } }'
(2).索引新文檔
curl -XPUT 'localhost:9200/music/test/1?pretty' -d '{ "test_name":"八度空間", "test_date":"2002-07-18", "test_songs":["半獸人","回到過去","米蘭的小鐵匠","最后的戰役"] }'
(3).查詢
FengZhendeMacBook-Pro:cv FengZhen$ curl 'localhost:9200/music/test/_search?q=2002-07-18&pretty' { "took" : 3, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "failed" : 0 }, "hits" : { "total" : 0, "max_score" : null, "hits" : [ ] } }
此時,不指定字段查詢,已經查不出數據了
使用include_in_all的選項,將賦予更高的靈活性,靈活性不僅體現在空間存儲上,同樣體現在查詢的表現方式上。如果一次搜索在沒有指定字段的情形下運行,ES只會匹配_all所包含的字段。