Lambda 失败但字符串有效

Lambda where fails but string where works

使用旧的 MongoDB 驱动程序,我能够执行以下查询:

Query.Where("this.plan.sstats.used < this.plan.sstats.available")

但是有了新的,我不得不这样写:

builder.Filter
      .Where(t => t.Plan.StorageStats.UploadUsed < t.Plan.StorageStats.UploadAvailable)

这些看起来一样,但新的不起作用,我收到此错误消息:

Additional information: Unsupported filter: ({plan.sstats.used} < {plan.sstats.available}).

后端版本目前是相同的,所以我看不出有任何理由不能继续工作。

我该如何解决这个问题?有没有更好的方法来做到这一点,同时保持原子性?

似乎 MongoDb 驱动器不再支持它。我个人看到两种可能的解决方案:

1) 你查询的是 bson,而不是你的对象,它应该可以工作(我已经尝试使用我的样本数据):

FilterDefinition<BsonDocument> filter = 
    new BsonDocument("$where", "this.plan.sstats.used<this.plan.sstats.available");

Waht 这种方法不好:您应该将您的集合查询为 BsonDocument 集合。

2) 您将集合查询为 ToEnumerable(),而不是将过滤器添加为 Where linq 语句。这也行得通,但是您直接在 mongodb 上丢失了查询数据。

3)你可以使用聚合框架,我是这样做的:

var result = collection.Aggregate()
        .Group(r => r.Plan.StorageStats.UploadUsed - r.Plan.StorageStats.UploadAvailable,
              r => new {r.Key, Plans= r.Select(t=>t.Plan)} )
        .Match(r=>r.Key < 0)
        .ToEnumerable()
        .SelectMany(r=>r.Plans);

总计的负面因素是您无法将它与您在 Find() 调用中使用的其他过滤器结合使用。

所以,我也询问了 Mongo 的 JIRA,并被认为是一个潜在的替代方案。我将它张贴在这里以防有人对 Maksim 的回答不满意。


可以只创建一个过滤器定义:

FilterDefinition<C> filter = new JsonFilterDefinition<C>("{ $where : \"this.plan.sstats.used < this.plan.sstats.available\" }");

由于字符串可以转换为 FilterDefinitions,您还可以编写以下任一内容,最终都创建一个 JsonFilterDefinition: var filter = (FilterDefinition<C>)"{ $where : \"this.plan.sstats.used < this.plan.sstats.available\" }";

// or using an implicit conversion

FilterDefinition<C> filter = "{ $where : \"this.plan.sstats.used < this.plan.sstats.available\" }";