如何从所有文档返回数组的嵌套文档

时间:2017-05-28 10:57:36

标签: mongodb mongoose mongodb-query aggregation-framework

我有一个关于查询嵌套文档的问题。我试图搜索但没有回答我的问题,或者我可能会忽略它。我有这样的结构:

    {
    "_id" : ObjectId("592aa441e0f8de09b0912fe9"),
    "name" : "Patrick Rothfuss",
    "books" : [ 
    {
        "title" : "Name of the wind",
        "pages" : 400,
        "_id" : ObjectId("592aa441e0f8de09b0912fea")
    }, 
    {
        "title" : "Wise Man's Fear",
        "pages" : 500,
        "_id" : ObjectId("592aa441e0f8de09b0912feb")
    },
    },
    {
    "_id" : ObjectId("592aa441e0f8de09b0912fe9"),
    "name" : "Rober Jordan",
    "books" : [ 
    {
        "title" : "The Eye of the World",
        "pages" : 400,
        "_id" : ObjectId("592aa441e0f8de09b0912fea")
    }, 
    {
        "title" : "The Great Hunt",
        "pages" : 500,
        "_id" : ObjectId("592aa441e0f8de09b0912feb")
    }
    },

我想在整个作者集中查询所有图书的列表 - 类似于:

"books" : [ 
    {
        "title" : "The Eye of the World",
        "pages" : 400,
        "_id" : ObjectId("592aa441e0f8de09b0912fea")
    }, 
    {
        "title" : "The Great Hunt",
        "pages" : 500,
        "_id" : ObjectId("592aa441e0f8de09b0912feb")
    },
    {
        "title" : "Name of the wind",
        "pages" : 400,
        "_id" : ObjectId("592aa441e0f8de09b0912fea")
    },
    {
        "title" : "Wise Man's Fear",
        "pages" : 500,
        "_id" : ObjectId("592aa441e0f8de09b0912fea")
    }]

2 个答案:

答案 0 :(得分:1)

您可以使用.aggregate()并主要使用$unwind管道运算符来执行此操作:

在现代MongoDB 3.4及以上版本中,您可以与$replaceRoot

配合使用
Model.aggregate([
  { "$unwind": "$books" },
  { "$replaceRoot": { "newRoot": "$books" } }
],function(err,results) {

})

在早期版本中,您使用$project指定所有字段:

Model.aggregate([
  { "$unwind": "$books" },
  { "$project": {
    "_id": "$books._id",
    "pages": "$books.pages",
    "title": "$books.title"
  }}
],function(err,results) {

})

所以$unwind就是你用来解构或“非规范化”数组条目以进行处理的东西。实际上,这会为数组的每个成员创建整个文档的副本。

剩下的任务是“仅”返回数组中存在的那些字段。

但这不是一件非常明智的事情。如果您的目的是仅返回嵌入在文档数组中的内容,那么最好将该内容放入单独的集合中。

性能要好得多,使用聚合框架从集合中分离出所有文档,只是为了从列表中列出这些文档。

答案 1 :(得分:0)

根据上述说明,请尝试在MongoDB shell中执行以下查询。

db.collection.aggregate(

    // Pipeline
    [
        // Stage 1
        {
            $unwind: "$books"
        },

        // Stage 2
        {
            $group: {
              _id:null,
              books:{$addToSet:'$books'}
            }
        },

        // Stage 3
        {
            $project: {
                books:1,
                _id:0
            }
        },

    ]

);