此查询的起点是一个名为book的集合:

{
   '_id' {"$oid": "64ba6a416504f1f01d773faa"},
   'isbn': 8765434567890,
   'booktitle': 'some text',
   'chapters':
      [
         {
            'r_id': {"$oid": "64ba6a416504f1f01kkk333"},
            'pagenr': 7,
            'title': 'whatever',
         },
         {
            'r_id': {"$oid": "64ba6a416504f1f01dj3jd7f"},
            'pagenr': 12,
            'title': 'another title',
         },
      ]
}

当然,还有更多的事情要做.但这个集合是查询的起点.

第二个集合在不同的集合中有关于许多事情的注释,其中包括关于上面集合中的章节的注释:

{
   '_id' {"$oid": "64ba6a416504f1f01d773faa"},
   'r_id': {"$oid": "64ba6a416504f1f01kkk333"},
   'note': 'blabla',
},
{
   '_id' {"$oid": "64ba6a416504f1f01d888hhh"},
   'r_id': {"$oid": "64ba6a416504f1f01kkk333"},
   'note': 'more blabla',
},
{
   '_id' {"$oid": "55353536504f1f01d000000"},
   'r_id': {"$oid": "64ba6a416swldkjfdskjl34"},
   'note': 'blabla',
},

因此,同一章可以有更多的注释.由两个集合体中的r_id个OID相连.

我需要的是两件几乎相似的东西:

1获得一本书的完整记录由isbn nr. 并将amount of notes per chapter添加到该记录中.

2获得一本书的完整记录由isbn nr. 并在该记录上加all of the notes per chapter.

NB章节在集合中不排序,但应按输出中的章节.页面进行排序.

因此,1的输出应该类似于:

{
   '_id' {"$oid": "64ba6a416504f1f01d773faa"},
   'isbn': 8765434567890,
   'booktitle': 'some text',
   'chapters':
      [
         {
            'r_id': {"$oid": "64ba6a416504f1f01kkk333"},
            'pagenr': 7,
            'title': 'whatever',
            'notes': 2
         },
         {
            'r_id': {"$oid": "64ba6a416504f1f01dj3jd7f"},
            'pagenr': 12,
            'title': 'another title',
            'notes': 0
         },
      ]
}

对于2个音符,当然会包含音符array.几乎一样,但不是这样.

到目前为止,我想出的是:

match = {'$match': {'isbn': {'$in': isbns}}}
project = {'$project':
        {
            '_id': '$_id',
            'isbn': '$isbn',
            'booktitle': '$booktitle',
            'chapters': {'$sortArray':
                {
                    'input': {'$map':
                                  {'input':
                                       '$chapters',
                                   'in': {
                                       'pagenr': '$$this.pagenr',
                                       'title': '$$this.title',
                                       'r_id': '$$this.r_id',
                                       }
                                   }
                              },
                    'sortBy': {'pagenr': 1},
                }
            },
            'notes': '$$related_notes',
            
      }
}
lookup = {'$lookup':
        {
            'from': 'notes',
            'localField': 'chapters.r_id',
            'foreignField': 'r_id',
            'as': 'related_notes',
        },
}

pipeline = [
        lookup,
        match,
        project,
    ]

这行得通,注释当然会添加到输出的末尾.如果我把它们放在$map部分,它们会被重复无数次,并且不会以任何方式过滤.

顺便说一句,我来自SQL,我真的很喜欢Mongo.这很奇妙,但并不容易掌握.了解了很多关于它的知识.

谢谢你的帮助.

推荐答案

you can use $filter inside each map iteration where you filter the related_notes array to return an array which has notes having r_id of that particular iteration. Then you can get the size of the filtered array using $size.
Also you can do the $match before $lookup to reduce unnecessary lookups

db.books.aggregate([
  { $match: { isbn: { $in: isbns } } },
  { $lookup: { from: "notes", localField: "chapters.r_id", foreignField: "r_id", as: "related_notes" } },
  {
    $project: {
      _id: "$_id",
      isbn: "$isbn",
      booktitle: "$booktitle",
      chapters: {
        $sortArray: {
          input: {
            $map: {
              input: "$chapters",
              as: "chapter",
              in: {
                r_id: "$$chapter.r_id",
                pagenr: "$$chapter.pagenr",
                title: "$$chapter.title",
                notes: { $size: { $filter: { input: "$related_notes", as: "note", cond: { $eq: ["$$note.r_id", "$$chapter.r_id"] } } } }
              }
            }
          },
          sortBy: { pagenr: 1 }
        }
      }
    }
  }
])

playground

Mongodb相关问答推荐

获取文档字段名并将其作为嵌套字段添加到聚合中

Mongo:查找具有 0 个关联文档的文档,成本更低

MongoDB - 使用许多嵌套对象更新嵌套数组

MongoDB中的readPreference和readConcern有什么区别?

为什么 MongoDB 配置服务器必须只有一个或三个?

如何使用 mongoose 从 MongoDb 获取数据?

如何将查询结果(单个文档)存储到变量中?

使用 EventSourcing(NodeJS、MongoDB、JSON)跨多个偶尔连接的客户端同步数据

pymongo 排序和 find_one 问题

MongoDB:单个数据库处理程序的 >5 个打开连接

在 GridFS、express、mongoDB、node.js 中存储来自 POST 请求的数据流

启动mongodb和express的正确方法?

Mongoose 中不同集合的相同模式

如何获取 Mongoid 文档的所有字段名称?

Ruby 按键值分组哈希

将 MongoCursor from ->find() 转换为数组

MongoException: Index with name: code already exists with different options

brew install mongodb 错误:Cowardly refusing to `sudo brew install' Mac OSX Lion

即使重新安装后,Mongo 仍在等待 27017

全局初始化失败:BadValue Invalid or no user locale set.请确保正确设置 LANG 和/或 LC_* 环境变量