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

Lad*_*ker 4 mongoose mongodb 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")
    }
    },
Run Code Online (Sandbox Code Playgroud)

我想查询整个作者集合中所有书籍的列表- 例如:

"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")
    }]
Run Code Online (Sandbox Code Playgroud)

Nei*_*unn 5

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

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

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

})
Run Code Online (Sandbox Code Playgroud)

在早期版本中,您使用以下命令指定所有字段$project

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

})
Run Code Online (Sandbox Code Playgroud)

所以,$unwind是你用什么来解构或“denormalise”进行处理的数组项。这实际上为数组的每个成员创建了整个文档的副本。

其余的任务是关于“仅”返回数组中存在的那些字段。

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

它的性能要好得多,使用聚合框架将所有文档从集合中分离出来,仅从数组中列出这些文档。