更多內容參考:Elasticsearch學習總結html
在Elasticsearch中String是最基本的數據類型,若是不是數字或者標準格式的日期等這種很明顯的類型,其餘的通常都會優先默認存儲成String。一樣的數據類型,Elasticsearch也提供了多種存儲與分詞的模式,不一樣的模式應用於不一樣的場景。app
不少人在初次使用Elasticsearch時,都會很納悶...curl
等等,這些都與是否分詞、使用什麼分詞器有關。elasticsearch
我愛你中國
!若是是標準分詞器,會把它拆分紅,「我」,「愛」,「你」,「中」,「國」。
若是使用一些漢語的分詞器,則會分析成,「我」,「愛」,「你」,「中國」。學習
因爲倒排索引都是以詞Term爲索引的,所以若是分解成了一個一個的詞,查詢「中國」
的時候,中國也會被分解成「中」
,「國」
,這樣就可能偏差到」發展中國家「
這樣的詞。url
不光是在索引文檔(把數據導入到Elasticsearch中),在查詢的時候也須要分詞器。只有索引和查詢的時候使用相同的分詞器,才能查詢出正確的結果。code
可是有時候,咱們並不想把一串String給分析,想把它當作一個完整的詞。好比htm
www.baidu.com
吉林省 長春市 衛星路 6543號
此時,只要設置字段爲不分析,就能夠了。這時須要自定義下映射,由於默認String就是分析的,並且使用的是標準分詞器。blog
先創建一個索引索引
curl -XPUT localhost:9200/abc
而後定義映射,注意:只有剛剛新建、尚未任何數據的索引,才能定義映射。定義映射Mapping可使用_mapping RESTAPI,符合下面的標準語法:
curl -XPUT localhost:9200/索引名稱/類型名稱/_mapping?pretty -d '{"類型名稱":{"properties":{"字段名稱":{"type":"字段類型","store":"是否存儲","index":"索引方式、是否分析"}}}}'
好比,其中str1爲String類型不分析;其餘的字段str2爲默認配置,就不用設置了。
curl -XPUT localhost:9200/abc/abc/_mapping?pretty -d '{"abc":{"properties":{"str1":{"type":"string","index":"not_analyzed"}}}}'
而後添加兩條數據:
curl localhost:9200/abc/abc?pretty -d '{"str1":"hello, world!","str2":"goodbye! world"}' { "_index" : "abc", "_type" : "abc", "_id" : "AVM2vRQgJmh5lL1r79nv", "_version" : 1, "created" : true } curl localhost:9200/abc/abc?pretty -d '{"str1":"hello","str2":"world"}' { "_index" : "abc", "_type" : "abc", "_id" : "AVM2vbbqJmh5lL1r79nw", "_version" : 1, "created" : true }
若是查詢的單個詞,分詞的字段可使用term進行查詢,以下所示:若是查詢的是一個單獨的詞,那麼會返回包含它或者等於它的目標文檔。
curl -XPOST localhost:9200/abc/_search?pretty -d '{"query":{"term":{"str2":"world"}}}' { "took" : 1, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "failed" : 0 }, "hits" : { "total" : 2, "max_score" : 0.5945348, "hits" : [ { "_index" : "abc", "_type" : "abc", "_id" : "AVM2vbbqJmh5lL1r79nw", "_score" : 0.5945348, "_source":{"str1":"hello","str2":"world"} }, { "_index" : "abc", "_type" : "abc", "_id" : "AVM2vRQgJmh5lL1r79nv", "_score" : 0.37158427, "_source":{"str1":"hello, world!","str2":"goodbye! world"} } ] } }
若是字段是不分詞的,而查詢的是這個字段裏面的一個詞,那麼使用term時沒法查詢到目標文檔的。
$ curl -XPOST localhost:9200/abc/_search?pretty -d '{"query":{"term":{"str1":"hello"}}}' { "took" : 1, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "failed" : 0 }, "hits" : { "total" : 1, "max_score" : 1.0, "hits" : [ { "_index" : "abc", "_type" : "abc", "_id" : "AVM2vbbqJmh5lL1r79nw", "_score" : 1.0, "_source":{"str1":"hello","str2":"world"} } ] } }
使用term查詢,若是該字段是不分詞,只有完整的輸入目標字段,才能正確的匹配。
curl -XPOST localhost:9200/abc/_search?pretty -d '{"query":{"term":{"str1":"hello, world!"}}}' { "took" : 2, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "failed" : 0 }, "hits" : { "total" : 1, "max_score" : 1.0, "hits" : [ { "_index" : "abc", "_type" : "abc", "_id" : "AVM2vRQgJmh5lL1r79nv", "_score" : 1.0, "_source":{"str1":"hello, world!","str2":"goodbye! world"} } ] } }
1 若是查詢的是單個詞,則查詢到包含它的文檔,返回結果與匹配程度有關
2 若是查詢的是一段能被分析的話,好比hello world
。那麼查詢的結果是包含分析得出的詞的文檔,即包含hello
和world
的所有文檔。
只有查詢的是 目標字段的精確值,才能匹配。