笔记二十:Query & Filtering 与 多字符串多字段查询
Query Context & Filter Context
- 高级搜索的功能,支持多想文本输入,针对多个字段进行搜索
- 搜索引擎一般也提供时间,价格等条件过滤
- 在ES中,有
Query
和Filter
两种Context
- Query Context :相关性算分
- Filter Context :不需要算分(YES OR NO),可以利用Cache 获得更好的性能
条件组合
- 假设搜索一本电影
- 评论中包含了Guitar ,用户打分高于3分,同时上映时间在1993到2000年之间
- 这个搜索包含了3段逻辑,针对不同的字段
- 评论字段中要包含Guitar 、用户评论大于3、上映时间日期在给定范围内
- 同时包含这三个逻辑,并且有比较好的性能
- 复合查询: bool Query
bool 查询
- 一个bool查询,是一个或者多个查询子句的组合
- 总共包含4种子句,其中2种会影响算分,2种不影响算分
- 相关性并不只是全文本搜索的专利。也适合 yes | no 的子句,匹配的子句越多,相关性评分越高。如果多条查询子句被合并为一条复合查询语句,比如bool查询,则每个查询子句计算得出的评分会被合并到总的相关性评分中。
bool 查询语句
- 子查询可以任意顺序出现
- 可以嵌套多个查询
- 如果你的bool 查询中,没有must条件,should 中必须满足一条查询
//插入数据 POST /products/_bulk {"index":{"_id":1}} {"price":10,"avaliable":true,"date":"2018-01-01","productID":"XHDK-A-1293-#fJ3"} {"index":{"_id":2}} {"price":20,"avaliable":true,"date":"2019-01-01","productID":"KDKE-B-9947-#kL5"} {"index":{"_id":3}} {"price":30,"avaliable":true,"productID":"JODL-X-1937-#pV7"} {"index":{"_id":4}} {"price":30,"avaliable":false,"productID":"QQPX-R-3956-#aD8"} //查询 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_match": 1 } } }
如何解决结构化查询-“包含而不是相等”的问题
增加count字段,使用bool查询
- 从业务角度,按需改进数据模型
POST /newmovies/_bulk {"index":{"_id":1}} {"title":"Father of the Bridge Part II","year":1995,"genre":"Comedy","genre_count":1} {"index":{"_id":2}} {"title":"Dave","year":1993,"genre":["Comedy","Romance"],"genre_count":2} # must 有算分 POST /newmovies/_search { "query": { "bool": { "must": [ {"term": {"genre.keyword": {"value": "Comedy"}}}, {"term": {"genre_count": {"value": 1}}} ] } } } #Filter。不参与算分,结果的score是0 POST /newmovies/_search { "query": { "bool": { "filter": [ {"term": {"genre.keyword": {"value": "Comedy"}}}, {"term": {"genre_count": {"value": 1}}} ] } } }
Filter Context - 不影响算分
Query Context - 影响算分
POST /products/_search
{
"query": {
"bool": {
"should": [
{
"term": {
"productID.keyword": {
"value": "JODL-X-1937-#pV7"}}
},
{"term": {"avaliable": {"value": true}}
}
]
}
}
}
// 算分
"hits" : {
"total" : {
"value" : 3,
"relation" : "eq"
},
"max_score" : 1.5606477, //算分的
"hits" : [
{
"_index" : "products",
"_type" : "_doc",
"_id" : "3",
"_score" : 1.5606477,
"_source" : {
"price" : 30,
"avaliable" : true,
"productID" : "JODL-X-1937-#pV7"
}
},
{
"_index" : "products",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.35667494,
"_source" : {
"price" : 10,
"avaliable" : true,
"date" : "2018-01-01",
"productID" : "XHDK-A-1293-#fJ3"
}
},
{
"_index" : "products",
"_type" : "_doc",
"_id" : "2",
"_score" : 0.35667494,
"_source" : {
"price" : 20,
"avaliable" : true,
"date" : "2019-01-01",
"productID" : "KDKE-B-9947-#kL5"
}
}
]
}
bool 嵌套
查询语句的结构,会对相关度算分产生影响
- 同一层级下的竞争字段,具有相同的权重
- 通过嵌套bool查询,可以改变对算分的影响
控制字段的Boosting
- Boosting 是控制相关度的一种手段
- 索引,字段或查询子条件
- 参数boost的含义
- 当 boost > 1
- 当 0 < boost < 1
- 当 boost < 0
Not Quite Not
Boosting Query
知识点回顾
- Query Context vs Filter Context
- Bool Query - 更多的条件组合
- 查询结构与相关性算分
- 如何控制查询的精确度
- Boosting & Boosting Query
本作品采用《CC 协议》,转载必须注明作者和本文链接