如何在MongoDB聚合中遍历关联文档获取最后关联书籍?
实现MongoDB聚合中递归遍历nextBook获取最后书籍的方案
要实现从指定文档开始,递归遍历nextBook引用直到找到无后续关联的最后一本书,可以使用MongoDB的$graphLookup聚合阶段,它专门用于处理文档间的递归关联查询。
聚合管道示例
以下是以_id: '1'为起始文档的完整聚合操作:
db.books.aggregate([ // 筛选起始文档 { $match: { _id: '1' } }, // 递归遍历后续书籍链 { $graphLookup: { from: 'books', // 关联的集合名称 startWith: '$nextBook', // 从当前文档的nextBook开始遍历 connectFromField: 'nextBook', // 后续文档中用于关联的字段 connectToField: '_id', // 被关联文档的匹配字段 as: 'bookChain', // 存储遍历结果的数组字段名 depthField: 'depth' // 可选:记录文档在链中的深度,便于确认顺序 } }, // 确定最后一本书 { $addFields: { lastBook: { $cond: { if: { $eq: [ { $size: '$bookChain' }, 0 ] }, then: '$$ROOT', else: { $last: '$bookChain' } } } } }, // 按需返回结果字段 { $project: { lastBook: 1, _id: 0 } } ])
代码解释
- $match:精准定位起始文档(这里是
_id: '1'的书籍)。 - $graphLookup:递归遍历所有通过
nextBook关联的后续文档,将结果存入bookChain数组。depthField会为每个文档添加depth字段,值越大表示在链中越靠后。 - $addFields:通过
$cond判断边界情况:如果bookChain为空(起始文档无后续),则lastBook为起始文档;否则取bookChain的最后一个元素(即链的终点)。 - $project:按需精简返回结果,只保留
lastBook字段。
边界情况处理
- 如果起始文档本身没有
nextBook字段,bookChain会是空数组,此时lastBook就是起始文档本身。 - 无论链中有多少层关联,
$graphLookup都会自动遍历到没有nextBook的文档为止。
内容的提问来源于stack exchange,提问作者SimonHbw
相关产品推荐
相关产品推荐

