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

如何使用C# Lambda表达式在MongoDB中实现全文搜索(规范模式)

使用Lambda表达式结合规范模式实现MongoDB全文搜索

嘿,我刚好折腾过类似的需求,其实要把Lambda表达式、规范模式和MongoDB全文搜索结合起来,核心就是把MongoDB的全文搜索逻辑包装成符合规范模式的表达式条件,下面我给你一步步拆解,附上手写的示例代码:


第一步:确保集合已创建文本索引

文本索引是MongoDB全文搜索的基础,你得先给目标集合的字段创建文本索引,不然全文搜索根本没法工作。比如你要搜索Foo类的Title和Content字段,用C#驱动创建索引的代码如下:

var collection = _mongoContextFactory.GetCollection<Foo>();
// 定义要创建文本索引的字段
var indexKeys = Builders<Foo>.IndexKeys
    .Text(foo => foo.Title)
    .Text(foo => foo.Content);
// 创建索引模型
var indexModel = new CreateIndexModel<Foo>(indexKeys);
// 执行索引创建
collection.Indexes.CreateOne(indexModel);

当然你也可以直接在MongoDB Shell里创建:

db.foos.createIndex({ Title: "text", Content: "text" })

第二步:搭建规范模式的基础接口

如果你还没有规范模式的接口,先定义一个最基础的版本,核心就是包含一个Lambda表达式的条件属性:

public interface ISpecification<T>
{
    // 用于查询过滤的Lambda表达式
    Expression<Func<T, bool>> Criteria { get; }
}

第三步:实现全文搜索的规范类

接下来我们要写一个专门处理全文搜索的规范类,把MongoDB的全文搜索逻辑转换成Lambda表达式,适配上面的规范接口:

public class FullTextSearchSpecification<T> : ISpecification<T>
{
    private readonly string _searchTerm;
    private readonly string[] _targetFields; // 可选:指定只在某些字段中搜索

    public FullTextSearchSpecification(string searchTerm, params string[] targetFields)
    {
        _searchTerm = searchTerm?.Trim() ?? string.Empty;
        _targetFields = targetFields;
    }

    public Expression<Func<T, bool>> Criteria
    {
        get
        {
            // 处理空搜索词的情况,返回空过滤(即查询所有)
            if (string.IsNullOrEmpty(_searchTerm))
                return _ => true;

            // 构建MongoDB全文搜索过滤条件
            var textFilter = Builders<T>.Filter.Text(
                _searchTerm,
                new TextSearchOptions 
                { 
                    CaseSensitive = false, // 忽略大小写
                    DiacriticSensitive = false // 忽略变音符号,比如é和e视为相同
                });

            // 如果指定了目标字段,再加上字段过滤
            if (_targetFields != null && _targetFields.Length > 0)
            {
                textFilter &= Builders<T>.Filter.AnyIn("_fts", _targetFields);
            }

            // 将MongoDB的FilterDefinition转换为Lambda表达式
            var expressionFilter = new ExpressionFilterDefinition<T>(textFilter);
            return expressionFilter.Expression;
        }
    }
}

第四步:用规范类执行全文搜索

现在就可以像你平时用Lambda查询那样,结合规范模式来执行全文搜索了:

var collection = _mongoContextFactory.GetCollection<Foo>();

// 示例:搜索包含"MongoDB全文搜索"的文档,只在Title和Content字段中查找
var searchSpec = new FullTextSearchSpecification<Foo>(
    "MongoDB全文搜索", 
    nameof(Foo.Title), 
    nameof(Foo.Content));

// 用规范的Criteria作为过滤条件查询
var searchResults = collection.FindSync(searchSpec.Criteria).ToList();

一些额外说明

  • 如果不需要指定特定搜索字段,直接用默认的文本索引字段搜索,创建规范类时可以不传targetFields参数;
  • 文本搜索的选项(大小写敏感、变音符号敏感)可以根据业务需求调整;
  • 这种方式既保留了规范模式的扩展性(比如你可以后续给规范类加排序、分页等属性),又完美适配了MongoDB的全文搜索能力,和你平时用collection.FindSync(x => x.Created >= new DateTime())的写法风格完全统一。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 19:07:52