使用 MongoDB 处理重复数据及批量生成数据的实践

数据库 MongoDB
在实际开发中,处理大量数据时,可能会遇到重复数据、批量插入等需求。以下是一个 MongoDB 实战案例,包括批量生成数据、删除重复数据以及数据去重后的索引优化。

在实际开发中,处理大量数据时,可能会遇到重复数据、批量插入等需求。以下是一个 MongoDB 实战案例,包括批量生成数据、删除重复数据以及数据去重后的索引优化。

1、批量插入数据

场景

我们需要为某个设备在每月生成一条记录,涉及以下条件:

  • 设备编号在一定范围内。
  • 每月固定日期生成时间戳。
  • 特定字段的值在一个范围内随机生成。

解决方案

利用 MongoDB 的批量插入功能,通过 JavaScript 脚本批量生成数据:

插入脚本

// 定义设备编号范围
var startDevice = 1001;
var endDevice = 1120;
// 定义每月时间戳(示例时间)
var timestamps = [
    NumberLong(1727731200000), // 2024-10-01 0:00:00
    NumberLong(1730323200000), // 2024-11-01 0:00:00
    NumberLong(1733001600000)  // 2024-12-01 0:00:00
];
// 批量插入数据
for (var tsIdx = 0; tsIdx < timestamps.length; tsIdx++) {
    var calcBeginDate = timestamps[tsIdx];


    for (var deviceCode = startDevice; deviceCode <= endDevice; deviceCode++) {
        var randomValue = (Math.random() * (0.9999 - 0.9800) + 0.9800).toFixed(4); // 随机值生成


        // 构建文档
        var document = {
            "deviceCode": "D" + deviceCode, // 替换设备编号
            "type": "months",
            "calcTime": calcTime,
            "type0": NumberLong(0),
            "type1": NumberLong(0),
            "type2": NumberLong(0),
            "type3": NumberLong(0),
            "type4": NumberLong(0),
            "flag": "1",
            "ta": parseFloat(randomValue), // 随机值
            "updateTime": NumberLong(Date.now()),
            "createTime": NumberLong(Date.now()),
            "_class": "com.example.data.entity.Entity"
        };


        // 插入到集合
        db.device_data.insert(document);
    }
}

注意事项

1.执行脚本前,确保集合已存在,避免插入失败。

2.生成的随机数范围和设备编号范围可根据实际需求调整。

2、删除重复数据

场景

由于多次执行插入脚本,可能导致集合中存在重复数据。重复的定义是:

同一设备在同一个时间点(如每月初)的记录有多条。

解决方案

通过 MongoDB 的聚合和删除操作,删除重复数据,仅保留每组中的一条。

删除重复数据的脚本

// 删除重复数据,保留每组唯一数据
db.device_data.aggregate([
    {
        $group: {
            _id: { deviceCode: "$deviceCode", calcBeginDate: "$calcBeginDate" },
            duplicateIds: { $push: "$_id" } // 收集所有重复的 _id
        }
    },
    {
        $project: {
            _id: 0,
            keepId: { $arrayElemAt: ["$duplicateIds", 0] }, // 保留第一个 _id
            deleteIds: { $slice: ["$duplicateIds", 1, { $size: "$duplicateIds" }] } // 需要删除的 _id
        }
    }
]).forEach(function(doc) {
    // 删除所有多余的 _id
    if (doc.deleteIds.length > 0) {
        db.device_data.remove({ _id: { $in: doc.deleteIds } });
    }
});

脚本说明

1.分组:使用$group按deviceCode和calcBeginDate分组,将重复的_id收集到duplicateIds。

2.数据分离:保留第一条记录的_id(keepId),将其余的标记为需要删除的记录(deleteIds)。

3.删除操作:遍历结果,对deleteIds 中的文档执行删除。

3、数据去重后的索引优化

场景

在清理数据后,为了避免重复数据再次出现,可以为集合创建唯一索引。

解决方案

为deviceCode 和calcBeginDate 创建复合唯一索引,确保每个设备每月只有一条记录。

索引创建脚本

db.device_data.createIndex(
    { deviceCode: 1, calcBeginDate: 1 },
    { unique: true }
);

注意事项

1.在创建唯一索引前,必须确保数据中没有重复记录,否则索引创建会失败。

2.索引创建成功后,重复插入相同键值对的操作将会报错。

总结

通过以上方法,可以实现以下目标:

1.批量生成数据:高效插入多条满足特定条件的数据。

2.删除重复数据:清理因脚本多次执行或其他原因导致的重复记录。

3.防止重复数据再次出现:通过创建唯一索引,从数据层面杜绝重复。

在实际操作中,建议先备份数据,确保脚本执行安全可靠。同时,可以将这些脚本封装为工具类或定期任务,进一步提升效率。

责任编辑:华轩 来源: 微技术之家
相关推荐

2021-04-08 10:55:53

MySQL数据库代码

2024-10-16 17:04:13

2009-02-24 22:51:07

EMC闪存重复数据删除

2019-08-07 09:52:34

数据库MySQLSQL

2021-06-28 10:25:47

MySQL数据库重复数据

2023-02-23 07:46:48

学习模型数据仓库

2011-04-13 13:05:14

重复数据删除

2021-09-14 13:15:43

MySQL数据库脚本

2022-11-01 08:02:04

2011-04-13 13:13:09

重复数据删除

2023-01-03 07:44:53

MySQL查询重复

2021-11-30 10:00:01

SQL数据重复

2023-02-26 23:31:01

SQL数据库

2010-05-07 15:48:38

Oracle数据库

2010-07-07 16:53:54

SQL Server重

2010-11-03 13:50:49

DB2删除重复数据

2015-10-23 16:40:21

DB2删除数据

2016-08-23 13:35:22

MVCEFNuGet

2009-01-11 17:32:03

Oracle数据库重复数据

2010-04-08 16:28:07

Oracle数据库
点赞
收藏

51CTO技术栈公众号