es查询语法
Searchtimeout
默认没有timeout,如果设置了timeout,name会执行timeout机制。
timeout机制:假设用户查询结果有1W条数据,但是需要10s才能查询完毕,但是用户设置了1s的timeout,name不管当前以供查询到了多少数据,都会在1s后ES将停止查询,并返回当前数据。
ES查询
- queryString查询
类似URL传参的形式
如
1 | GET /index/_search |
tips:
types removal specifying types in search requests is deprecated
7.X 还能用, 8.X已删除
为什么加了排序,没有相关度分数?
答:默认按照_score 排序,如果使用了sort 这个时候_score:null
- query DSL
如:
1 | //查询全部 match_all |
- Full-text queries 全文检索
- query-term:不会被分词
关键词作为一个完整的词,进行匹配查询 - match 和 term
- match 的关键词会被分词后进行匹配查询,
- term 的 关键词不会被分词,进行匹配查询
全文检索
1
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全文检索
GET /index/_search
{
"query":{
"term":{
"name":"xiaomi"
}
}
}
# term 关键词 不分词
GET /index/_search
{
"query":{
"bool":{
"must":[
{"term":{"name":"xiaomi"}},
{"term":{"name":"phone"}}
]
}
}
}
# name in("xiaomi", "phone")
GET /index/_search
{
"query":{
"terms":{
"name":["xiaomi","phone"]
}
}
}
# 默认分词器
GET /_analyze
{
"analyzer": "standard"
"test":"xiaomi nfc phone"
}
- query-term:不会被分词
GET 和 POST 也能查
- 短语搜索
1 | GET /index/_search |
- query and filter 查询和过滤
- bool: 可以组合多个查询条件,bool查询也是采用more_matches_is_batter的机制,因此满足must和should的字句的文档将会合并起来计算分值。
- must:必须满足
- filter:过滤器 不计算相关度分数的(性能比must高),支持缓存
- should: 可能满足 or
- must_not:必须不满足 不计算相关度分数的
- minimum_should_match: 默认 1 ,配置should 里面必须匹配的条件数量
- bool: 可以组合多个查询条件,bool查询也是采用more_matches_is_batter的机制,因此满足must和should的字句的文档将会合并起来计算分值。
1 | GET /index/_search |
- 嵌套查询
1 | GET /index/_search |
- 高亮查询
匹配到的结果 高亮返回
Deep paging 问题
size 500
index 11
如: 用户查询 50条 价格 由低到高的数据
数据在不同保证的分片上。5个分片
每个分片 1W
都去取 5050 全部拿出来,进行排序,在去取,排完序后取50条数据
- 数据大于1W ,不要使用
- 返回数据数量不要大于1W
解决方法:
- 尽量避免
- 使用scroll search
scroll search
scroll 游标
1m 开窗期:1分钟时间到了,就不能查询了
1 | GET /index/_search?scroll=1m |
会返回 scroll_id 标记 最后查询的位置
下一次查询,如下:
1 | GET /_search/scroll |
filter 缓存
- filter不是每次执行否会进行缓存,而是当执行一定次数的时候才会进行cache一个二进制数组,1表示匹配,2表示不匹配,这个次数是不固定的。
- filter会从有限过滤掉稀疏的数据中,保留匹配的cache数组。
- filter cache 保存的是匹配的结果,不需要再从倒排索引中去查找比对,大大涂改可查询速度,
- filter 一般会在query之前执行,过滤掉一部分数据,从而提高query的速度
- filter不计算相关度分数,在执行效率上比query高。
- 当元数据发生改变时,cache也会更新。
filter没有匹配度查询
mapping
概念:mapping 就是ES数据字段field的type元数据,ES在创建索引的时候,dynamic mapping会自动为不同的数据指定相应mapping,mapping中包含了字段的类型、搜索方式(exact value或者full text)、分词器等。
1 | PUT /index/_doc/100 |
1 | GET /product/_mapping/type(旧) |
如果 字段属性 类型是text ,会默认keyword 的type是keyword 关键词长度是256后忽视
Dynamic mapping
- “Elasticsearch” : text/keyword
- 123456 => long ? 为啥不是integer
- 123.123 => double
- true => boolean
- 2020-05-30 => date
为啥price是long类型而不是integer类型,因为es的mapping_type 是由json分析器检测数据类型,而json没有隐式类型转换(integer=>long or float => double),所以dynamic mapping 会选择比较宽的数据类型
搜索方式
- exact value 精确匹配: 在倒排索引过程中,分词器会将field作为一个整体创建到索引中,
注短语搜索:关键词作为整体匹配
full text 全文索引: 分词、近义词同义词、混淆词、大小写、过滤、时态转换等(normalzition)
exact value 类型字段 必须完全匹配 如:date 类型
string 的 text 是 full text,keyword 是 exact value
ES 数据类型
- 核心类型
- 数字类型
- long/integer/short/byte/float/half_foat/scaled_float
- 字符串:string
- keyword: 适用于索引结构化的字段,可以用于过滤、排序、聚合。keyword类型的字段只能通过精确值(exact value) 搜索到。如id应该用keyword
- text: 当一个字段是要被全恩搜索的,比如email内容、产品描述,这些字段应该使用text类型。设置text类型以后,字段内容会被分析,在生成倒排序索引以前,字符串会被分析器分恒一个一个词项。text类型的字段不用于排序,很少用于聚合。
- 有时,在同一个字段汇总同时具有全文和关键词版本会很有用,一个用于全文本搜索,另一个用于聚合和排序。
- date
- 布尔类型
- binary:二进制
- range(区间类型):integer_range/float_range/long_range/double_range/date_range
- 复杂类型
- object:用于单个JSON字符串
- Nested: 用于JSON字符串数组
- 地理位置
- 特有类型
- Array
- 数字类型
- 核心类型
创建mapping
1 | PUT /index |
索引、名字、字段 一律小写
- mapping parameters
- index:是否创建对当前字段创建索引,默认 true,如果不创建索引,该字段不会被通过这个字段检索数据。
- analyzer: 指定分析器(character filter、tokenizer、Token filter)
- coerce: 是否允许被强制类型转换
- bost:权重 默认1,权重
- copy_to:
- doc_value:为了提高排序和聚合效率,默认true。如果确定不需要对字段进行排序或聚合,也不需要通过脚本访问字段值,呢可以禁用doc值一节省磁盘空间(不支持text和annotated_text),如果不需要聚合查询,可以设置为false,提高查询效率,如果设置成false,不能再改了, 如果想改,只能重新创建索引。
- dynamic: 控制是否可以动态添加新字段
- true新检测到的字段将添加到映射中。(默认)
- false 新检测到的字段将被忽略,这些字段将不会被索引,因此将无法搜索,单人会出现在_source返回的匹配相中,这些字段不会添加到映射总,必须显示添加新字段。
- strict如果检测到新字段,则会引发异常并拒绝文档。必须将新字段显示添加到映射中。
- eager_global_ordinals: 用于集合的字段上,优化聚合性能。
- enable:是否创建倒排索引,可以对字段操作。
- fielddate:查询是内存数据结构,在首次用当前字段聚合、排序或者在脚本中使用时,需要字段为fielddata数据结构,并且创建正排索引保存到堆中。
- fields: 给filed创建多个字段,用于不同目的(全文检索或聚合分析排序)
- format: 格式化 如果date 的格式化
- norms: 是否禁用评分(filter和聚合字段上应该禁用)
- null_value: 为null 设置默认值
- search_analyzer: 单独设置查询时分析器
- similarity: 相关度算法。
- …(其他看官网)
聚合搜索
- bucket 和 metirc
- 语法
1
2
3aggs:{
} - “group by”:
{
}
1 | GET /index/_search |
- avg
1 | GET /index/_search |
- 分组查询
1 | GET /index/_search |