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

如何扩展GraphQL过滤器实现多关键词搜索?

实现HotChocolate GraphQL多关键词OR逻辑的Contains过滤扩展

你需要修改MyStringContainsHandler的HandleOperation方法,将输入字符串拆分为独立关键词,为每个关键词生成Contains表达式,再通过OR逻辑组合这些表达式,即可匹配包含任意一个关键词的条目。

修改后的完整代码

public class MyGqlFilterConvention : FilterConvention
{
    protected override void Configure(IFilterConventionDescriptor descriptor)
    {
        descriptor.AddDefaultOperations();
        descriptor.AddDefaults();

        descriptor.AddProviderExtension(
            new QueryableFilterProviderExtension(y => y.AddFieldHandler<MyStringContainsHandler>()));
    }
}

public class MyStringContainsHandler : QueryableStringOperationHandler
{
    protected override int Operation => DefaultFilterOperations.Contains;

    public override Expression HandleOperation(QueryableFilterContext context, 
        IFilterOperationField field, IValueNode value, object parsedValue)
    {
        var property = context.GetInstance();
        var inputString = parsedValue as string;

        // 非字符串输入按原逻辑处理
        if (string.IsNullOrWhiteSpace(inputString))
        {
            return FilterExpressionBuilder.Contains(Expression.Call(property), parsedValue);
        }

        // 拆分关键词:按空格分割,过滤空值并去重
        var keywords = inputString.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
                                  .Distinct(StringComparer.OrdinalIgnoreCase);

        // 无有效关键词时返回永远不匹配的表达式
        if (!keywords.Any())
        {
            return Expression.Constant(false);
        }

        // 为第一个关键词生成初始表达式
        Expression combinedExpression = FilterExpressionBuilder.Contains(
            Expression.Call(property), 
            keywords.First(),
            StringComparison.OrdinalIgnoreCase); // 可选:忽略大小写匹配

        // 用OR逻辑组合剩余关键词的表达式
        foreach (var keyword in keywords.Skip(1))
        {
            var containsExpr = FilterExpressionBuilder.Contains(
                Expression.Call(property), 
                keyword,
                StringComparison.OrdinalIgnoreCase);
            combinedExpression = Expression.OrElse(combinedExpression, containsExpr);
        }

        return combinedExpression;
    }
}

关键修改说明

  1. 关键词拆分与清洗:用Split按空格分割输入字符串,通过RemoveEmptyEntries过滤空关键词,Distinct避免重复匹配相同关键词。
  2. 表达式组合:
    • 先为第一个关键词生成基础的Contains表达式
    • 遍历剩余关键词,用Expression.OrElse将每个关键词的Contains表达式以OR逻辑组合
  3. 可选优化:添加StringComparison.OrdinalIgnoreCase实现大小写不敏感匹配,可根据业务需求移除。
  4. 边界处理:对空输入、无有效关键词的场景做兜底处理,避免运行时异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 15:45:08