文章目录
DSL(Domain Specific Language)查询
DSL查询是Elasticsearch 提供的一个完整的基于 JSON 的查询。其分为两大类:
- 普通查询:如match、term、range等
- 复合查询:可以以多个普通查询组合的方式进行查询。
查询接口
GET /<target>/_search
GET /_search
POST /<target>/_search
POST /_search
target:索引名称,可以为 * 或者多个用逗号隔开的索引名称
exists 查询字段是否存在
{
"_source":{
"excludes":["remark"]
},
"query": {
"exists": {
"field":"aaa"
}
}
}
field 表示要查询的字段
- 如果 JSON 值为null或[],则字段被视为不存在
- 如果是包含null值的数组[null,aaa]或空字符串""则表示该字段存在。
执行结果
{
"took": 267, // 查询花费时间,单位毫秒
"timed_out": false, // 是否超时
"_shards": { // 分片信息
"total": 3, // 分片总数
"successful": 3, // 成功数
"skipped": 0, // 跳过(忽略)数
"failed": 0 // 失败数
},
"hits": { // 命中结果对象
"total": { // 按条件匹配的文档数
"value": 3, // 文档数
"relation": "eq" //eq 表示计数准确, gte 表示计数不准确
},
"max_score": 1, // 匹配度分值,一般为0~1
"hits": [// 命中的结果列表
]
}
}
fuzzy 模糊查询
{
"_source":{
"excludes":["remark"]
},
"query": {
"fuzzy": {
"name": {
"value": "钱军",
"fuzziness": 1,
"max_expansions": 50,
"prefix_length": 0,
"transpositions": true,
"rewrite": "constant_score"
}
}
}
}
此查询将会把name中包含“钱”和“军”的都查询出来。
编辑距离
编辑距离是将一个术语变成另一个术语所需的一个字符更改的数量。这些变化可以包括:
- 改变一个字符(b ox → f ox)
- 删除一个字符(b lack → lack)
- 插入一个字符 (sic → sic k )
- 调换两个相邻字符 ( act → cat t)
参数说明
- <field>:要搜索的字段,示例为 name
- value
(必需,字符串)您希望在提供的. - fuzziness
(可选,字符串)允许匹配的最大编辑距离。- 0…2
必须完全匹配 - 3…5
允许一次编辑 - > 5
允许两次编辑 - AUTO
首选值应该使用AUTO 等同于3,6
- 0…2
- max_expansions
(可选,整数)创建的最大变体数。默认为50。建议不要太大,否则影响效率。 - prefix_length
(可选,整数)创建扩展时保持不变的起始字符数。默认为0. - transpositions
(可选,布尔值)指示编辑是否包括两个相邻字符的换位 (ab → ba)。默认为true. - rewrite
(可选,字符串)用于重写查询的方法。rewrite参数有很多可选值,建议使用constant_score、 constant_score_boolean或top_terms_boost_N即可。默认为constant_score。
- value
通过_id列表查询
{
"_source":{
"excludes":["remark"]
},
"query": {
"ids": {
"values": ["507","699","567"]
}
}
}
此示例查询索引 _id 为 “507”,“699”,“567” 的文档数据。
prefix 前缀查询
{
"_source":{
"excludes":["remark"]
},
"query": {
"prefix": {
"name": {
"value":"周"
}
}
}
}
此示例查询name字段,以“周”开头的文档。
参数说明
- <field>:要搜索的字段,示例为 name
- value
(必需,字符串)查询参数 - rewrite
(可选,字符串)用于重写查询的方法。 - case_insensitive
(可选,布尔值)设置为 true 时允许不区分大小写的值与索引字段值匹配。默认为 false,区分大小写。
- value
range 范围查询
{
"_source":{
"excludes":["remark"]
},
"query": {
"range": {
"age": {
"gte":23,
"lte":24
}
}
}
}
此示例为查询age在[23,24]之间的文档。
参数说明
- <field>:要搜索的字段,示例为 name
- gt
(可选)大于。 - gte
(可选)大于或等于。 - lt
(可选)小于。 - lte
(可选)小于或等于。 - format
(可选,字符串)用于转换date查询中值的日期格式。 - relation
(可选,字符串)指示范围查询如何匹配字段值range 。有效值为:- INTERSECTS(默认)
匹配范围字段值与查询范围相交的文档。 - CONTAINS
匹配具有完全包含查询范围的范围字段值的文档。 - WITHIN
匹配范围字段值完全在查询范围内的文档。
- INTERSECTS(默认)
- time_zone
(可选,字符串) 用于将查询中的值转换为 UTC的协调世界时 (UTC) 偏移量。有效值为 ISO 8601 UTC 偏移量,例如+01:00或 -08:00和 IANA 时区 ID,例如America/Los_Angeles。如果使用 now 则始终是 UTC 中的当前系统时间 - boost
(可选,float)浮点数,用于减少或增加 查询的相关性分数。默认为1.0。0和之间的提升值 1.0会降低相关性得分。大于的值1.0 会增加相关性分数。
- gt
日期计算
计算格式
- +1h: 加一小时
- -1d: 减去一天
- /d:四舍五入到最近的一天
格式 | 说明 |
---|---|
y | 年 |
M | 月 |
w | 周 |
d | 天 |
h | 小时 |
H | 小时 |
m | 分钟 |
s | 秒 |
假设now是2001-01-01 12:00:00,那么
now+1h:now以毫秒加一小时为单位。结果:2001-01-01 13:00:00
now-1h:now以毫秒减一小时为单位。结果:2001-01-01 11:00:00
now-1h/d:now以毫秒减一小时为单位,四舍五入。结果:2001-01-01 00:00:00
2001.02.01\|\|+1M/d:2001-02-01以毫秒加一个月为单位。结果:2001-03-01 00:00:00
# 2001.02.01视为字符串,后面需要跟 ||,此处使用了 \ 斜线来转义
比如:查询生日在1988.11.30日之前的文档信息
{
"_source":{
"excludes":["remark"]
},
"query": {
"range": {
"birthday": {
"lte":"1988.11.30",
"format":"yyyy.MM.dd"
}
}
}
}
查询当前时间之前1个月以前出生的人的文档
{
"_source":{
"excludes":["remark"]
},
"query": {
"range": {
"birthday": {
"lte":"now-1M"
}
}
}
}
Regexp 正则表达式查询
正则表达式规则
表达式 | 说明 | 示例 |
---|---|---|
. | 匹配任何字符 | ab. 匹配 abc,abb、abd等 |
? | 重复一次或0次 | ab? 匹配 ab,abc,abb等 |
+ | 重复前一个表达式或字符一次或多次 | ab+ 匹配 abddd,abc,abbaaa等 |
* | 重复前一个表达式或字符0次或多次 | ab* 匹配 a,ab,abc,abb等 |
{} | 前面的字符可以重复的最小和最大次数 | a{2} # 匹配 ‘aa’ a{2,4} # 匹配 ‘aa’、‘aaa’ 和 ‘aaaa’ a{2,} # 匹配 'a` 重复两次或更多次 |
| | 或运算符 | abc|xyz # 匹配 ‘abc’ 和 ‘xyz’ |
() | 组合,将()内的字符视为一个整体 | abc(def)? # 匹配 ‘abc’ 和’abcdef’ 但不匹配 ‘abcd’ |
[] | 将[]内的字符视为一个占位字符 | [abc] # 匹配 ‘a’, ‘b’, ‘c’ [a-c] # 匹配 ‘a’、‘b’ 或 ‘c’ [-abc] # ‘-’ 是第一个字符。匹配 ‘-’、‘a’、‘b’ 或 ‘c’ [abc\-] # 转义 ‘-’。匹配 ‘a’、‘b’、‘c’ 或 ‘-’ |
^ | 非运算符,常和[]一起使用 | [^abc] # 匹配除 ‘a’、‘b’ 或 ‘c’ 之外的任何字符 [^ac] # 匹配除 ‘a’、‘b’ 或 ‘c’ 之外的任何字符 [^-abc] # 匹配任何字符character except ‘-’, ‘a’, ‘b’, or ‘c’ [^abc-] # 匹配除 ‘a’, ‘b’, ‘c’, or ‘-’ 之外的任何字符 |
注:Lucene 的正则表达式引擎不支持锚运算符,例如 ^(行首)或$(行尾)。
查询示例
{
"_source":{
"excludes":["remark"]
},
"query": {
"regexp": {
"name": {
"value": ".+军"
}
}
}
}
示例查询以“军”字结尾的姓名
regexp 查询参数
- <field>:要搜索的字段,示例为 name
- value:(必需,字符串)标准的正则表达式
- case_insensitive:(可选,布尔值)当设置为 true 时,允许正则表达式值与索引字段值进行不区分大小写的匹配。默认为 false。
- flags
(可选,字符串)为正则表达式启用可选运算符,默认为 ALL。 - rewrite
(可选,字符串)用于重写查询的方法。
term 精确查询
{
"_source":{
"excludes":["remark"]
},
"query": {
"term": {
"name": {
"value": "钱军"
}
}
}
}
查询参数
- <field>:要搜索的字段,示例为 name
- value
(必需,字符串)查询参数内容 - boost
(可选,float)浮点数,用于减少或增加 查询的相关性分数。默认为1.0。小于1减少,大于1增加相关性分数。 - case_insensitive:(可选,布尔值)当设置为 true 时,允许正则表达式值与索引字段值进行不区分大小写的匹配。默认为 false。
- value
注:term 查询主要用于精确查询,不会经过文本分析(分析器分析),所以我们应该尽量避免使用term查询text类型的字段。
terms 多关键字精确匹配
{
"_source":{
"excludes":["remark"]
},
"query": {
"terms": {
"name": ["钱军","钱艳"]
}
}
}
示例匹配name值为“钱军”和“钱艳”的文档
参数说明
- <field>:要搜索的字段,示例为name
- boost:(可选,float)浮点数,用于减少或增加 查询的相关性分数。默认为1.0。小于1减少,大于1增加相关性分数。
wildcard 通配符查询
{
"_source":{
"excludes":["remark"]
},
"query": {
"wildcard": {
"name": {
"value" : "钱*"
}
}
}
}
参数说明
- <field>:要搜索的字段,示例为name
- value
(必需,字符串)通配符表达式( 只支持两种通配符 “?”和“*” ) - boost:(可选,float)浮点数,用于减少或增加 查询的相关性分数。默认为1.0。小于1减少,大于1增加相关性分数。
- case_insensitive:(可选,布尔值)当设置为 true 时,允许正则表达式值与索引字段值进行不区分大小写的匹配。默认为 false。
- rewrite
(可选,字符串)用于重写查询的方法。
- value
match_all 匹配所有
GET /_search
{
"query": {
"match_all": {}
}
}
执行结果
{
"took": 267, // 查询花费时间,单位毫秒
"timed_out": false, // 是否超时
"_shards": { // 分片信息
"total": 3, // 分片总数
"successful": 3, // 成功数
"skipped": 0, // 跳过(忽略)数
"failed": 0 // 失败数
},
"hits": { // 命中结果对象
"total": { // 按条件匹配的文档数
"value": 3, // 文档数
"relation": "eq" //eq 表示计数准确, gte 表示计数不准确
},
"max_score": 1, // 匹配度分值,一般为0~1
"hits": [// 命中的结果列表
{
"_index": "person",
"_id": "1",
"_score": 1,
"_source": {
"id": 1,
"name": "张三",
"age": 18,
"height": 1.75,
"birthday": "1988-09-10 00:00:00",
"sex": 1
}
},
{
"_index": "person1",
"_id": "1",
"_score": 1,
"_source": {
"id": 1,
"name": "张三",
"age": 18,
"height": 1.75,
"birthday": "1988-09-10 00:00:00",
"sex": 1
}
},
{
"_index": "users",
"_id": "1",
"_score": 1,
"_source": {
"id": 1,
"name": "嬴政",
"age": 2300,
"desc": "中国历史上第一位皇帝"
}
}
]
}
}
使用boost设置匹配度分值
分值可以设置为1以上,以达到完全匹配
GET /_search
{
"query": {
"match_all": { "boost" : 1.2 }
}
}
执行结果
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 3,
"successful": 3,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 3,
"relation": "eq"
},
"max_score": 1.2,
"hits": [
{
"_index": "person",
"_id": "1",
"_score": 1.2,
"_source": {
"id": 1,
"name": "张三",
"age": 18,
"height": 1.75,
"birthday": "1988-09-10 00:00:00",
"sex": 1
}
},
{
"_index": "person1",
"_id": "1",
"_score": 1.2,
"_source": {
"id": 1,
"name": "张三",
"age": 18,
"height": 1.75,
"birthday": "1988-09-10 00:00:00",
"sex": 1
}
},
{
"_index": "users",
"_id": "1",
"_score": 1.2,
"_source": {
"id": 1,
"name": "嬴政",
"age": 2300,
"desc": "中国历史上第一位皇帝"
}
}
]
}
}
match_none 完全不匹配
match_none 表示不匹配任何文档。类似于 myslq 中的 select * from dual。
GET /_search
{
"query": {
"match_none": {}
}
}
执行结果
{
"took": 39,
"timed_out": false,
"_shards": {
"total": 3,
"successful": 3,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 0,
"relation": "eq"
},
"max_score": null,
"hits": []
}
}
以上我们是全库查询,如果要对某个索引进行查询,在 /_search 前添加路径参数索引名称。
GET /{index}/_search
math 匹配查询
示例
GET /person/_search
{
"query": {
"match": {
"name": {
"query":"万娟"
}
}
}
}
上面示例等价于
{
"query": {
"match": {
"name": "万娟"
}
}
}
当前匹配查询匹配索引person,中 name属性等于 "万娟"的数据。
注:我们的name字段类型为keyword,此时我们只输入万,将不会有数据。但如果name字段为text类型,其会经过解析器分词,输入“万”将会出现包含万字的数据。
参数说明
- <field>:要搜索的字段,示例为 name
- query
(必填)查询的内容 - analyzer
(可选,字符串)设置查询时的文本分析器,如果没有映射分析器,则使用索引的默认分析器。 - auto_generate_synonyms_phrase_query
(可选,布尔值)如果true, 将自动为多术语同义词创建匹配短语查询。默认为true. - fuzziness
(可选,字符串)允许匹配的最大编辑距离。 - max_expansions
(可选,整数)查询将扩展到的最大术语数。默认为50. - prefix_length
(可选,整数)模糊匹配保留不变的起始字符数。默认为0. - fuzzy_transpositions
(可选,布尔值)如果true,模糊匹配的编辑包括两个相邻字符的换位 (ab → ba)。默认为true. - fuzzy_rewrite
(可选,字符串)用于重写查询的方法。如果fuzziness参数不是0,则查询默认match使用fuzzy_rewrite 方法 - lenient
(可选,布尔值)如果true,则忽略基于格式的错误,默认为false. - operator
(可选,字符串)- OR: capital of Hungary被解释为capital OR of OR Hungary。默认为OR
- AND: capital of Hungary被解释为capital AND of AND Hungary。
- query
match_phrase_prefix
匹配前缀,列如我们要查询姓钱的Person。但match_phrase_prefix只与词组的开头进行匹配,如text类型的数据,在分词之后有一个词语为 “中国”,那么输入“中”,可以匹配,但输入“国”,则不能匹配
{
"_source":{
"excludes":["remark"]
},
"query": {
"match_bool_prefix": {
"name": {
"query": "钱"
}
}
}
}
multi_match
多字段匹配
{
"query": {
"multi_match": {
"query":"万军",
"fields": ["name^3","*_name","remark"]
}
}
}
fields 指定多个字段进行匹配,name^3 表示将name字段的分数乘以3,提升字段name的匹配度,*_name * 是通配符。注意:中文我们目前还没有提到分词器,所以此处的查询结果还不一定准确。
combined_fields
组合字段,和 multi_match 的作用大致一样。combined_fields 不能作用于 keyword 字段。
query_string
{
"_source":{
"excludes":["remark"]
},
"query": {
"query_string": {
"query":"(万军) OR (钱艳)",
"default_field": "name"
}
}
}
script 脚本查询
{
"_source":{
"excludes":["remark"]
},
"query": {
"script": {
"script": {
"source": "doc['age'].value > 20 && doc['sex'].value == 1",
"lang": "painless"
}
}
}
}
示例为:查询 年龄大于20,sex为1的文档。查询过滤这里的脚本返回值应该为布尔值,否则是会报错的。
此处涉及到 脚本的一些语法知识,这些知识我们将在后面的章节单独讲解。
结果
{
"took": 16,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 387,
"relation": "eq"
},
"max_score": 1.0,
"hits": [
{
"_index": "person",
"_id": "5",
"_score": 1.0,
"_source": {
"id": 6,
"name": "戴刚",
"age": 23,
"height": 1.82,
"birthday": "2010-08-07 03:46:28",
"sex": 1
}
},
{
"_index": "person",
"_id": "273",
"_score": 1.0,
"_source": {
"id": 274,
"name": "龙娜",
"age": 33,
"height": 1.26,
"birthday": "2007-05-26 12:06:33",
"sex": 1
}
},
{
"_index": "person",
"_id": "287",
"_score": 1.0,
"_source": {
"id": 288,
"name": "易娜",
"age": 45,
"height": 1.47,
"birthday": "1983-11-27 10:35:25",
"sex": 1
}
},
{
"_index": "person",
"_id": "293",
"_score": 1.0,
"_source": {
"id": 294,
"name": "常超",
"age": 25,
"height": 1.39,
"birthday": "2019-01-16 16:20:09",
"sex": 1
}
},
{
"_index": "person",
"_id": "303",
"_score": 1.0,
"_source": {
"id": 304,
"name": "卢勇",
"age": 34,
"height": 1.88,
"birthday": "1987-08-22 06:58:30",
"sex": 1
}
},
{
"_index": "person",
"_id": "313",
"_score": 1.0,
"_source": {
"id": 314,
"name": "秦强",
"age": 29,
"height": 1.17,
"birthday": "2007-10-30 23:54:14",
"sex": 1
}
},
{
"_index": "person",
"_id": "315",
"_score": 1.0,
"_source": {
"id": 316,
"name": "阎霞",
"age": 25,
"height": 1.22,
"birthday": "1999-05-07 19:21:01",
"sex": 1
}
},
{
"_index": "person",
"_id": "317",
"_score": 1.0,
"_source": {
"id": 318,
"name": "董涛",
"age": 48,
"height": 1.94,
"birthday": "1979-08-24 18:26:16",
"sex": 1
}
},
{
"_index": "person",
"_id": "319",
"_score": 1.0,
"_source": {
"id": 320,
"name": "戴杰",
"age": 24,
"height": 1.53,
"birthday": "2008-07-19 04:20:41",
"sex": 1
}
},
{
"_index": "person",
"_id": "329",
"_score": 1.0,
"_source": {
"id": 330,
"name": "谭秀英",
"age": 43,
"height": 1.35,
"birthday": "1981-10-24 09:40:27",
"sex": 1
}
}
]
}
}