You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Solr中跳过文本搜索仅传递用户信息用于自定义排序?

我之前也碰到过一模一样的需求,其实核心就是把用户信息和搜索查询拆分开——别把用户数据塞到q参数里,而是用自定义请求参数单独传递,同时让Solr只执行你需要的排序逻辑,不把用户信息当作文本关键词去匹配。下面是具体的实现方案和代码示例:

核心思路
  • 用自定义请求参数(比如user_info)传递用户的31,1这类数据,彻底避免和搜索关键词混淆
  • 将搜索的q参数设为*:*(如果不需要过滤文档),或者保留你原本的过滤条件,只把用户信息从q里剥离
  • 在自定义的CustomScoreProvider中读取这个自定义参数,用于计算排序得分
代码实现示例

1. 自定义ScoreProvider和QParserPlugin

首先需要一个自定义的QParserPlugin来创建你的CustomScoreProvider,这样才能在解析查询时获取请求参数:

import org.apache.solr.common.params.SolrParams;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.search.QParser;
import org.apache.solr.search.QParserPlugin;
import org.apache.solr.search.SyntaxError;
import org.apache.solr.search.function.CustomScoreProvider;
import org.apache.solr.search.function.CustomScoreQuery;

public class UserAwareScorePlugin extends QParserPlugin {

    @Override
    public QParser createParser(String qstr, SolrParams localParams, SolrParams params, SolrQueryRequest req) {
        return new QParser(qstr, localParams, params, req) {
            @Override
            public org.apache.solr.search.Query parse() throws SyntaxError {
                // 获取自定义的用户信息参数并解析
                String userInfo = getParams().get("user_info");
                String[] userData = userInfo.split(",");
                int userId = Integer.parseInt(userData[0]);
                int userType = Integer.parseInt(userData[1]);

                // 这里用MatchAllDocsQuery匹配所有文档,如果你有原本的过滤条件,替换成你的baseQuery即可
                org.apache.solr.search.Query baseQuery = new org.apache.solr.search.MatchAllDocsQuery();

                return new CustomScoreQuery(baseQuery) {
                    @Override
                    protected CustomScoreProvider getCustomScoreProvider(SolrQueryRequest req) {
                        return new CustomScoreProvider(req) {
                            @Override
                            public float customScore(int doc, float subQueryScore, float[] valSrcScores) {
                                // 这里根据userId和userType计算自定义得分
                                float score = subQueryScore;
                                if (userType == 1) {
                                    // 示例:从文档中读取关联字段,结合用户信息调整得分
                                    float userRelevance = req.getSearcher().doc(doc).getFloatValue("user_relevance");
                                    score += userRelevance * userId * 0.1f;
                                }
                                return score;
                            }
                        };
                    }
                };
            }
        };
    }
}

2. 在solrconfig.xml中注册插件

把你的自定义插件注册到Solr配置文件里:

<queryParser name="user_aware_score" class="com.yourpackage.UserAwareScorePlugin"/>

3. 发起查询请求

现在可以用这个插件发起查询,用户信息通过user_info参数传递,q参数用*:*(或你的过滤条件):

GET /solr/your_core/select?defType=user_aware_score&q=*:*&user_info=31,1&sort=score desc

如果需要保留原本的过滤条件(比如只搜索分类为electronics的文档):

GET /solr/your_core/select?defType=user_aware_score&q=category:electronics&user_info=31,1&sort=score desc
轻量替代方案:用Function Query传递参数

如果不想写复杂的QParserPlugin,也可以用Solr的Function Query结合param()函数传递参数,在bf(Boost Function)中使用:

1. 自定义ValueSource函数

import org.apache.solr.search.ValueSource;
import org.apache.solr.search.function.ValueSourceParser;
import org.apache.solr.search.function.FloatValueSource;
import org.apache.solr.common.params.SolrParams;

public class UserBonusValueSourceParser extends ValueSourceParser {
    @Override
    public ValueSource parse(FunctionQParser fp) throws SyntaxError {
        // 直接从请求参数中获取用户信息
        int userId = fp.getIntParam("user_id");
        int userType = fp.getIntParam("user_type");
        
        return new FloatValueSource() {
            @Override
            public float floatVal(int doc) {
                // 根据用户信息计算加分
                return userType == 1 ? userId * 0.1f : 0f;
            }

            @Override
            public String description() {
                return "user_bonus(" + userId + "," + userType + ")";
            }
        };
    }
}

2. 注册函数到solrconfig.xml

<valueSourceParser name="user_bonus" class="com.yourpackage.UserBonusValueSourceParser"/>

3. 发起查询

GET /solr/your_core/select?q=*:*&bf=user_bonus()&user_id=31&user_type=1&sort=score desc

内容的提问来源于stack exchange,提问作者Quiz Master

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:59:16