MongoDB聚合:根据切片索引数组拆分对象数组并重组
解决MongoDB中根据slicingIndex字段拆分数组的问题
问题描述
需依据文档内的slicingIndex字段,对array字段的对象数组进行切片拆分,并将拆分后的子数组合并为新数组。
输入示例:
[ { "slicingIndex": [0, 4, 7, 10], "array": [ { "name": 1 }, { "name": 2 }, { "name": 3 }, { "name": 4 }, { "name": 5 }, { "name": 6 }, { "name": 7 }, { "name": 8 }, { "name": 9 }, { "name": 10 } ] } ]
预期输出:
{ "array": [ [ { "name": 1 }, { "name": 2 }, { "name": 3 }, { "name": 4 } ], [ { "name": 5 }, { "name": 6 }, { "name": 7 } ], [ { "name": 8 }, { "name": 9 }, { "name": 10 } ] ] }
原管道问题分析
你提供的聚合管道未达预期,核心问题是计算$slice的长度时,错误地用当前slicingIndex元素减去自身({ "$subtract": [ { "$arrayElemAt": ["$slicingIndex", { "$indexOfArray": ["$slicingIndex", "$$num"] }] }, "$$num" ] }),结果始终为0,导致每个切片都为空数组。
正确的聚合管道
我们需要遍历slicingIndex的相邻元素对,用后一个元素减去前一个元素得到切片长度,具体实现如下:
db.collection.aggregate([ { "$project": { "_id": 0, "array": { "$map": { "input": { "$range": [0, { "$subtract": [{ "$size": "$slicingIndex" }, 1] }] }, "as": "idx", "in": { "$slice": [ "$array", { "$arrayElemAt": ["$slicingIndex", "$$idx"] }, { "$subtract": [ { "$arrayElemAt": ["$slicingIndex", { "$add": ["$$idx", 1] }] }, { "$arrayElemAt": ["$slicingIndex", "$$idx"] } ] } ] } } } } } ])
管道逻辑解释
- 生成遍历索引:通过
$range创建从0到slicingIndex长度减2的索引数组(因为要取相邻元素对,最后一个元素无需配对)。 - 遍历相邻元素对:对每个索引
$$idx,分别获取当前位置和下一个位置的slicingIndex值,前者作为切片起始位置,两者的差值作为切片长度。 - 执行数组切片:用
$slice根据起始位置和长度对array进行切割,得到目标子数组。
内容的提问来源于stack exchange,提问作者user1715
相关产品推荐
相关产品推荐

