安装
写入
查询
查询与过滤
基础知识
Elasticsearch 使用的查询语言(DSL)拥有一套查询组件,这些组件可以以无限组合的方式进行搭配。这套组件可以在以下两种情况下使用:过滤情况(filtering context)和查询情况(query context)。
- 过滤情况
关键词:filter
使用过滤时,只关心一个问题,该文档是否匹配 - 查询情况
关键词:query
与过滤一样,也需要判断该文档是否匹配,同时还要判断文档的匹配程度。它会计算每个文档与该查询的相关程度,同时将这个相关性分配给表示相关性的字段_score,并根据_score排序,非常适用于全文检索。
Elasticsearch2.0之后,过滤(filters)已经在技术上被排除,
同时,所有的查询(queries)拥有变成不评分查询的能力。???
性能差异
- filter 只是简单的检查包含或排除,且会被缓存到内存,速度快
- query 不仅要找出匹配的文档,还要计算每个匹配文档的相关程度,结果也不缓存
选择
通常的规则是,使用查询(query)语句来进行 全文 搜索或者其它任何需要影响 相关性得分 的搜索。除此以外的情况都使用过滤(filters)。
查询关键字
-
match_all
匹配所有文档,为elasticsearch的默认查询
常与filter结合使用,如查询收件箱中的所有邮件,所有邮件被认为有相同的相关性,所以都将获得评分为1的中性_score -
match
无论你在任何字段上进行的是全文搜索还是精确查询,match 查询是你可用的标准查询。- 如果你在一个全文字段上使用 match 查询,在执行查询前,它将用正确的分析器去分析查询字符串:
- 如果在一个精确值的字段上使用它,例如数字、日期、布尔或者一个 not_analyzed 字符串字段,那么它将会精确匹配给定的值:
-
multi_match
可以在多个字段上执行相同的 match 查询
-
range
查询在指定区间内的数字或时间
gt 大于
lt 小于
gte 大于等于
lte 小于等于 -
term
被用于精确值匹配,这些精确值可能是数字、时间、布尔或者那些 not_analyzed 的字符串:
-
terms
和 term 查询一样,但它允许你指定多值进行匹配。如果这个字段包含了指定值中的任何一个值,那么这个文档满足条件:
-
exists
被用于查找那些指定字段中有值 (exists) 的文档。 -
missing
被用于查找那些指定字段中无值 (missing) 的文档。
组合多查询
bool 将多种查询条件组合成一个整体
- must 文档必须匹配这些条件
- must_not 文档必须不匹配这些条件
- should 如果满足这些语句中的任意语句,则增加_score,否则无影响。主要用于修正相关性得分
- filter 必须满足这些条件,但不参与评分(非全文检索时常用)
bool内部可以组合多种查询
而bool本身也可以嵌套到filter内部
constant_score查询
它将一个不变的常量评分应用于所有匹配的文档。它被经常用于你只需要执行一个 filter 而没有其它查询(例如,评分查询)的情况下。
实际应用
因为本身做的项目是将ES作为缓存使用,并不涉及全文检索的评分功能,所以最终组合出的查询条件如下:
{
"query": {
"constant_score": {
"filter": {
"bool": {
"must": [{
"term": {
"id": "123456"
}
}, {
"term": {
"billType": "sale"
}
}, {
"range": {
"billDate": {
"gte": 1614528000,
"lte": 1615392000
}
}
}, {
"term": {
"transType": "1111111"
}
}]
}
}
}
},
"sort": [
{
"contactName.keyword": {
"order": "desc"
}
}
]
}
详细官方文档 组合多查询官方文档
排序
默认情况下,返回的结果是按照 相关性 进行排序的——相关性最高的文档排在最前。
在 Elasticsearch 中, 相关性得分 由一个浮点数进行表示,并在搜索结果中通过 _score 参数返回, 默认排序是 _score 降序。
按照字段的值排序
可以简单的指定一个字段用于排序
“sort”: "id"
字段将会默认升序排序,而按_score降序排序
也可以指定排序方式
"sort": { "date": { "order": "desc" }}
此时,_score值不被计算,且不用于排序
结果数组会包含一个名为sort的元素,包含我们用于排序的值
多级排序
当需要根据多条件进行排序的时候,可以这么写
"sort": [
{ "date": { "order": "desc" }},
{ "_score": { "order": "desc" }}
]
排序条件的顺序是很重要的。结果首先按第一个条件排序,仅当结果集的第一个 sort 值完全相同时才会按照第二个条件进行排序,以此类推。
多级排序并不一定包含 _score 。可以根据一些不同的字段进行排序。
文本排序
文本排序会涉及到拆词和多字段等问题,具体查看官方文档 字符串排序与多字段
本人遇到的情况是需要使用text字段做排序,es对text字段,默认有一个keyword映射
因此,正如在组合多查询里的例子,我们可以直接使用contactName.keyword来做排序
"sort": [
{
"contactName.keyword ": {
"order": "desc"
}
}
]