MongoDB中如何对嵌套数组内的元素按顺序两两配对?
MongoDB 数组相邻元素两两配对实现方案
直接使用MongoDB聚合管道即可完成需求,不需要应用层额外处理,完整查询语句如下:
db.your_collection.aggregate([ { $project: { events: { $map: { input: { $range: [0, { $size: "$events" }] }, as: "idx", in: { $mergeObjects: [ { $arrayElemAt: ["$events", "$$idx"] }, { mod: { $mod: ["$$idx", 2] }, pairIndex: { $floor: { $divide: ["$$idx", 2] } } } ] } } } } }, { $project: { couples: { $reduce: { input: "$events", initialValue: [], in: { $let: { vars: { currentPair: { $arrayElemAt: ["$$value", "$$this.pairIndex"] } }, in: { $cond: [ { $isArray: "$$currentPair" }, { $concatArrays: [ { $slice: ["$$value", "$$this.pairIndex"] }, [{ $concatArrays: ["$$currentPair", ["$$this"]] }], { $slice: ["$$value", { $add: ["$$this.pairIndex", 1] }, { $size: "$$value" }] } ] }, { $concatArrays: ["$$value", [["$$this"]]] } ] } } } } } } } ])
逻辑说明
- 第一阶段通过
$range生成与events数组等长的从0开始的索引序列,遍历每个索引时取出对应位置的事件对象,追加两个标记字段:mod为索引对2取余的结果(每对第一个元素值为0,第二个为1,和需求输出一致),pairIndex为索引除以2向下取整的结果,用来标记当前元素所属的配对组。 - 第二阶段通过
$reduce遍历带标记的事件列表,遍历过程中按pairIndex归组:如果对应位置的配对数组已存在,就将当前元素追加到该配对数组中;如果不存在,就新建一个包含当前元素的配对数组放到对应位置,最终输出的couples字段就是符合要求的二维配对数组。 - 该方案为通用实现,支持任意长度的输入数组:如果数组长度为奇数,最后一个配对组只会包含单个元素,可根据业务需求在管道末尾追加
$project阶段过滤掉长度不足2的配对组。
内容的提问来源于stack exchange,提问作者nimrod serok
相关产品推荐
相关产品推荐

