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

如何在IQueryable LINQ中使用正则表达式搜索CosmosDB数据

问题描述

我希望在CosmosDB容器中使用正则表达式(RegEx)搜索数据。例如,容器中有如下文档:

{
  "name": "test"
},
{
  "name": "test_1"
},
{
  "name": "test_data_1"
}

当搜索名称为test或test_<number>时,希望匹配前两个文档。

我定义了如下模型:

public class TestObj
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    // 其他属性
}

并编写了按名称搜索TestObj对象的方法:

public async Task<List<TestObject>> GetManyByName(string searchName)
{
    var regex = new Regex($"^{searchName}_\\d$", RegexOptions.IgnoreCase);

    var options = new QueryRequestOptions {PartitionKey = new PartitionKey("partitionId")};

    var container = client.GetContainer("dbId", "containerId");
    var iterator = container.GetItemLinqQueryable<TestObject>(false, null, options)
        .Where(x => x.Name == searchName || regex.IsMatch(x.Name))
        .ToFeedIterator();

    var results = new List<TestObject>();
    while (iterator.HasMoreResults)
    {
        var feedResponse = await iterator.ReadNextAsync();
        if (feedResponse.Any())
            results.AddRange(feedResponse);
    }

    return results.ToList();
}

运行代码时出现异常:

DocumentClientException with status code 0, message: Method 'IsMatch' is not supported., inner exception: null, and response headers: null

看起来regex.IsMatch(x.Name)无法在IQueryable中使用,尝试Regex.IsMatch()也出现相同异常。已知CosmosDB支持RegEx,想咨询:是否可以在IQueryable中使用正则表达式?若不支持,有什么其他方法可以实现需求?优先使用LINQ方案,也接受其他实现方式。

解决方案

1. 使用LINQ的RegexMatch扩展方法(推荐)

CosmosDB的LINQ提供程序支持RegexMatch扩展方法,需引入Microsoft.Azure.Cosmos.Linq命名空间,该方法会被转换为CosmosDB原生支持的REGEX_MATCH系统函数,直接在服务端执行正则匹配。

修改后的代码:

using Microsoft.Azure.Cosmos.Linq;

public async Task<List<TestObject>> GetManyByName(string searchName)
{
    // 合并精确匹配和正则匹配的规则
    var regexPattern = $"^{searchName}$|^{searchName}_\\d$";
    var options = new QueryRequestOptions {PartitionKey = new PartitionKey("partitionId")};

    var container = client.GetContainer("dbId", "containerId");
    var iterator = container.GetItemLinqQueryable<TestObject>(false, null, options)
        .Where(x => x.Name.RegexMatch(regexPattern, RegexOptions.IgnoreCase))
        .ToFeedIterator();

    var results = new List<TestObject>();
    while (iterator.HasMoreResults)
    {
        var feedResponse = await iterator.ReadNextAsync();
        results.AddRange(feedResponse);
    }

    return results;
}

2. 使用SQL查询字符串

若LINQ方式存在局限,可直接构造SQL查询,调用CosmosDB的REGEX_MATCH函数:

public async Task<List<TestObject>> GetManyByName(string searchName)
{
    var regexPattern = $"^{searchName}$|^{searchName}_\\d$";
    var queryText = $"SELECT * FROM c WHERE REGEX_MATCH(c.name, @pattern, 'i')";
    var parameters = new QueryDefinition(queryText)
        .WithParameter("@pattern", regexPattern);

    var options = new QueryRequestOptions {PartitionKey = new PartitionKey("partitionId")};
    var container = client.GetContainer("dbId", "containerId");
    var iterator = container.GetItemQueryIterator<TestObject>(parameters, requestOptions: options);

    var results = new List<TestObject>();
    while (iterator.HasMoreResults)
    {
        var feedResponse = await iterator.ReadNextAsync();
        results.AddRange(feedResponse);
    }

    return results;
}

SQL中的'i'参数对应忽略大小写的规则,和RegexOptions.IgnoreCase效果一致。

3. 客户端过滤(不推荐)

仅适合数据量极小的场景,先拉取分区内所有数据,再在客户端用正则过滤,性能较差:

public async Task<List<TestObject>> GetManyByName(string searchName)
{
    var regex = new Regex($"^{searchName}$|^{searchName}_\\d$", RegexOptions.IgnoreCase);
    var options = new QueryRequestOptions {PartitionKey = new PartitionKey("partitionId")};

    var container = client.GetContainer("dbId", "containerId");
    var iterator = container.GetItemLinqQueryable<TestObject>(false, null, options)
        .ToFeedIterator();

    var results = new List<TestObject>();
    while (iterator.HasMoreResults)
    {
        var feedResponse = await iterator.ReadNextAsync();
        results.AddRange(feedResponse.Where(x => regex.IsMatch(x.Name)));
    }

    return results;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 15:35:16