Elasticsearch-高级用法
# 经纬度
# 定义
在 Elasticsearch 中,可以将经纬度信息作为 Geo Point 类型存储在文档中。
定义文档映射时,需要指定字段为Geo Point类型:
{
"mappings": {
"properties": {
"location": {
"type": "geo_point"
}
}
}
}
2
3
4
5
6
7
8
9
当我们存储数据时,经纬度可以用两种方式表示:
数组方式:第一个元素是经度,第二个元素是纬度
{
"location": [120.123, 30.456]
}
2
3
对象方式:lon字段表示经度,lat字段表示纬度
{
"location": {
"lon": 120.123,
"lat": 30.456
}
}
2
3
4
5
6
或者
{
"location": {
"longtitude": 120.123,
"latitude": 30.456
}
}
2
3
4
5
6
# 查询
纬度的取值范围为 -90 ~ 90。赤道为0度,北半球为北纬(+),南半球为南纬(-)。
经度的取值范围为-180 ~ 180。一般以英国为0度。东半球为东经(+),西半球为西经(-)。
# Geo Bounding Box
作用:查找位于指定边界框内的所有点。需要提供一个矩形区域的左上角和右下角坐标
{
"query": {
"geo_bounding_box": {
"location": {
"top_left": {
"lat": 72.51,
"lon": 13.37
},
"bottom_right": {
"lat": 12.49,
"lon": 173.39
}
}
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Geo Distance
作用:查找距离指定点在一定范围内的所有点。需要提供一个中心点和最大距离(单位可以是米、千米、英里或英尺)。
{
"query": {
"geo_distance": {
"distance": "10km",
"location": {
"lat": 52.52,
"lon": 13.38
}
}
}
}
2
3
4
5
6
7
8
9
10
11
# Geo Polygon
作用:查找位于多边形内的所有点。需要提供一个由多个点组成的多边形。
{
"query": {
"geo_polygon": {
"location": {
"points": [
[121, 31], [121, 32], [122, 32], [122, 31]
]
}
}
}
}
2
3
4
5
6
7
8
9
10
11
# Geo Shape
作用:查找与指定几何形状相交的点。你可以使用多种几何形状,如点、线、多边形等。
{
"query": {
"geo_shape": {
"location": {
"shape": {
"type": "polygon",
"coordinates": [
[
[13.37, 52.51],
[13.37, 52.53],
[13.39, 52.53],
[13.39, 52.51],
[13.37, 52.51]
]
]
}
}
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# copy_to
作用:opy_to
是 Elasticsearch 中的一个映射(mapping)选项,它允许你将一个或多个字段的值复制到另一个字段。
映射定义:
{
"mappings": {
"properties": {
"first_name": {
"type": "text",
"copy_to": "full_name"
},
"last_name": {
"type": "text",
"copy_to": "full_name"
},
"full_name": {
"type": "text"
}
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 自动补全
准备工作
- 下载elasticsearch;
- 下载elasticsearch对应版本的插件:
- 将插件解压,并放到下载elasticsearch的插件目录下(/elasticsearch-7.15.0/plugins);
unzip elasticsearch-analysis-ik-7.15.0.zip -d ik # 解压文件,并将内容防止到 ik 目录下(不存在则创建) mv ik elasticsearch-7.15.0/plugins/
1
2 - 重启elasticsearch;
定义索引时,进行自动补全配置
PUT http://192.168.1.6:9200/my_idx
Content-Type: application/json
{
"settings": {
"analysis": {
"analyzer": {
"king_word": {
"tokenizer": "ik_max_word",
"filter": [
"custom_pinyin_filter"
]
},
"king_completion": {
"tokenizer": "keyword",
"filter": "custom_pinyin_filter"
}
},
"filter": {
"custom_pinyin_filter": {
"type": "pinyin",
"keep_joined_full_pinyin": true,
"keep_original": true,
"remove_duplicated_term": true,
"none_chinese_pinyin_tokenize": false
}
}
}
},
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "king_word",
"search_analyzer": "ik_max_word"
},
"name": {
"type": "completion",
"analyzer": "king_completion"
}
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
创建倒排索引时:
{
"id": 1,
"name": "柿子"
}
{
"id": 2,
"name": "狮子"
}
2
3
4
5
6
7
8
9
10
11
假设es中使用用自定义分词器分词后这两个索引在数据库中保存的格式为:
词条 | 文档编号 |
---|---|
狮子 | 1 |
sz | 1,2 |
shizi | 1,2 |
柿子 | 2 |
当用户进行搜索时输入: “我去动物园看狮子” 后发现,柿子也被搜索到了。
原因是es 会对输入内容进行分词,分词中包含狮子,运用拼音过滤器 后生成了(sz,shizi,狮子),导致同时将 狮子和 sz 的倒排索引同时查找出来,结果就是搜索的内容同时包含 柿子。
解决:
在进行索引映射时,我们需要同时指定2个analyzer,格式如下:
{
"mappings": {
"properties": {
"name": {
"type": "text",
"analyzer": "king_word",
"search_analyzer": "ik_smart"
}
}
}
}
2
3
4
5
6
7
8
9
10
11
创建索引时,我们需要生产(sz,shizi,狮子)对应的词条,但是在搜索时,我们需要按照用户输入的内容进行搜索,而不进行扩展。
定义自动补全字段
{
"mappings": {
"properties": {
"title": {
"type": "completion"
}
}
}
}
2
3
4
5
6
7
8
9
设置补全数据
POST hotel/_doc
{
"title": ["r", "rj"]
}
2
3
4
5
自动补全查询
GET /hotel/_search
{
"suggest": {
"title_suggest": {
"text": "s" //关键字,搜索前缀
"completion": {
"field": "title",
"skip_duplicates": true, // 跳过重复
"size": 10
}
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
引入pinyin分词器插件
拼音分词器: