Query DSL
Elasticsearch 提供了一个完整的基于 JSON 的 Query DSL(Domain Specific Language)来定义查询,Query DSL 被视为查询的 AST(抽象语法树)。
基本查询
查询全部
SQL:
select * from account;
Query DSL:
// GET http://localhost:9200/account/_search
{
"query": {
"match_all": {}
}
}
查询指定字段
SQL:
select account_number, balance from account;
Query DSL:
{
"query": {
"match_all": {}
},
"_source": [
"account_number",
"balance"
]
}
count 查询
SQL:
select count(*) from account;
Query DSL:
// GET http://localhost:9200/account/_count
// 如果是查询表中的全部数据,那么可以省略请求体
{
"query": {
"match_all": {}
}
}
where 等值查询
SQL:
select * from account where age = 26;
Query DSL:
// GET http://localhost:9200/account/_search
{
"query": {
"term": {
"age": 26
}
// 使用 match 也可以,在小结部分会提到 term 和 match 的区别
// "match": {
// "age": 26
//}
// "match": {
// "age": "26"
//}
}
}
where 字符串等值查询
SQL:
select * from account where address = '990 Mill Road';
Query DSL:
// GET http://localhost:9200/account/_search
{
"query": {
"match": {
"address.keyword": "990 Mill Road" // 区分大小写
}
}
}
where like 模糊查询
SQL:
select * from account where address like '%mill road%';
Query DSL:
// GET http://localhost:9200/account/_search
{
"query": {
"match_phrase": {
"address": "mill road" // 不区分大小写
}
// 或者使用 wildcard
// {
// "query": {
// "wildcard": {
// "address.keyword": "*mill road*"
// }
// }
// }
}
}
where 多字段模糊查询
SQL:
select * from account where city like '%mill road%' or address like '%mill road%';
Query DSL:
// GET http://localhost:9200/account/_search
{
"query": {
"bool": {
"should": [
{
"match_phrase": {
"city": "mill road"
}
},
{
"match_phrase": {
"address": "mill road"
}
}
]
}
}
}
where 多字段等值查询
SQL:
select * from account where city = '990 Mill Road' or address = '990 Mill Road';
Query DSL:
// GET http://localhost:9200/account/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"city.keyword": "990 Mill Road"
}
},
{
"match": {
"address.keyword": "990 Mill Road"
}
}
]
}
}
}
Query DSL:
// GET http://localhost:9200/account/_search
{
"query": {
"multi_match": {
"query": "990 Mill Road",
"fields": ["city.keyword", "address.keyword"] // 不加 keyword 也可以,但是 query 会被分词
}
}
}
where in 查询
SQL:
select * from account where age in (26, 27);
Query DSL:
// GET http://localhost:9200/account/_search
{
"query": {
"terms": {
"age": [26, 27]
}
}
}
where 多条件查询
使用 bool 可以构造多个查询条件。
SQL:
select * from account where age = 26 and gender = 'M';
Query DSL:
// GET http://localhost:9200/account/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"age": 26
}
},
{
"match": {
"gender": "M"
}
}
]
}
}
}
**SQL:**
```sql
select * from account where age = 26 and gender = 'M' and state <> 'VT';
Query DSL:
// GET http://localhost:9200/account/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"age": 26
}
},
{
"match": {
"gender": "M"
}
}
],
"must_not": [
{
"match": {
"state": "VT"
}
}
]
}
}
}
where 范围查询
SQL:
select * from account where age > 26 and age < 30;
Query DSL:
// GET http://localhost:9200/account/_search
{
"query": {
"range": {
"age": {
"gt": 26,
"lt": 30
}
}
}
}
where between 查询
SQL:
select * from account where age between 26 and 30;
Query DSL:
// GET http://localhost:9200/account/_search
{
"query": {
"range": {
"age": {
"gte": 26,
"lte": 30
}
}
}
}
排序
SQL:
select * from account order by age desc;
Query DSL:
// GET http://localhost:9200/account/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"age": "desc"
}
]
// 等价于下面的写法
// "sort": [
// {
// "age": {
// "order": "desc"
// }
// }
// ]
}
SQL:
select * from account order by age desc, account_number asc;
Query DSL:
// GET http://localhost:9200/account/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"age": "desc"
},
{
"account_number": "asc"
}
]
}
分页
SQL:
select * from account limit 20;
Query DSL:
// GET http://localhost:9200/account/_search
{
"query": {
"match_all": {}
},
"from": 0, // from 可以省略,默认值为 0
"size": 20
}
SQL:
select * from account limit 10, 20;
Query DSL:
// GET http://localhost:9200/account/_search
{
"query": {
"match_all": {}
},
"from": 10,
"size": 20
}
复合查询
Boolean 查询
bool 查询使用一个或多个 bool 子句(子句也就是查询条件)构建,每个子句都有一类条件。条件类型如下:
| 类型 | 描述 |
|---|---|
must | 文档必须匹配的条件,否则文档将被排除在结果之外。must 会记录相关性得分。 |
filter | 文档必须匹配的条件。然而,与 must 不同的是,查询的分数将被忽略。filter 子句在 filter context 中执行,这意味着将忽略评分,并考虑将查询条件用于缓存。 |
should | 文档应该匹配子句,不匹配也可以。如果 should 里面的条件被匹配上了,那么会增加文档的相关性得分。需要注意的是,should 并不参与查询条件的过滤,它只影响文档的相关性得分。 |
must_not | 文档必须不匹配子句,否则文档将被排除在结果之外。must_not 最终会被转化为 filter,并在在 filter context 中执行,这意味着忽略评分,并考虑子句进行缓存。因为忽略了分数,所以返回所有文档的分数为0。 |
bool 查询采用“匹配越多越好”的方法,因此每个匹配 must 或 should 子句的分数将被加在一起,以提供每个文档的最终 _score。
minimum_should_match
您可以使用 minimum_should_match 参数指定返回的文档必须匹配的 should 子句的数量或百分比。
如果 bool 查询包含至少一个 should 子句和 must_not 或 filter 子句,则 minimum_should_match 默认值为 1。否则,默认值为 0。
其他有效值请参见参数 minimum_should_match。
小结:
- 在上面的查询示例中,我使用的是 GET 方式。其实,Elasticsearch 还支持 POST 方式,只需要将查询条件放在请求体中即可。在使用 Elasticsearch 的 API 时,我们可以根据自己的习惯来选择使用 GET 还是 POST 方式。
- 默认情况下,ES 只会在
hits.hits中返回查询到的前 10 条数据,如果想要返回全部数据,可以使用size参数来指定返回的数据条数。 term用于精确匹配,对于不需要分词的字段(例如金额、年龄等),如果我们想精确匹配,一般使用term查询。match用于模糊匹配,对于需要分词的字段,可以使用match查询。