MongoDB:确定是否有任何对象具有特定子数组值的特定计数



本质上,我有:

  • bands集合
  • 每个频带可以具有也可以不具有players的阵列
  • 每个玩家都有一个roles(字符串(数组

例如:

// a band
{
_id: 1,
players: [
{ 
name: "George",
roles: [ "GUITAR" ]
},
{ 
name: "John",
roles: [ "SINGER", "GUITAR" ]
},
{ 
name: "Paul",
roles: [ "SINGER", "BASS GUITAR" ]
},
{ 
name: "Ringo",
roles: [ "DRUMS" ]
},
]
}

我需要确定是否有任何乐队包含多名成员担任歌手角色。

$unwind / $group解决方案的替代方案是$filter:

db.collection.aggregate([
{
$match: {
"players.roles": "GUITAR"
}
},
{
"$set": {
"member_cnt": {
$size: {
$filter: {
input: "$players",
cond: {
$in: [
"GUITAR",
"$$this.roles"
]
}
}
}
}
}
},
{
$match: {
"member_cnt": {
$gt: 1
}
}
},
{
"$project": {
member_cnt: 0
}
}
])

它应该更快一点,因为它没有阻塞$group阶段。

一些简单的选项:

db.collection.aggregate([
{
$unwind: "$players"
},
{
$unwind: "$players.roles"
},
{
$match: {
"players.roles": "SINGER"
}
},
{
$group: {
_id: "$_id",
cnt: {
$sum: 1
}
}
},
{
$match: {
cnt: {
$gt: 1
}
}
}
])

解释:

  1. 展开第一个数组
  2. 展开第二个阵列
  3. 仅筛选SINGER角色
  4. 按band_id分组并计数SINGER角色
  5. 使用>1名歌手

操场

这个查询似乎给了我所需要的:

db.bands.aggregate([
{
$addFields: {
players: {
$ifNull: [
"$players",
[]
]
}
}
},
{
"$match": {
"$expr": {
"$gt": [
{
"$size": {
"$filter": {
"input": "$players",
"as": "player",
"cond": {
"$in": [
"SINGER",
"$$player.roles"
]
}
}
}
},
1
]
}
}
}
])

最新更新