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\" }";
使用旧的 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\" }";