鉴于以下文件:
[
{
_id: "N0001",
name: "Bruce Lee",
skills: ["karate", "jiu jitsu"],
},
{
_id: "N0002",
name: "Bruce Dee",
skills: ["karate", "tae kwon do"],
},
{
_id: "N0003",
name: "Bruce See",
skills: ["aikido", "jiu jitsu"],
},
{
_id: "N0004",
name: "Deuce Lee",
skills: ["karate", "judo"],
},
]
字符串
我想得到以下信息:
{
karate: 3,
jiu jitsu: 2,
tae kwon do: 1,
judo: 1,
aikido: 1,
}
型
现在,我可以用下面这样的脚本来获得上面的内容:
const uniqueSkills = db.fighters.distinct('skills');
console.log(
Object.fromEntries(
uniqueSkills.map(
async m => [m, await db.fighters.find({ skills: m }).length]
)
)
)
型
但是我真的很想把这整个事情保持在聚合框架内,而不是使用节点运行时来重复进行这个查询,我完全不知道如何做到这一点。注意,技能集是有限的,但未知的,所以我不能从已知的技能列表开始,然后把它们硬编码到查询本身中。
1条答案
按热度按时间vlurs2pr1#
这样做的一种方法如下:
字符串
使用示例输入的输出为:
型
我们在这里:
$unwind
执行skills
数组以获取各个条目。$group
将这些技能组合在一起以获得计数$group
将这些组组合在一起,以将所有条目放入单个文档中1.使用
$replaceRoot
重塑文档。第三步和第四步是为了利用the
$arrayToObject
operator而设计的。看看它在this playground example中是如何工作的。
我很确定还有其他方法可以做到这一点。同样需要注意的是,随着数据集的增长,这种操作将是资源密集型的,但这只是像这样的分析操作必须针对该模式运行的自然结果。