多字符串多字段查询
在ES中,Query Context 和Filter Context 是两种不同的上下文,其主要区别在于
- Query Context 会进行相关性算分
- Filter Context,不会进行相关性算分,性能更好
在ES中如果要进行复杂的查询,那么可以使用bool Query
bool 查询
一个bool查询是一个或者多个查询子句的组合
bool查询总共包含4种子句
子句类型 | 备注 |
must | 必须满足该条件。结果会贡献算分 |
should | 至少有一个满足条件。结果会贡献算分 |
must_not | 必须不满足该条件。属于Filter Context查询子句,结果不会算分 |
filter | 必须满足该条件。属于Filter Context查询子句,结果不会算分 |
算分,就是计算相关性。并不只是全文本检索才特有的,在yes或者no的子句中,匹配的子句越多,相关性评分就越高。如果多条查询子句被合并为一条符合查询语句,比如bool查询,则每个查询子句计算得出的评分会被合并到总的相关性评分中。
示例:
POST /products/_search
{
"query": {
"bool" : {
"must" : {
"term" : { "price" : "30" }
},
"filter": {
"term" : { "avaliable" : "true" }
},
"must_not" : {
"range" : {
"price" : { "lte" : 10 }
}
},
"should" : [
{ "term" : { "productID.keyword" : "JODL-X-1937-#pV7" } },
{ "term" : { "productID.keyword" : "XHDK-A-1293-#fJ3" } }
],
"minimum_should_tch" :1
}
}
}
意为:必须满足 price=30 并且avaliable=true 并且 price>10 或 productID ="JODL-X-1937-#pV7"或者 productID =“XHDK-A-1293-#fJ3”
bool查询中的子查询的顺序没有限制,且可以在子查询中嵌套多个子查询,如果bool查询中没有must条件,那么should中必须至少满足一条查询
bool查询语句的结构对算分的影响
bool查询语句的结构是会影响相关性算分的。
例如
//示例1
POST /animals/_search
{
"query": {
"bool": {
"should": [
{ "term": { "text": "brown" }},
{ "term": { "text": "red" }},
{ "term": { "text": "quick" }},
{ "term": { "text": "dog" }}
]
}
}
}
//示例2
POST /animals/_search
{
"query": {
"bool": {
"should": [
{ "term": { "text": "quick" }},
{ "term": { "text": "dog" }},
{
"bool":{
"should":[
{ "term": { "text": "brown" }},
{ "term": { "text": "brown" }},
]
}
}
]
}
}
}
示例1中,所有子句在同一层级下,则具有相同的权重
示例2,同示例一虽然是一个意思,但是子句的权重不一致,通过这种嵌套的bool查询,可以改变对算分的影响
通过boost字段控制相关度算分
boost参数的含义
- 当boost > 1时,打分的相关度会相对性提升
- 当0 < boost < 1时,打分的权重相对性降低
- 当 boost < 0 时, 贡献负分
示例
DELETE blogs
POST /blogs/_bulk
{ "index": { "_id": 1 }}
{"title":"Apple iPad", "content":"Apple iPad,Apple iPad" }
{ "index": { "_id": 2 }}
{"title":"Apple iPad,Apple iPad", "content":"Apple iPad" }
POST blogs/_search
{
"query": {
"bool": {
"should": [
{"match": {
"title": {
"query": "apple,ipad",
"boost": 1.1
}
}},
{"match": {
"content": {
"query": "apple,ipad",
"boost":
}
}}
]
}
}
}
解决包含而不是相等的问题
在我们 电影 索引中,有一个 genre字段,这个字段是数组,包含了多个数据,但是es中并没有数组类型,我们在查询时可能会出现这样的情况
可以看到,包含了同样关键字的数据都被查询了出来,所以索引设计上,我们需要增加一个字段,genre_count,对genre字段的数量进行统计。在查询时,使用复合查询,即可解决该问题