MongoDB 过滤匹配和不匹配的条件
MongoDB Filter for both matched and un-matched conditions
我有一个场景,我 认为 我可能需要使用 $cond 根据现有属性是否存在于数组中来设置 $project 中的属性(聚合)字符串。
以下数据作为简化示例...
var teamMemberFilter = ['Dave', 'Kate'];
[
{
ticketId: '1',
ticketDesc: 'Dummy ticket 1',
assignments: [
{
asignee: 'Team',
email: 'supportinbox@mysite.com'
},
{
asignee: 'Dave',
email: 'dave@mysite.com'
},
{
asignee: 'Kate',
email: 'kate@mysite.com'
}
]
},
{
ticketId: '2',
ticketDesc: 'Dummy ticket 2',
assignments: [
{
asignee: 'Team',
email: 'supportinbox@mysite.com'
},
{
asignee: 'Rob',
email: 'rob@mysite.com'
}
]
},
{
ticketId: '3',
ticketDesc: 'Dummy ticket 3',
assignments: [
{
asignee: 'Team',
email: 'supportinbox@mysite.com'
},
{
asignee: 'Dave',
email: 'dave@mysite.com'
},
{
asignee: 'Mark',
email: 'mark@mysite.com'
}
]
}
]
我想查询 returns 所有有团队分配但没有团队成员分配的工单。
在上面的例子中,只有工单 2 应该被返回,因为它有一个团队分配,并且同一个工单中唯一的其他分配属于 Rob,他不属于该团队(如 teamMemberFilter 中指定的)。
当一个简单的查询就足够时,不确定为什么您认为需要为此使用聚合过滤器:
db.tickets.find({
"$and": [
{ "assignments.asignee": "Team" },
{ "assignments.asignee": {"$nin": teamMemberFilter } }
]
})
匹配具有 "Team" 作为 "asignee" 但在列出的数组中没有任何人的所有内容。
如果出于某种原因您确实需要在聚合管道中评估逻辑,那么您可以使用逻辑运算符代替:
db.tickets.aggregate([
{ "$project": {
"matched": {
"$let": {
"vars": {
"names": { "$map": {
"input": "$assignments",
"as": "a",
"in": "$$a.asignee"
}}
},
"in": {
"$and": [
{ "$eq": [
{ "$size": { "$setIntersection": [ "$$names", ["Team"] ] } },
1
]},
{ "$eq": [
{ "$size": { "$setIntersection": [ "$$names", teamMemberFilter ] } },
0
]},
]
}
}
}
}}
])
这只会在第二个文档上 return true
并且通过 $map
and $setIntersection
运算符处理数组内容大大简化了。
我有一个场景,我 认为 我可能需要使用 $cond 根据现有属性是否存在于数组中来设置 $project 中的属性(聚合)字符串。
以下数据作为简化示例...
var teamMemberFilter = ['Dave', 'Kate'];
[
{
ticketId: '1',
ticketDesc: 'Dummy ticket 1',
assignments: [
{
asignee: 'Team',
email: 'supportinbox@mysite.com'
},
{
asignee: 'Dave',
email: 'dave@mysite.com'
},
{
asignee: 'Kate',
email: 'kate@mysite.com'
}
]
},
{
ticketId: '2',
ticketDesc: 'Dummy ticket 2',
assignments: [
{
asignee: 'Team',
email: 'supportinbox@mysite.com'
},
{
asignee: 'Rob',
email: 'rob@mysite.com'
}
]
},
{
ticketId: '3',
ticketDesc: 'Dummy ticket 3',
assignments: [
{
asignee: 'Team',
email: 'supportinbox@mysite.com'
},
{
asignee: 'Dave',
email: 'dave@mysite.com'
},
{
asignee: 'Mark',
email: 'mark@mysite.com'
}
]
}
]
我想查询 returns 所有有团队分配但没有团队成员分配的工单。
在上面的例子中,只有工单 2 应该被返回,因为它有一个团队分配,并且同一个工单中唯一的其他分配属于 Rob,他不属于该团队(如 teamMemberFilter 中指定的)。
当一个简单的查询就足够时,不确定为什么您认为需要为此使用聚合过滤器:
db.tickets.find({
"$and": [
{ "assignments.asignee": "Team" },
{ "assignments.asignee": {"$nin": teamMemberFilter } }
]
})
匹配具有 "Team" 作为 "asignee" 但在列出的数组中没有任何人的所有内容。
如果出于某种原因您确实需要在聚合管道中评估逻辑,那么您可以使用逻辑运算符代替:
db.tickets.aggregate([
{ "$project": {
"matched": {
"$let": {
"vars": {
"names": { "$map": {
"input": "$assignments",
"as": "a",
"in": "$$a.asignee"
}}
},
"in": {
"$and": [
{ "$eq": [
{ "$size": { "$setIntersection": [ "$$names", ["Team"] ] } },
1
]},
{ "$eq": [
{ "$size": { "$setIntersection": [ "$$names", teamMemberFilter ] } },
0
]},
]
}
}
}
}}
])
这只会在第二个文档上 return true
并且通过 $map
and $setIntersection
运算符处理数组内容大大简化了。