使用 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.防止重復數據再次出現:通過創建唯一索引,從數據層面杜絕重復。
在實際操作中,建議先備份數據,確保腳本執行安全可靠。同時,可以將這些腳本封裝為工具類或定期任務,進一步提升效率。