例如:
PUT /music { "mappings": { "children": { "properties": { "name": { "type": "text", "analyzer": "ik_max_word" }, "content": { "type": "text", "analyzer": "ik_max_word", "term_vector" : "with_positions_offsets" } } } } }一般情况下,用plain highlight也就足够了,不需要做其他额外的设置
如果对高亮的性能要求很高,可以尝试启用unified highlight
如果field的值特别大,超过了1M,那么可以用fast vector highlight
我们知道高亮的默认标签是<em>,这个标签可以自己定义的,然后使用自己喜欢的样式:
GET /music/children/_search { "query": { "match": { "content": "Love" } }, "highlight": { "pre_tags": ["<tag1>"], "post_tags": ["</tag2>"], "fields": { "content": { "type": "plain" } } } } 高亮片段fragment的设置针对一些很长的文本,我们不可能在页面上完整显示的,我们需要只显示有关键词的上下文即可,这里设置fragment就行:
GET /_search { "query" : { "match": { "content": "friend" } }, "highlight" : { "fields" : { "content" : {"fragment_size" : 150, "number_of_fragments" : 3, "no_match_size": 150 } } } }fragment_size: 设置要显示出来的fragment文本判断的长度,默认是100。
number_of_fragments:你可能你的高亮的fragment文本片段有多个片段,你可以指定就显示几个片段。
地理位置现在基于地理位置的app层出不穷,支持地理位置的组件也有不少,Elasticsearch也不例外,并且ES可以把地理位置、全文搜索、结构化搜索和分析结合到一起,我们来看一下。
geo point数据类型Elasticsearch基于地理位置的搜索,有一个专门的对象geo_point存储地理位置信息(经度,纬度),并且提供了一些基本的查询方法,如geo_bounding_box。
建立geo_point类型的mapping
PUT /location { "mappings": { "hotels": { "properties": { "location": { "type": "geo_point" }, "content": { "type": "text" } } } } } 插入数据推荐使用如下插入数据方式:
#latitude:维度,longitude:经度 PUT /location/hotels/1 { "content":"7days hotel", "location": { "lon": 113.928619, "lat": 22.528091 } }还有两种插入数据的方式,但特别容易搞混经纬度的位置,所以不是很推荐:
# location中括号内,前一个是经度,后一个是纬度 PUT /location/hotels/2 { "content":"7days hotel ", "location": [113.923567,22.523988] } # location中,前一个是纬度,后一个是经度 PUT /location/hotels/3 { "text": "7days hotel Orient Sunseed Hotel", "location": "22.521184, 113.914578" } 查询方法geo_bounding_box查询,查询某个矩形的地理位置范围内的坐标点
GET /location/hotels/_search { "query": { "geo_bounding_box": { "location": { "top_left":{ "lon": 112, "lat": 23 }, "bottom_right":{ "lon": 114, "lat": 21 } } } } } 常见查询场景 geo_bounding_box方式 GET /location/hotels/_search { "query": { "bool": { "must": [ {"match_all": {}} ], "filter": { "geo_bounding_box": { "location": { "top_left":{ "lon": 112, "lat": 23 }, "bottom_right":{ "lon": 114, "lat": 21 } } } } } } } geo_polygon方式,三个点组成的多边形(三角形)区域支持多边形,只是这个过滤器使用代价很大,尽量少用。
GET /location/hotels/_search { "query": { "bool": { "must": [ {"match_all": {}} ], "filter": { "geo_polygon": { "location": { "points": [ {"lon": 115,"lat": 23}, {"lon": 113,"lat": 25}, {"lon": 112,"lat": 21} ] } } } } } } geo_distance方式根据当前位置的距离进行搜索,非常实用
GET /location/hotels/_search { "query": { "bool": { "must": [ {"match_all": {}} ], "filter": { "geo_distance": { "distance": 500, "location": { "lon": 113.911231, "lat": 22.523375 } } } } } } 按距离排序根据当前位置进行条件搜索,会指定一个距离的上限,2km或5km,并且符合条件查询的结果显示与当前位置的距离(可以指定单位),并且按从近到远排序,这个是非常常用的场景。
请求示例:
GET /location/hotels/_search { "query": { "bool": { "must": [ {"match_all": {}} ], "filter": { "geo_distance": { "distance": 2000, "location": { "lon": 113.911231, "lat": 22.523375 } } } } }, "sort": [ { "_geo_distance": { "location": { "lon": 113.911231, "lat": 22.523375 }, "order": "asc", "unit": "m", "distance_type": "plane" } } ] }filter.geo_distance.distance: 最大的距离,这里是2000m
_geo_distance: 固定写法,下面为指定位置的经纬度
order: 排序方式,asc或desc
unit: 距离的单位,m/km都行
distance_type: 计算距离的方式,sloppy_arc (默认值), arc (精准的) and plane (最快速的)
响应如下:
"hits": [ { "_index": "location", "_type": "hotels", "_id": "3", "_score": null, "_source": { "text": "7days hotel Orient Sunseed Hotel", "location": "22.521184, 113.914578" }, "sort": [ 421.35435857277366 ] }, { "_index": "location", "_type": "hotels", "_id": "2", "_score": null, "_source": { "content": "7days hotel", "location": [ 113.923567, 22.523988 ] }, "sort": [ 1268.8952707727062 ] }sort里面的内容,就是与当前位置的地面距离,单位是m。
统计我当前位置几个范围内酒店的数量unit表示距离单位,常用的是mi和km。