搜索 Query DSL
字数: 0 字 时长: 0 分钟
查询和检索
查询和检索尽管有时会被互换使用,但它们实际上有着不同的含义和技术背景。
- 查询:通常针对结构化的数据,基于某些条件进行精确匹配或者范围筛选
- 检索:指从大量的文档、网页、文件或其他非结构化或半结构化的数据集合中找到相关数据的过程。召回结果取决于
相关性
。
相关度评分 _score
_source
是搜索结果中每个文档的相关性评分,用于衡量文档与搜索条件的匹配程度,得分越高,文档与查询越相关。
在 ES 早期版本中,使用 TF-IDF 算法, ES 5.* 版本之后采用 BM25 算法。
- 查看
_score
细节
json
GET goods/_search
{
"explain": true,
"query": {
"match": {
"name": "手机"
}
}
}
- 设置权重
boost
json
GET goods/_search
{
"query": {
"match": {
"name": {
"query": "手机",
// 设置该字段权重为其他字段的 2 倍
"boost": 2
}
}
}
}
源数据 _source
- 通过
including
或excluding
来设置查询出的源数据中包含哪些数据
json
GET goods2/_search
{
"_source": {
"includes": ["name","price"],
"excludes": "description"
}
}
- 使用通配符来设置查询出的源数据中包含哪些数据
json
GET goods/_search
{
"_source": ["n*"]
}
- 关闭源数据展示
json
GET goods/_search
{
"_source": false,
"query": {
"match": {
"name": "手机"
}
}
}
全文检索
match
match 查询是 ES 中最常用的查询方式,它基于全文检索算法,也是 ES 中最重要的查询方式。
比如,通过 "手机" 查询,所有分词词项包含 "手机" 相关的文档都会被检索出来。
json
GET goods/_search
{
"query": {
"match": {
"name": "手机"
}
}
}
{
"_index": "goods",
"_id": "1",
"_score": 0.50392604,
"_source": {
"name": "手机",
"price": 2000,
"description": "手机"
}
},
{
"_index": "goods",
"_id": "3",
"_score": 0.3034693,
"_source": {
"name": "小米智能手机",
"price": 2000,
"description": "小米手机真智能"
}
},
{
"_index": "goods",
"_id": "4",
"_score": 0.3034693,
"_source": {
"name": "智能手机小米",
"price": 2000,
"description": "智能手机选小米"
}
}
match_all
检索所有文档
match_phrase
match_phrase
查询,基于全文检索算法,可以精确匹配短语。
比如,当查询条件为 "小米手机" 时
match
: 会将结果中包含 “小米” 和 “手机” 的文档都返回match_phrase
: 只会返回包含 “小米手机” 的文档
匹配规则
- 会分词: 首先先将 "小米手机" 分词为 "小米" 和 "手机"
- 必须全部匹配且顺序必须相同 : 检索文档必须包含 "小米" 和 "手机" ,顺序必须相同
- slop 距离:允许在检索文档中,有 slop 个词项的误差,默认为 0
精确查询 Term Query
与 match 查询相比 term 查询不会对搜索词进行分词,而且会保留搜索词的完整属性,比如带小写、标定符号等。
一般来说,term 查询适用于 keyword 之类的不需要分词的字段。
注意, term 只是保证搜索词不分词,文档字段是否分词与 term 无关
json
//文档字段 name 被分词成了 小米 与 手机 两个词项,此时不会命中
GET goods/_search
{
"query": {
"term": {
"name" : "小米手机"
}
}
}
完美匹配
json
PUT goods2/_doc/7
{
"name":"XiaoMi 900"
}
//此时 match 会对搜索词分词为 xiaomi 和 900 两个词项
//而 name.keyword不会分词,按理说不会命中
//但这里是特殊情况,搜索词和字段内容完全一样,称为完美匹配,会命中
GET goods2/_search
{
"query": {
"match": {
"name.keyword": "XiaoMi 900"
}
}
}
Terms 查询
terms 查询可以一次查询多个 term,性能比多次查询性能高。
json
GET goods2/_search
{
"query": {
"terms": {
"name.keyword": [
"华为",
"小米"
]
}
}
}
范围查找 Range Query
- gte : 大于等于
- gt : 大于
- lte : 小于等于
- lt : 小于
json
GET goods/_search
{
"query": {
"range": {
"price": {
"gte": 1000,
"lte": 3000
}
}
}
}
组合查询 (布尔查询) bool Query
bool 查询可以组合多个查询条件,有多个子句
must 子句
- must 子句表示多个条件必须同时满足
- 会计算相关度得分
json
GET goods/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "小米"
}
},
{
"range": {
"price": {
"gte": 10
}
}
}
]
}
}
}
filter 子句
- 与 must 子句不同,filter 子句不会计算相关度得分,性能更高,能用 filer 都用 filter
- 结果会被缓存
should 子句
- 查询条件不需要全部满足,是
or
的关系 - 会计算相关度得分
minimum_should_match
参数可以指定查询条件至少满足几个才命中,默认为 1- 注意,当
should
子句与must
或filter
子句一起使用时,should
子句的minimum_should_match
默认值变为 0
must_not 子句
- 查询条件都不能被满足
- 不会计算相关度得分