Mongoexport时如何保留内嵌数组中对象的顺序?
解决MongoDB 3.0.2中mongoexport保留内嵌数组对象顺序的问题
首先得明确:MongoDB里的数组元素顺序是持久化且默认保留的,如果导出后dataSet数组的顺序乱了,大概率是数组本身在文档里的顺序就不符合预期,或者导出前没有做针对性的排序处理。结合你的Schema和MongoDB 3.0.2的特性,给你几个可行的解决方案:
1. 先修正文档内数组的顺序(推荐)
如果你的dataSet数组在入库时没按date排序,或者后续更新打乱了顺序,先遍历所有文档重新排序数组:
打开MongoDB Shell,执行以下脚本:
// 替换成你的集合名称 db.yourCollection.find().forEach(function(doc) { // 按date字段升序排序(降序的话把return值反过来) doc.dataSet.sort(function(a, b) { return new Date(a.date) - new Date(b.date); }); // 保存修改后的文档 db.yourCollection.save(doc); });
执行完后,文档里的dataSet就会按date有序排列,此时再用mongoexport导出,就能直接保留这个顺序。
2. 用聚合生成有序数组后导出(不修改原数据)
如果不想改动原数据,可以通过聚合管道先把dataSet按date排序,再导出结果。由于MongoDB 3.0.2没有$sortArray这样的直接排序数组的操作符,我们需要用$unwind+$sort+$group的组合:
步骤1:把聚合结果写入临时集合
db.yourCollection.aggregate([ // 展开dataSet数组 { $unwind: "$dataSet" }, // 先按文档_id分组,再按dataSet.date升序排序 { $sort: { "_id": 1, "dataSet.date": 1 } }, // 重新组合数组 { $group: { _id: "$_id", parity: { $first: "$parity" }, exchange: { $first: "$exchange" }, interval: { $first: "$interval" }, dataSet: { $push: "$dataSet" } } }, // 将结果写入临时集合 { $out: "temp_sorted_data" } ])
步骤2:导出临时集合
用mongoexport命令导出临时集合:
mongoexport --db your_database_name --collection temp_sorted_data --out sorted_output.json
步骤3:清理临时集合
导出完成后删除临时集合:
db.temp_sorted_data.drop()
3. 检查mongoexport的导出参数
确保你没有使用可能影响数组顺序的参数:
- 如果你导出的是JSON格式,默认就会保留数组元素顺序,不要用
--csv(CSV不适合内嵌数组的场景); - 如果用
--jsonArray参数,数组顺序也会正常保留,不用担心。
另外,MongoDB 3.0.2是比较老旧的版本,如果你遇到奇怪的顺序问题,可以考虑升级到3.0系列的最新小版本(比如3.0.15),修复一些已知的小bug。
内容的提问来源于stack exchange,提问作者quartaela
相关产品推荐
相关产品推荐

