ES默认是动态创建索引和索引类型的mapping的。这就相当于无需定义Solr中的Schema,无需指定各个字段的索引规则就可以索引文件,很方便。但有时方便就代表着不灵活。比如,ES默认一个字段是要做分词的,但我们有时要搜索匹配整个字段却不行。如有统计工作要记录每个城市出现的次数。对于NAME字段,若记录“new york”文本,ES可能会把它拆分成“new”和“york”这两个词,分别计算这个两个单词的次数,而不是我们期望的“new york”。
这时,就需要我们在创建索引时定义mapping。假设索引叫index_name,索引类型的名字叫index_type,编写mapping文件如下(注意:mapping文件中,index_type必须与实际索引当中的索引类型完全一致。):
{
"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方式的请求编写如下:
{
"query": {
"match_all": {}
},
"aggregations": {
"cityAggs": {
"terms": {
"field": "NAME.raw"
}
}
}
}