目录
es搜索排序是es的高级特性之一,也是我们需求中经常遇到的问题,今天我们详细分析一下,废话少数,马上开始:
一、相关性排序
1、TF-IDF模型、向量空间模型、BM25算法简介、分布式场景对排序的影响。这些都是比较大的课题,后期我们会一个个专题分享。
二、查询时设置权重
- 查询时 boost参数的设置
boost 值得设置只限定在term 和match ,默认值是1,当设置的大于1起正向作用,设置0-1起负向作用;
1.1 、默认设置
GET /nandao_scenic/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"title": {
"query": "河南"
}
}
},
{
"match": {
"title": {
"query": "山西"
}
}
}
]
}
}
}
1.2、设置自定义
GET /nandao_scenic/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"title": {
"query": "河南",
"boost": 3
}
}
},
{
"match": {
"title": {
"query": "山西"
}
}
}
]
}
}
}
1.3、java客户端展示
public void getBoostSearch() {
SearchRequest searchRequest = new SearchRequest("nandao_scenic");//创建搜索请求
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//构建"金都"的match查询
MatchQueryBuilder matchQueryBuilder1 = QueryBuilders.matchQuery("title", "河南");
//设置boost值为2
matchQueryBuilder1.boost(2);
//构建"文雅"的match查询,boost使用默认值
MatchQueryBuilder matchQueryBuilder2 = QueryBuilders.matchQuery("title", "山西");
BoolQueryBuilder boolQueryBuilder=QueryBuilders.boolQuery();
//将"金都"的match查询添加到布尔查询
boolQueryBuilder.should(matchQueryBuilder1);
//将"文雅"的match查询添加到布尔查询
boolQueryBuilder.should(matchQueryBuilder2);
searchSourceBuilder.query(boolQueryBuilder);//设置查询为布尔查询
searchRequest.source(searchSourceBuilder);//设置查询请求
printResult(searchRequest);//打印搜索结果
}
- boosting 参数的设置
此参数可以设置 range条件的查询,同时分为两部分查询,positive查询,代表正向查询;另一部分是negetive 查询,代表负向查询;
2.1、单个参数设置
GET /nandao_scenic/_search
{
"query": {
"boosting": {
"positive": {
"match": {
"title": {
"query": "山"
}
}
},
"negative": {
"range": {
"price": {
"lte": 20
}
}
},
"negative_boost": 0.2
}
}
}
2.2、多个参数设置
GET /nandao_scenic/_search
{
"query": {
"boosting": {
"positive": {
"match": {
"title": {
"query": "山"
}
}
},
"negative": {
"bool": {
"should": [
{
"range": {
"price": {
"lte": 200
}
}
},
{
"term": {
"FIELD": {
"value": "true"
}
}
}
]
}
},
"negative_boost": 0.2
}
}
}
2.3、java客户端处理
public void getBoostingSearch() {
SearchRequest searchRequest = new SearchRequest("nandao_scenic");//创建搜索请求
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//构建"金都"的match查询
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "河南");
//构建价格的range查询
QueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("price").lte("200");
//构建满房的term查询
QueryBuilder termQueryBuilder = QueryBuilders.termQuery("full_room",true);
BoolQueryBuilder boolQueryBuilder=QueryBuilders.boolQuery();
//将价格的range查询添加到布尔查询
boolQueryBuilder.should(rangeQueryBuilder);
//将满房的term查询添加到布尔查询
boolQueryBuilder.should(termQueryBuilder);
//构建boosting查询,match查询作为正向查询,布尔查询作为负向查询
BoostingQueryBuilder boosting=QueryBuilders.boostingQuery(matchQueryBuilder,boolQueryBuilder);
boosting.negativeBoost(0.2f);//设置负向查询的系数
searchSourceBuilder.query(boosting);//设置查询为boosting查询
searchRequest.source(searchSourceBuilder);//设置查询请求
printResult(searchRequest);//打印搜索结果
}
三、Function Score 查询简介
1、简单函数
2、函数计算关系
3、衰减函数
四、Script Score 查询简介
1、Painless 简介
2、在 Script Score 中使用Painless
3、使用数组和集合
4、使用文档数据
5、向脚本传参
6、Script Score 中使用函数
7、java客户端使用 Script Score
public void getScriptScoreQuery() {
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "山西");
//编写脚本代码
String scoreScript =
"int weight=10;\n" +
"def random= randomScore(params.uuidHash);\n" +
" return weight*random;";
Map paraMap = new HashMap();
paraMap.put("uuidHash", 234537);//设置传递到脚本的参数
//创建脚本对象
Script script = new Script(Script.DEFAULT_SCRIPT_TYPE, "painless", scoreScript, paraMap);
//创建ScriptScore查询builder
ScriptScoreQueryBuilder scriptScoreQueryBuilder = QueryBuilders.scriptScoreQuery(matchQueryBuilder, script);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(scriptScoreQueryBuilder);
SearchRequest searchRequest = new SearchRequest("nandao_scenic");//创建搜索请求
searchRequest.source(searchSourceBuilder);//设置查询请求
printResult(searchRequest);//打印搜索结果
}
五、二次打分
1、仅设置二次打分
GET /nandao_scenic/_search
{
"query": {
"range": {
"price": {
"gte": 30
}
}
},
"rescore": {
"query": {
"rescore_query":{
"match":{
"title":"五台山"
}
}
},
"window_size": 5
}
}
2、设置二次打分权重
GET /nandao_scenic/_search
{
"query": {
"range": {
"price": {
"gte": 30
}
}
},
"rescore": {
"query": {
"rescore_query":{
"match":{
"title":"五台山"
}
},
"query_weight": 0.6,
"rescore_query_weight":1.7
},
"window_size": 5
}
}
3、java客户端展示
public void getRescoreQuery(){
//构建原始的range查询
QueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("price").gte("300");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(rangeQueryBuilder);//添加原始查询Builder
//构建二次打分的查询
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "山西");
//构建二次打分Builder
QueryRescorerBuilder queryRescorerBuilder = new QueryRescorerBuilder(matchQueryBuilder);
queryRescorerBuilder.setQueryWeight(0.6f);//设置原始打分权重
queryRescorerBuilder.setRescoreQueryWeight(1.7f);//设置二次打分权重
queryRescorerBuilder.windowSize(3);//设置每个分片的参加二次打分文档个数
searchSourceBuilder.addRescorer(queryRescorerBuilder);//添加二次打分Builder
SearchRequest searchRequest = new SearchRequest("scenic");//创建搜索请求
searchRequest.source(searchSourceBuilder);//设置查询请求
printResult(searchRequest);//打印搜索结果
}
到此、搜索排序分析完了,下篇我们分享es项目实战,敬请期待!
文章出处登录后可见!
已经登录?立即刷新