使用 C# MongoDB 驱动程序在 for 循环中创建过滤器的布尔逻辑

时间:2021-06-10 09:57:54

标签: c# mongodb

所以,我正在尝试在 C# 中实现以下 mongoDB 过滤器:

find({ "$or" : [
 {"$and":[{ "isPublic" : false}, {"_id" : ObjectId("60c0bfc23b3ffd14f2675104")}]},
 {"$and":[{ "isPublic" : false}, {"_id" : ObjectId("60c0bfe43b3ffd14f2675105")}]},
 {"$and":[{ "isPublic" : false}, {"_id" : ObjectId("60c0c1863b3ffd14f2675106")}]}] 
});

上面的过滤器需要在for循环中创建,因为嵌套的“ands”的数量可能会有所不同。

使用 https://stackoverflow.com/a/32253436/16185277 的公认答案,我尝试了以下操作:

FilterDefinition<documents.poses> idFilter;
FilterDefinition<documents.poses> isPublicFilter = Builders<documents.poses>.Filter.Eq(x => x.isPublic, false);
posesFilter = Builders<documents.poses>.Filter.Empty;
foreach (ObjectId _id in DBManager.loggedInUser.poses){
    idFilter = Builders<documents.poses>.Filter.Eq(x => x._id, _id);
    posesFilter |= isPublicFilter & idFilter;
} 

这段代码创建的过滤器是:

find({ "$or" : [{ },
 { "isPublic" : false, "_id" : ObjectId("60c0bfc23b3ffd14f2675104") },
 { "isPublic" : false, "_id" : ObjectId("60c0bfe43b3ffd14f2675105") },
 { "isPublic" : false, "_id" : ObjectId("60c0c1863b3ffd14f2675106") }] })

我还尝试了以下方法,它们创建了与上述完全相同的过滤器。

FilterDefinition<documents.poses> idPublicFilter;
FilterDefinition<documents.poses> isPublicFilter = Builders<documents.poses>.Filter.Eq(x => x.isPublic, false);
posesFilter = Builders<documents.poses>.Filter.Empty;
foreach (ObjectId _id in DBManager.loggedInUser.poses){
    idPublicFilter = Builders<documents.poses>.Filter.Where(x => x._id == _id && x.isPublic == false);
     posesFilter = Builders<documents.poses>.Filter.Or(idPublicFilter, posesFilter);
} 

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

我建议使用一个看起来像这样的 in 子句

FilterDefinitionBuilder<Poses> filter = new();


var ids = poses.Select(p => p.ID);

var f = filter.And(
    filter.Eq(f => f.isPublic, false),
    filter.In(f => f.ID, ids)
);

失败将构建一个可枚举的过滤器,然后在 or 子句中组合

List<FilterDefinition<Poses>> filters = new();
foreach (var item in poses)
{
    filters.Add(filter.And(
        filter.Eq(f => f.isPublic, false),
        filter.Eq(f => f.ID, item.ID)
    ));

}
var f = filter.Or(filters.ToArray());