如何用NativeQuery实现文档主评分叠加booster字段值
解决方案:两种方式实现评分叠加booster字段值
一、修正RescorerQuery的用法
你遇到的MissingRequiredPropertyException是因为RescorerQuery必须明确指定query属性,不能仅构造带脚本字段的查询。正确做法是用ScriptQuery作为重打分查询的核心,同时配置重打分参数:
// 1. 构造基础匹配查询 Query baseQuery = MatchQuery.of(m -> m .field("content") .query("your_search_text") )._toQuery(); // 2. 构造重打分脚本查询:主评分 + booster字段值 ScriptQuery rescoreScriptQuery = ScriptQuery.of(sq -> sq .script(Script.of(sc -> sc .inline(InlineScript.of(is -> is .source("_score + doc['booster'].value") )) )) ); // 3. 构建RescorerQuery,指定查询和重打分参数 RescorerQuery rescorerQuery = RescorerQuery.of(rq -> rq .query(q -> q .script(rescoreScriptQuery) ) .windowSize(100) // 根据业务需求设置窗口大小,仅对前N个文档重打分 .scoreMode(RescoreQueryScoreMode.Total) // 叠加原评分与重打分结果 ); // 4. 构建NativeQuery并添加重打分器 NativeQuery query = NativeQuery.builder() .withQuery(baseQuery) .withRescorerQuery(rescorerQuery) .build(); // 执行多搜索 MultiSearchResponse<YourEntity> response = operations.multiSearch(...);
二、用FunctionScoreQueryBuilder实现(更推荐)
既然你了解function_score的DSL逻辑,用Spring Data Elasticsearch的FunctionScoreQueryBuilder可以更直观地实现需求:
// 1. 基础匹配查询 Query baseQuery = MatchQuery.of(m -> m .field("content") .query("your_search_text") )._toQuery(); // 2. 构造脚本函数:原评分叠加booster字段值 FunctionScoreQueryBuilder.FunctionScoreFunction scoreFunction = new ScriptFunctionBuilder( Script.of(sc -> sc .inline(InlineScript.of(is -> is .source("_score + doc['booster'].value") )) ) ); // 3. 构建FunctionScoreQuery FunctionScoreQuery functionScoreQuery = FunctionScoreQuery.of(fsq -> fsq .query(baseQuery) .functions(scoreFunction) .scoreMode(FunctionScoreMode.Sum) // 叠加原评分与函数计算结果 .boostMode(FunctionBoostMode.Replace) // 用计算后的总分替换原评分 )._toQuery(); // 4. 构建NativeQuery NativeQuery query = NativeQuery.builder() .withQuery(functionScoreQuery) .build(); // 执行多搜索 MultiSearchResponse<YourEntity> response = operations.multiSearch(...);
关键注意事项
- 确保
booster字段为数值类型(integer、float等),否则脚本会执行失败。 - 重打分的
windowSize需根据业务场景调整,过大可能影响性能,过小可能遗漏需要调整评分的文档。 - 若使用Spring Data Elasticsearch 4.x以下版本,
ScriptFunctionBuilder的构造方式略有差异,直接调用ScriptFunction的静态方法即可。
内容的提问来源于stack exchange,提问作者Dmitriy_Ze
相关产品推荐
相关产品推荐

