【问题标题】:Mongo C# filter on integer contains整数上的Mongo C#过滤器包含
【发布时间】:2021-11-11 17:40:52
【问题描述】:

我有一个包含订单的集合,每个订单都有一个 int32 类型的 OrderId 字段。我想过滤收集并获取 OrderId 包含的所有订单,例如123。例如,以下 OrderId 必须匹配:

  • 123
  • 9912399
  • 99123

以下原始 mongo 过滤器有效: { $where: "/^.*123.*/.test(this.OrderId)" }

这如何在 C# Mongo 客户端或其他可以完成这项工作的东西中表达?

我无法使用下面的代码,因为它似乎只适用于字符串字段:

Builders<Order>.Filter.Regex(x => x.OrderId, new BsonRegularExpression("123"))

【问题讨论】:

  • 你试过Builders&lt;Order&gt;.Filter.Regex(x =&gt; x.OrderId, new BsonRegularExpression("/^.*123.*/"))吗?
  • 是的,这变成了{ "OrderId" : /^.*123*/ },它不适用于int32 字段。如果我将字段类型更改为string,该过滤器确实有效,但不适用于int32
  • 尝试解析原始字符串:var filter = BsonDocument.Parse(@"{ $where: ""/^.*123.*/.test(this.OrderId)"" }");
  • 在某个时候。您将需要在字符串级别进行比较。数字中间的 123 在技术上不是数值。您可以使用聚合管道创建一个两阶段聚合 - 第一阶段是将数字转换为字符串,第二阶段对字符串值执行 regex()。
  • 这可能会有所帮助https://stackoverflow.com/questions/34184764/filter-with-regex-mongodb-c-sharp-driver?noredirect=1&amp;lq=1

标签: c# mongodb


【解决方案1】:

理想情况下,您应该在文档中存储订单 ID 的字符串版本。如果这不是一个选项,您可以执行以下聚合管道:

var res = await collection
    .Aggregate()
    .AppendStage<object>("{ $set : { orderIdString : { $toString : '$OrderId' } } }")
    .Match(Builders<object>.Filter.Regex("orderIdString", "/123/"))
    .AppendStage<object>("{ $unset : 'orderIdString' }")
    .As<Order>()
    .ToListAsync();

【讨论】:

    【解决方案2】:

    我认为您不能通过类型化构建器生成$where。因此,正如上面提到的,您唯一的选择是从原始 MQL 创建过滤器,如下所示:

        var coll = db.GetCollection<Order>("coll");
        var result = coll.Find("{ $where: '/^.*123.*/.test(this.OrderId)' }").ToList();
    

    【讨论】:

    • 我目前有一个使用new List&lt;FilterDefinition&lt;Order&gt;&gt;() 之类的列表动态地列出不同过滤器的列表。如何从原始 MQL 构建 FilterDefinition?
    • 你的意思是不同的过滤器而不是'/^.*123.*/ 常量?
    • 如果是这样,您可以通过 $where 或 $function docs.mongodb.com/manual/reference/operator/query/where 定义任何复杂的逻辑
    【解决方案3】:

    您是否尝试过使用:

    x => x.OrderId.ToString() 
    

    而不是

    x => x.Orderid
    

    【讨论】:

    • 不,这不起作用。 Unable to determine the serialization information for x =&gt; x.OrderId.ToString()
    • 我可以试试 Mongodb,但是: x.OrderId.Value.Tostring() 吗? (我只是兴奋。)
    【解决方案4】:

    您可以使用 Filter.Regex 来实现所需的行为:

    var valueToFilterBy = "123"
    var filter = Builders<Order>.Filter.Regex(nameof(Order.Id), new BsonRegularExpression($".*{valueToFilterBy}.*"));
    var data = await collection.FindAsync(filter).ToListAsync();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-18
      • 1970-01-01
      • 2011-01-01
      • 1970-01-01
      • 2014-05-30
      • 2019-01-20
      • 1970-01-01
      • 2019-02-22
      相关资源
      最近更新 更多