我有一个架构:
var ProjectSchema = new Schema({
name: {
type: String,
default: ''
},
topics: [{
type: Schema.ObjectId,
ref: 'Topic'
}],
user: {
type: Schema.ObjectId,
ref: 'User'
}
});
我想要做的是获取一个数组,其中包含所有项目的所有主题。我无法直接查询主题并获得完整列表,因为某些主题未分配并且它们不保留对项目的引用(出于避免双向引用的原因)。所以我需要查询 Project 并聚合一些方法。我正在做类似的事情:
Project.aggregate([{$project:{topics:1}}]);
但这给了我一个带有主题字段的项目对象数组。我想要的是一个包含主题对象的数组。
我该怎么做?
最佳答案
在处理数组时,您通常希望使用 $unwind
首先在数组成员上,然后是 $group
找到不同的条目:
Project.aggregate(
[
{ "$unwind": "$topics" },
{ "$group": { "_id": "$topics._id" } }
],
function(err,docs) {
}
)
但对于这种情况,使用 .distinct()
可能更简单这将执行与上面相同的操作,但只有一组结果而不是文档:
Project.distinct("topics._id",function(err,topics) {
});
但是等一下,因为我知道你在这里真正问的是什么。这不是您想要的 _id
值,而是您的 Topic
数据有一个属性,如“名称”。
由于您的项目被“引用”并且在另一个集合中,您不能对另一个集合中的文档属性执行聚合管道或 .distinct()
操作。基本上“MongoDB 不执行连接”和 mongoose .populate()
是不是连接,只是用额外的查询“模拟”它。
但是您当然可以从“项目”中找到“不同”的值,然后从“主题”中获取信息。如:
Project.distinct("topics._id",function(err,topics) {
Topic.find({ "_id": { "$in": topics } },function(err,topics) {
});
});
这很方便,因为 .distinct()
函数已经返回了一个适合与 $in
一起使用的数组。 .
关于node.js - 聚合并展平 MongoDB 中的数组字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31068402/