MongoDB聚合管道实现字符串拼接(类PostgreSQL string_agg)
MongoDB 聚合拼接key值为分隔符字符串的最优方案
你要的功能在MongoDB里没法像PostgreSQL的string_agg那样一步到位做集合级归约,但有比先转数组再$reduce更简洁高效的实现方式:
适合MongoDB 4.4+版本的最优方案
用$group收集所有key到数组,再用原生的$join操作符直接拼接,还能按id排序对应SQL里的order by:
db.collection.aggregate([ // 按id排序,保证拼接顺序和SQL一致 { $sort: { id: 1 } }, // 把所有文档的key字段收集到一个数组里 { $group: { _id: null, keysArray: { $push: "$key" } } }, // 用|分隔数组元素成字符串 { $project: { result: { $join: { input: "$keysArray", separator: "|" } } } } ])
低版本MongoDB(低于4.4)的替代方案
如果版本不支持$join,那$reduce结合$concat是可行的,就是你之前考虑的思路,完整写法如下:
db.collection.aggregate([ { $sort: { id: 1 } }, { $group: { _id: null, keysArray: { $push: "$key" } } }, { $project: { result: { $reduce: { input: "$keysArray", initialValue: "", in: { $concat: [ "$$value", // 避免开头加|,空初始值时不加分隔符 { $cond: [{ $eq: ["$$value", ""] }, "", "|"] }, { $toString: "$$this" } ] } } } } } ])
关于直接归约的问题
MongoDB聚合管道的设计是基于文档流处理的,没有原生的直接对整个集合做归约、跳过数组收集的操作,必须先通过$group把分散的key聚合到一个数组里,再做拼接。不过上面用$join的方式已经是当前版本下性能最好、写法最简洁的实现了,比$reduce效率更高,因为$join是MongoDB内置的优化过的字符串拼接逻辑。
内容的提问来源于stack exchange,提问作者Dreo
相关产品推荐
相关产品推荐

