ES默認是動態建立索引和索引類型的mapping的。這就至關於無需定義Solr中的Schema,無需指定各個字段的索引規則就能夠索引文件,很方便。但有時方便就表明着不靈活。好比,ES默認一個字段是要作分詞的,但咱們有時要搜索匹配整個字段卻不行。若有統計工做要記錄每一個城市出現的次數。對於NAME字段,若記錄「new york」文本,ES可能會把它拆分紅「new」和「york」這兩個詞,分別計算這個兩個單詞的次數,而不是咱們指望的「new york」。java
這時,就須要咱們在建立索引時定義mapping。假設索引叫index_name,索引類型的名字叫index_type,編寫mapping文件以下(注意:mapping文件中,index_type必須與實際索引當中的索引類型徹底一致。):
json
{ "index_type":{ "properties":{ "ID":{ "type":"string", "index":"not_analyzed" }, "NAME":{ "type":"string", "fields":{ "NAME":{ "type":"string" }, "raw":{ "type":"string", "index":"not_analyzed" } } } } } }
以上文件是說咱們對於index_type這個索引類型,定義了它的mapping。重點是將NAME這個字段映射爲兩個,一個是須要作索引分析的NAME,另外一個是不分析的raw,即不會拆分new york這種詞組。這樣咱們在作搜索的時候,就能夠對NAME.raw這個字段作term aggregation,得到全部城市出現的次數了。term aggregation的REST方式的請求編寫以下:app
{ "query": { "match_all": {} }, "aggregations": { "cityAggs": { "terms": { "field": "NAME.raw" } } } }
因爲我使用的是Windows開發機,強烈推薦安裝Elasticsearch Head來作測試,比命令行Curl方便多了。Elasticsearch Head的安裝很簡單,進入ES的bin目錄,執行elasticsearch
plugin -install mobz/elasticsearch-head
具體實現時,編寫JAVA代碼建立索引index_name,建立索引類型index_type指定這個mapping的方法以下測試
//省略讀取mapping文件的java代碼,內容保存在mapping_json中。 Client client = new TransportClient().addTransportAddress(new InetSocketTransportAddress("127.0.0.1", 9300)); client.admin().indices().prepareCreate("index_name").execute().actionGet(); client.admin().indices().preparePutMapping("index_name").setType("index_type").setSource(mapping_json).execute().actionGet();