假设文档有 title、content、author、type 四个字段,需求是在指定 type 中搜索关键词。这里实际上有两个条件:类别相等,以及文本相关性匹配。
先检查 mapping
假设 type 是 keyword,title、content、author 是 text,才可以使用下面的组合。若业务字段是分析过的 text,就不能直接把 term 当成原始字符串相等判断;存在 keyword 子字段时也要先确认真实名称和 normalizer。
GET /example_articles/_mapping
这里的 type 是普通业务字段,与旧版 Elasticsearch 的 mapping type 不是同一个概念。
类别放 filter,全文查询放 must
GET /example_articles/_search
{
"query": {
"bool": {
"filter": [
{ "term": { "type": "专题" } }
],
"must": [
{
"multi_match": {
"query": "集团",
"fields": ["title", "content", "author"]
}
}
]
}
}
}
filter 用于不参与评分的条件;must 中的全文查询参与评分。term 查询索引中的具体词项,match/multi_match 则按照相应字段和查询规则分析文本。ES 7.3 Term query、Bool query
嵌套多层 must 并不会把 match 自动变成精确相等。must 表示条件怎样组合,不会改写内部查询的分析语义。
“模糊搜索”不是一种统一操作
全文分词、任意子串、wildcard 通配符和 fuzziness 编辑距离容错,是不同需求。上面的例子是全文检索,并没有保证任意子串都命中,也没有开启拼写容错。
在自己的索引中,应结合 mapping、样本文档和分析结果检查大小写、中文分词、多值及缺失字段。若改变了索引期分析方式,也需要考虑已有文档是否要重建,不能只改请求就假定历史数据一起变化。