es搜索排序深入分析

目录


es搜索排序是es的高级特性之一,也是我们需求中经常遇到的问题,今天我们详细分析一下,废话少数,马上开始:

一、相关性排序

1、TF-IDF模型、向量空间模型、BM25算法简介、分布式场景对排序的影响。这些都是比较大的课题,后期我们会一个个专题分享。

二、查询时设置权重

  1. 查询时 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);//打印搜索结果
    }
  1. 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项目实战,敬请期待!

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
扎眼的阳光的头像扎眼的阳光普通用户
上一篇 2023年12月4日
下一篇 2023年12月4日

相关推荐