使用旧的MongoDB驱动程序,我能够执行以下查询:
Query.Where("this.plan.sstats.used < this.plan.sstats.available")
但是对于新的,我不得不写下这个:
builder.Filter
.Where(t => t.Plan.StorageStats.UploadUsed < t.Plan.StorageStats.UploadAvailable)
这些看起来一样,但新的不起作用,我收到此错误消息:
其他信息:不支持的过滤器:({plan.sstats.used}&lt; {plan.sstats.available})。
后端版本目前是相同的,所以我认为没有任何理由不能继续这样做。
我该如何解决这个问题?有没有更好的方法来做到这一点,同时保持原子性?
答案 0 :(得分:2)
似乎MongoDb驱动器不再支持它了。我个人认为有两种可能的解决方案:
1)你查询应该工作的bson,而不是你的对象(我试过我的样本数据):
FilterDefinition<BsonDocument> filter =
new BsonDocument("$where", "this.plan.sstats.used<this.plan.sstats.available");
这种方法很糟糕:您应该将您的收藏集查询为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()
电话中使用的其他过滤器结合使用。
答案 1 :(得分:2)
所以,我也对Mongo的JIRA提出过要求,并将其作为一种潜在的选择。我在这里发帖,以防有人对马克西姆的回答不满意。
可以只创建过滤器定义:
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\" }";