跳到主要内容

ES搜索与查询

查询上下文

查询结果说明:

GET product/_search
{
"query": {
"match_all": {}
}
}

{
"took": 17, // 这次请求消耗了多少时间(毫秒)
"timed_out": false, // 当前请求是否超时
"_shards": { // 当前请求的分片
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 4, // 当前请求查询到了5条结果
"relation": "eq" // 当前查询的关系是等于
},
"max_score": 1, // 当前最大的评分
"hits": [ // 当前返回的结果
{
"_index": "product", // 索引
"_id": "1", // 当前数据的id
"_score": 1, // 当前数据的评分
"_source": { // 源数据
"name": "Xiaomi",
"desc": "小米手机",
"price": 3999,
"tags": [
"leijun",
"xingjiabi",
"fashao"
]
}
},
// ...
]
}
}

使用query关键字进行检索,倾向于相关度搜索,故需要计算评分。

相关度评分用于对搜索结果排序,评分越高则认为其结果和搜索的预期值相关度越高,即越符合搜索预期值。在7.x之前,相关度评分默认使用TF/IDF算法计算而来,7.x之后默认为BM25

相关度评分为搜索结果的排序依据, 默认情况下评分越高则结果越靠前。

源数据:_source

禁用_source

GET product/_search
{
"_source": false,
"query": {
"match_all": {}
}
}

好处:节省存储开销

坏处:

  • 不支持updateupdate_by_queryreindex API
  • 不支持高亮
  • 不支持reindex、更改mapping分析器和版本升级
  • 通过查看索引时使用的原始文档来调试查询或聚合的功能
  • 将来可能自动修复索引损坏

如果只是为了节省磁盘,可以压缩索引比禁用_source更好。

数据源过滤器

mapping中定义过滤,支持通配符:

PUT product
{
"mappings": {
"_source": {
"includes": ["name", "price"],
"excludes": ["desc", "tags"]
}
}
}

includes:结果中返回哪些field

excludes:结果中不返回哪些field。不返回的field不代表不能通过该字段进行检索,因为源数据不存在不代表索引不存在。excludes优先级比includes高。

不推荐在mapping中定义过滤,因为mapping不可变。

常用过滤规则:

"_source": false,
"_source": "obj.*", // 支持通配符
"_source": ["obj1.*", "obj2.*"],
"_source": {
"includes": ["obj1.*", "obj2.*"],
"excludes": ["*.description"]
}

QueryString

// 查询所有
GET product/_search

// 带参数
GET product/_search?q=name:xiaomi

// 分页
GET product/_search?from=0&size=2&sort=price:asc

// 精准匹配
GET product/_search?q=date:2021-06-01

// _all搜索,相当于在所有有索引的字段中检索
GET product/_search?q=2021-06-01

全文检索:match

match:匹配包含某个term的子句

match_all:匹配所有结果的子句

multi_match:多字段条件

match_phrase:短语查询

精准查询:term

term:匹配和搜索词项完全相等的结果

termmatch_phrase区别:

  • match_phrase会将检索关键词分词,match_phrase的分词结果必须在被检索字段的分词中都包含,而且顺序必须相同,而且默认必须都是连续的
  • term搜索不会将搜索词分词

termkeyword区别:

  • term是对于搜索词不分词
  • keyword是字段类型,是对于source data中的字段值不分词

terms:匹配和搜索词项列表中任意匹配的结果

range:范围查找

过滤器:filter

filter与query的区别:

  • query对查询的每一个结果计算相关度得分
  • filter不计算相关度评分,filter的结果不按照某个字段进行排序,因此性能更好
  • filter还有缓存机制
GET product/_search
{
"query": {
"constant_score": {
"filter": {
"term": {
"name": "phone"
}
},
"boost": 1.2
}
}
}

组合查询:boolquery

bool:可以组合多个查询条件,bool查询也是采用more_matches_is_better的机制,因此满足mustshould子句的文档将会合并起来计算分值。

must:必须满足子句(查询)必须出现在匹配的文档中,并将有助于得分。

filter:过滤器。不计算相关度分数,cache★子句(查询)必须出现在匹配的文档中,但是不像must,查询的分数将被忽略。filter子句在filter上下文中执行,这意味着计分将被忽略,并且子句被考虑用于缓存。

should:可能满足 or子句(查询)应出现在匹配的文档中

must_not:必须不满足 不计算相关度分数 not子句(查询)不得出现在匹配的文档中。子句在过滤器上下文中执行,这意味着计分被忽略,并且子句被视为用于缓存。

minimum_should_match:参数指定should返回的文档必须匹配的子句的数量或百分比。如果bool查询包含至少一个should子句,而没有mustfilter子句,则默认值为1,否则默认值为0。