我有一个关于查询嵌套文档的问题。我试图搜索但没有回答我的问题,或者我可能会忽略它。我有这样的结构:
{
"_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")
}]
答案 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
}
},
]
);