在记录上使用 $unwind 后只匹配一条记录
Match with only one record after using $unwind on the record
我有如下记录
[
{
_id : 1, nm : 1,
usr:[
{id : 1, ty : 'team'},
{id : 2, em : 'a'},
{id : 3, em : 'b'}
]
},
{
_id : 2, nm : 2,
usr:[
{id : 2, em : 'a'},
{id : 3, em : 'b'}
]
},
{
_id : 3, nm : 3,
usr:[
{id : 1, ty : 'team'},
{id : 3, em : 'b'}
]
},
{
_id : 4, nm : 4,
usr:[
{id : 3, em : 'b'}
]
}
]
- 我希望在使用
userAndTeam = [1, 2]
查询时计数为 3
,即,如果一条记录有 usr.id as 1 or 2
,则获取这些记录。
- 我希望在使用
userAndTeam4 = [1, 4]
查询时计数为 2
,即如果一条记录有 usr.id as 1 or 4
,则获取这些记录。
我尝试使用 $unwind
,这使得第一种情况的计数为 4,因为 $unwind
为第一条记录创建了 3 条记录,下面的查询与其中 2 条记录匹配。
我试过的查询:
var userAndTeam = [1, 2] //User id and team id. Record should match one of the ids.
var userAndTeam4 = [1, 4]
[{
$unwind: '$usr'
},
{
$project:{
'count-2' : {$cond: {
if: {$in : ['$usr.id',userAndTeam]},
then: 1,
else: 0
}},
'count-4' : {$cond: {
if: {$in : ['$usr.id',userAndTeam4]},
then: 1,
else: 0
}}
}
}
]
输出:
ID 为 2 的用户预期 - 'count-2' : 3
为 ID 为 2 的用户获得 - 'count-2' : 4
ID 为 4 的用户预期 - 'count-4' : 2
为 ID 为 4 的用户获得 - 'count-4' : 2
有人可以指导我解决这个问题并获得预期的计数吗?
您可以尝试以下聚合:
db.col.aggregate([
{
$unwind: "$usr"
},
{
$project:{
"userId": "$usr.id",
"count-2": {
$cond: {
if: { $in: [ "$usr.id", userAndTeam ] },
then: 1,
else: 0
}
},
"count-4": {
$cond: {
if: { $in: [ "$usr.id", userAndTeam4] },
then: 1,
else: 0
}
}
}
},
{
$group: {
_id: "$_id",
"count-2": { $max: "$count-2" },
"count-4": { $max: "$count-4" }
}
},
{
$group: {
_id: null,
"count-2": { $sum: "$count-2" },
"count-4": { $sum: "$count-4" }
}
}
])
您的代码中缺少的是您希望每个 _id
具有 0
或 1
,因此您需要按 _id
进行分组$max
每个组的值 0
如果 none 匹配 1
如果任何元素与您的数组匹配。
我有如下记录
[
{
_id : 1, nm : 1,
usr:[
{id : 1, ty : 'team'},
{id : 2, em : 'a'},
{id : 3, em : 'b'}
]
},
{
_id : 2, nm : 2,
usr:[
{id : 2, em : 'a'},
{id : 3, em : 'b'}
]
},
{
_id : 3, nm : 3,
usr:[
{id : 1, ty : 'team'},
{id : 3, em : 'b'}
]
},
{
_id : 4, nm : 4,
usr:[
{id : 3, em : 'b'}
]
}
]
- 我希望在使用
userAndTeam = [1, 2]
查询时计数为3
,即,如果一条记录有usr.id as 1 or 2
,则获取这些记录。 - 我希望在使用
userAndTeam4 = [1, 4]
查询时计数为2
,即如果一条记录有usr.id as 1 or 4
,则获取这些记录。
我尝试使用 $unwind
,这使得第一种情况的计数为 4,因为 $unwind
为第一条记录创建了 3 条记录,下面的查询与其中 2 条记录匹配。
我试过的查询:
var userAndTeam = [1, 2] //User id and team id. Record should match one of the ids.
var userAndTeam4 = [1, 4]
[{
$unwind: '$usr'
},
{
$project:{
'count-2' : {$cond: {
if: {$in : ['$usr.id',userAndTeam]},
then: 1,
else: 0
}},
'count-4' : {$cond: {
if: {$in : ['$usr.id',userAndTeam4]},
then: 1,
else: 0
}}
}
}
]
输出:
ID 为 2 的用户预期 - 'count-2' : 3
为 ID 为 2 的用户获得 - 'count-2' : 4
ID 为 4 的用户预期 - 'count-4' : 2
为 ID 为 4 的用户获得 - 'count-4' : 2
有人可以指导我解决这个问题并获得预期的计数吗?
您可以尝试以下聚合:
db.col.aggregate([
{
$unwind: "$usr"
},
{
$project:{
"userId": "$usr.id",
"count-2": {
$cond: {
if: { $in: [ "$usr.id", userAndTeam ] },
then: 1,
else: 0
}
},
"count-4": {
$cond: {
if: { $in: [ "$usr.id", userAndTeam4] },
then: 1,
else: 0
}
}
}
},
{
$group: {
_id: "$_id",
"count-2": { $max: "$count-2" },
"count-4": { $max: "$count-4" }
}
},
{
$group: {
_id: null,
"count-2": { $sum: "$count-2" },
"count-4": { $sum: "$count-4" }
}
}
])
您的代码中缺少的是您希望每个 _id
具有 0
或 1
,因此您需要按 _id
进行分组$max
每个组的值 0
如果 none 匹配 1
如果任何元素与您的数组匹配。