node.js - 聚合并展平 MongoDB 中的数组字段

标签 node.js mongodb mongoose

我有一个架构:

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/

相关文章:

node.js - Nightmare 不会连续运行两次 - NodeJS

javascript - Jasmine 链测试

javascript - 如何使字符串指向 Less 中的变量?

mongodb - Spark scala 使用 spark-mongo connector 进行 upsert

javascript - Node.js + Mongoose : Model/Schema separated from db logic

node.js - MongoDB 设置数据库脚本(基于 NodeJS 的项目)

json - 如何在 Node JS 中读取文本文件并将其作为 JSON 对象返回?

javascript - 在 mongodb 中,作为 key 而不是匿名用户的用户名和密码传递什么?

node.js - Mongoose 分页不区分大小写的字符串排序

javascript - 如何在保存另一个文档之前等待循环完成?