如何使用C#MongoDB驱动程序编写嵌套对象属性不能相等的强类型过滤器?

如何使用C#MongoDB驱动程序编写嵌套对象属性不能相等的强类型过滤器?,c#,mongodb,mongodb-query,C#,Mongodb,Mongodb Query,我想多次筛选出不具备相同技能的候选人。 应用过滤器后,我的预期结果是: Model:{_id:1, Name:"Ross", Skills: [{ _id:1, SkillName:"Swiming"}, { _id:3, SkillName:"Fishing"}]} Candidate1:{_id:1, Name:"Ross", Skills: [{ _id:1, SkillName:"Swiming&

我想多次筛选出不具备相同技能的候选人。 应用过滤器后,我的预期结果是:

Model:{_id:1, Name:"Ross", Skills: [{ _id:1, SkillName:"Swiming"}, { _id:3, SkillName:"Fishing"}]}

Candidate1:{_id:1, Name:"Ross", Skills: [{ _id:1, SkillName:"Swiming"}, { _id:2, SkillName:"Kayaking"}]}
Candidate2:{_id:2, Name:"Ted", Skills: [{ _id:1, SkillName:"Swiming"}, { _id:3, SkillName:"Fishing"}]}
Candidate3:{_id:3, Name:"Snow", Skills: [{ _id:1, SkillName:"Swiming"}, { _id:1, SkillName:"Swiming"}]}
Candidate4:{_id:4, Name:"Snow", Skills: [ { _id:3, SkillName:"Fishing"}]}
候选人3不会被选中,因为他有两次相同的技能

所以我试过这个

Candidate1:{_id:1, Name:"Ross", Skills: [{ _id:1, SkillName:"Swiming"}, { _id:2, SkillName:"Kayaking"}]}
Candidate2:{_id:2, Name:"Ted", Skills: [{ _id:1, SkillName:"Swiming"}, { _id:3, SkillName:"Fishing"}]}   
Candidate4:{_id:4, Name:"Snow", Skills: [ { _id:3, SkillName:"Fishing"}]}
filter=Builders.filter.Where(cndt=>cndt.Skills.Count>1&&cndt.Skills[0]。\u id!=cndt.Skills[1]。\u id);
但这并不奏效。 注意:最多可以有两个
技能

通过将技能数组的大小与不同的技能数组集进行比较,可以做到这一点。这可以在mongo控制台中用以下find查询表示

db.candidates.find({
“$expr”:{
“$eq”:[
{
“$size”:{
“$reduce”:{
“输入”:“$Skills”,
“初始值”:[
],
“在”:{
“$setUnion”:[
“$$value”,
[
“$$this.\u id”
]
]
}
}
}
},
{
“$size”:“$Skills”
}
]
}
}
这很难用C#类型的helper函数来表达,因此值得将其作为字符串过滤器传递

var client=newmongoclient();
var database=client.GetDatabase(“测试”);
var collection=database.GetCollection(“候选者”);
var results=await collection.Find(@){
“$expr”:{
“$eq”:[
{
“$size”:{
“$reduce”:{
“输入”:“$Skills”,
“初始值”:[
],
“”在“”中:{
“$setUnion”:[
“$$value”,
[
“$$this.\u id”
]
]
}
}
}
},
{
“$size”:“$Skills”
}
]
}
})。ToListAsync();
foreach(结果中的var候选值)
{
WriteLine($“{candidate.Id}:{candidate.Name}”);
}
//1:罗斯
//2:Ted
//4:下雪
这个查询相当复杂,下面是它所做工作的分解

$expr
查询运算符允许我们在查询中使用聚合表达式

$size
给出了一个数组的大小,我们可以用
$eq
来比较这两个大小

然后,我们将使用
$reduce
创建一个新数组,该数组将是技能ID的所有值的并集

filter = Builders<Candidate>.Filter.Where(cndt => cndt.Skills.Count>1 && cndt.Skills[0]._id != cndt.Skills[1]._id );