1.搜索模板
搜索模板,search template,高级功能,就可以将我们的一些搜索进行模板化,然后每次执行这个搜索,就直接调用模板,给传入一些参数就可以了。
1)template入门案例
GET /cars/_search/template
{
"source": {
"query": {
"match": {
"remark": "{{kw}}"
}
},
"size": "{{size}}"
},
"params": {
"kw": "大众",
"size": 2
}
}
toJson方式传递参数
GET cars/_search/template
{
"source": "{ \"query\": { \"match\": {{#toJson}}parameter{{/toJson}} }}",
"params": {
"parameter" : {
"remark" : "大众"
}
}
}
join方式传递参数
GET cars/_search/template
{
"source": {
"query": {
"match": {
"remark": "{{#join delimiter=' '}}kw{{/join delimiter=' '}}"
}
}
},
"params": {
"kw": [
"大众",
"标致"
]
}
}
default value 定义
GET cars/_search/template
{
"source": {
"query": {
"range": {
"price": {
"gte": "{{start}}",
"lte": "{{end}}{{^end}}200000{{/end}}"
}
}
}
},
"params": {
"start": 100000
}
}
2)记录template实现重复调用
可以使用Mustache语言作为搜索请求的预处理,它提供了模板,然后通过键值对来替换模板中的变量。把脚本存储在本地磁盘中,默认的位置为:elasticsearch\config\scripts,通过引用脚本名称进行使用
2.1)保存template到ES
POST _scripts/test
{
"script": {
"lang": "mustache",
"source": {
"query": {
"match": {
"remark": "{{kw}}"
}
}
}
}
}
2.2)调用template执行搜索
GET cars/_search/template
{
"id": "test",
"params": {
"kw": "大众"
}
}
2.3)查询已定义的template
GET _scripts/test
2.4)删除已定义的template
DELETE _scripts/test
2.搜索建议 suggest search(completion suggest)
suggest search(completion suggest):就是建议搜索或称为搜索建议,也可以叫做自动完成-auto completion。类似百度中的搜索联想提示功能。ES实现suggest的时候,性能非常高,其构建的不是倒排索引,也不是正排索引,就是纯的用于进行前缀搜索的一种特殊的数据结构,而且会全部放在内存中,所以suggest search进行的前缀搜索提示,性能是非常高。需要使用suggest的时候,必须在定义index时,为其mapping指定开启suggest。具体如下:
PUT /movie
{
"mappings": {
"properties": {
"title": {
"type": "text",
"fields": {
"suggest": {
"type": "completion"
}
}
},
"content": {
"type": "text"
}
}
}
}
PUT /movie/_doc/1
{
"title": "西游记电影系列",
"content": "西游记之月光宝盒将与2021年进行......"
}
PUT /movie/_doc/2
{
"title": "西游记文学系列",
"content": "某知名网络小说作家已经完成了大话西游同名小说的出版"
}
PUT /movie/_doc/3
{
"title": "西游记之大话西游手游",
"content": "网易游戏近日出品了大话西游经典IP的手游,正在火爆内测中"
}
suggest 搜索
GET /movie/_search
{
"suggest": {
"mySuggest": {
"prefix": "西游记",
"completion": {
"field": "title.suggest"
}
}
}
}
3.地理位置搜索
ES支持地理位置的搜索和聚合分析,可实现在指定区域内搜索数据、搜索指定地点附近的数据、聚合分析指定地点附近的数据等操作。
ES中如果使用地理位置搜索的话,必须提供一个特殊的字段类型。GEO - geo_point。地理位置的坐标点。
1)定义geo point mapping
如果需要使用地址坐标,则需要定义一个指定的mapping类型。具体如下:
使用什么数据可以确定,地球上的一个具体的点?经纬度。
PUT /hotel_app
{
"mappings": {
"properties": {
"pin": {
"type": "geo_point"
},
"name": {
"type": "text"
}
}
}
}
2)录入数据
新增一个基于geo point类型的数据,可以使用多种方式。
多种类型描述geo_point类型字段的时候,在搜索数据的时候,显示的格式和录入的格式是统一的。不影响搜索。任何数据描述的geo_point类型字段,都适用地理位置搜索。
数据范围要求:纬度范围是-90~90之间,经度范围是-180~180之间。经纬度数据都是浮点数或数字串(数字组成的字符串),最大精度:小数点后7位。(常用小数点后6位即可。)
基于对象:latitude:纬度、longitude:经度。语义清晰,建议使用。
PUT /hotel_app/_doc/1
{
"name": "七天连锁酒店",
"pin": {
"lat": 40.12,
"lon": -71.34
}
}
基于字符串和数组:依次定义纬度、经度。不推荐使用
PUT /hotel_app/_doc/2
{
"name": "维多利亚大酒店",
"pin": "40.99, -70.81"
}
PUT /hotel_app/_doc/3
{
"name": " 红树林宾馆",
"pin": [
40,
-73.81
]
}
3)搜索指定区域范围内的数据
矩形范围搜索:传入的top_left和bottom_right坐标点是有固定要求的。地图中以北作为top,南作为bottom,西作为left,东作为right。也就是top_left应该从西北向东南。Bottom_right应该从东南向西北。Top_left的纬度应该大于bottom_right的纬度,top_left的经度应该小于bottom_right的经度。
GET /hotel_app/_search
{
"query": {
"bool": {
"filter": [
{
"geo_bounding_box": {
"pin": {
"top_left": {
"lat": 41.73,
"lon": -74.1
},
"bottom_right": {
"lat": 40.01,
"lon": -70.12
}
}
}
}
]
}
}
}
GET /hotel_app/_search
{
"query": {
"constant_score": {
"filter": {
"geo_bounding_box": {
"pin": {
"top_left": {
"lat": -70,
"lon": 39
},
"bottom_right": {
"lat": -75,
"lon": 41
}
}
}
}
}
}
}
GET /hotel_app/_search
{
"query": {
"geo_bounding_box": {
"pin": {
"top_left": {
"lat": 41.73,
"lon": -74.1
},
"bottom_right": {
"lat": 40.01,
"lon": -70.12
}
}
}
}
}
多边形范围搜索:对传入的若干点的坐标顺序没有任何的要求。只要传入若干地理位置坐标点,即可形成多边形。
GET /hotel_app/_search
{
"query": {
"bool": {
"filter": {
"geo_polygon": {
"pin": {
"points": [
{
"lat": 40.73,
"lon": -74.1
},
{
"lat": 40.01,
"lon": -71.12
},
{
"lat": 50.56,
"lon": -90.58
}
]
}
}
}
}
}
}
4)搜索某地点附近的数据
这个搜索在项目中更加常用。类似附近搜索功能。Distance距离的单位,常用的有米(m)和千米(km)。建议使用filter来过滤geo_point数据。因为geo_point数据相关度评分计算比较耗时。使用query来搜索geo_point数据效率相对会慢一些。建议使用filter。
GET /hotel_app/_doc/_search
{
"query": {
"bool": {
"filter": {
"geo_distance": {
"distance": "200km",
"pin": {
"lat": 40,
"lon": -70
}
}
}
}
}
}
GET hotel_app/_search
{
"query": {
"geo_distance": {
"distance": "90km",
"pin": {
"lat": 40.55,
"lon": -71.12
}
}
}
}
5)统计某位置附近区域内的数据
聚合统计分别距离某位置80英里,300英里,1000英里范围内的数据数量。
其中 unit 是距离单位,常用单位有:米(m),千米(km),英里(mi)
distance_type 是统计算法:sloppy_arc 默认算法、arc 最高精度、plane 最高效率
GET /hotel_app/_doc/_search
{
"size": 0,
"aggs": {
"agg_by_pin": {
"geo_distance": {
"distance_type": "arc",
"field": "pin",
"origin": {
"lat": 40,
"lon": -70
},
"unit": "mi",
"ranges": [
{
"to": 80
},
{
"from": 80,
"to": 300
},
{
"from": 300,
"to": 1000
}
]
}
}
}
}