精准查询:Term-Level Query
概念
官方把我们本小节所述的知识点,也就是精准查询称之为术语级查询,术语指的就是词项,简单来说,术语就是在全文检索中的最小粒度文本,而术语级查询,其实指的就是不可分词的查询类型。即有明确查询条件边界的查询。如:范围查询、词项查询等。
Term 查询一般用于如: Id、姓名、价格等不需要分词的字段。
Term Query
基本逻辑
和 match query 相比,term query 不会对搜索词分词,而且会保留搜索词原有的所有属性,如大小写、标点符号等。
数据类型
通常来说,term query 和 keyword 列举宽 [他不分词字段亦可。
term query | match query | match_phrase | |
---|---|---|---|
字段类型 | 不分词(如:keyword) | 分词(如:text) | 分词(如:text) |
搜索场景 | 精确匹配 | 全文检索 | 全文检索 |
语法
GET <index>/_search
{
"query": {
"term": {
"<keyword_field_name>" : "<field_value>"
}
}
}
term 与 keyword
term | keyword | |
---|---|---|
参数类型 | 查询函数 | 字段类型 |
是否分词 | 否 | 否 |
作用范围 | 搜索词 | 源字段 |
特殊情况
在match query中有一种情况是不符合上述所说的搜索逻辑的,即match发生完美匹配的时候。
如:当使用match去匹配不分词字段的时候,假如存在如下文档:
在上述文档中,name的类型为text,如果按照以下代码执行:
GET products/_search
{
"query": {
"match": {
"name.keyword":"华为"
}
}
}
Terms Query
语法语义
Terms 和 Term 的区别就在于 Terms 是同时匹配多个词项。
{
"query": {
"terms": {
"<field_name>": [ "<value1>", "<value2>" ]
}
}
}
示例
查询products索引中包含标签 续航 、性价比的所有文档
GET products/_search
{
"query": {
"terms": {
"tags.keyword": [
"续航",
"性价比"
]
}
}
}
范围查找 Range Query
GET /_search
{
"query": {
"range" : {
"age" : {
"gte" : 10,
"lte":20,
"boost" : 2.0
}
}
}
}
可选参数
参数 | 英文翻译 | 含义 |
---|---|---|
gt | greater than | 大于 |
gte | greater than or equal | 大于或等于 |
lt | less than | 小于 |
lte | less than or equal | 小于或等于 |
布尔查询:Boolean Query
概述
概念
**bool:**可以组合多个查询条件,bool 查询也是采用 more_matches_is_better 的机制,因此满足 must 和 should 子句的文档将会合并起来计算分值
bool query: 多用于多条件组合查询
语法
GET index/_search
{
"query": {
"bool": {
"boost":1,
"minimum_should_match":1,//至少满足条件多少
"filter": [ //(必须符合每条件
{条件一},
{条件二}
],
"must": [ //必须符合每条件
{条件一},
{条件二}
],
"must_not": [//必须不满足每个条件
{条件一},
{条件二}
],
"should": [//可以满足其中若干条件或全部不满足
{条件一},
{条件二}
]
}
}
}
查询子句
must 子句
计算相关度得分
多个条件必须同时满足
{
"must": {
"where": [
{"brand": "华为"},
{"price": "> 5000"}
]
}
}
filter 子句
过滤器 cache☆子句(查询)必须出现在匹配的文档中。但是不像 must 会计算评分,使用 filter 查询的评分将被忽略,并且结果会被缓存。
注:
不计算相关度分数
会被缓存
{
"query": {
"bool": {
"filter": [
{"match": { "type": "phone"}},
{"range": { "price": "< 20000"}}
]
}
},
"_source": false
}
Should 子句
可能满足 or 子句(查询)应出现在匹配的文档中。
{
"query": {
"bool": {
"should": [
{"match": { "type": "phone"}},
{"match": { "price": "< 20000"}},
{"match":{"name":"华为"}}
]
}
},
"_source": false
}
Must_not 子句
子句中出现的每个条件都不能满足,并且不计算相关度评分。
{
"query": {
"bool": {
"must_not": [
{"match": { "type": "phone"}},
{"match": { "price": "< 20000"}},
{"match":{"name":"华为"}}
]
}
},
"_source": false
}
组合查询
语义关系
当多个子句同时出现时,多个子句之间的逻辑关系为AND,即需要同时满足。如,当同时出现must [case1, case2]和 must_not[case3, case4]时,其语义为:必须同时满足case1和case2,且必须同时不满足case3、case4
示例
当filter 和must一起使用时,filter发挥的作用是对数据的过滤,这个过程不计算评分,而must则会对数据进行评分。经过了 filter 的过滤之后,需要评分的文档数量将降低,从而提升了查询效率。
原则上,能用 filer 的尽量用 filer。
GET index/_search
{
"_source": false,
"query": {
"bool": {
"filter": [
{
"range": {
"price": {
"gte": "5000"
}
}
}
],
"must": [
{
"match": {
"name": "phone"
}
}
]
}
}
}
minimum_should_match参数
第一语义
minimum_should_match参数用来指定should返回的文档必须匹配的条件数量或百分比,如果bool查询包含至少一个should子句,而没有must或filter子句,则默认值为1。
# 条件1: name中包含“phone”
# 当未设置minimum_should_match参数时,多个条件的关系为OR
# 条件2: type等于"phone"
第二语义但是如果bool查询中同级子句中出现了must或者filter子句,则minimum_should_match的默认值将变为0。
#(must或者filter)和should组合
# 条件1:价格小于20000
# 条件2:name中包含“phone”或者type等于“phone”
子查询嵌套
GET index/_search
{
"_source": false,
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{"match": { "type": "phone"}},
{"match": { "price": "< 20000"}},
{"match":{"name":"华为"}}
]
}
}
]
}
}
}