存档模式
如果需要存储多年前的历史数据,将最旧的数据与最新的数据存储在同一个数据库中,可能会对性能影响,尤其是在不需要经常访问旧数据的情况下。相反,您可以设计模式以存档旧数据并将该数据移动到单独的存储位置。
关于此任务
有多种存储存档数据的选项。示例,您可以:
将数据移动到外部文件存储,例如Amazon S3。
将数据移至成本更低的独立集群。
将数据移至同一集群上的单独集合。
在大多数情况下,就费用和性能而言,将数据移动到外部文件存储是最佳选择。如果您的使用案例无法实现外部文件存储,请考虑将数据移至单独的集群或集合。
数据存档技巧
在实现数据存档设计模式之前,查看以下最佳实践:
Scenario
在此示例中,一家电子商务存储希望存档五年多前发生的销售数据。初始数据集包含所有销售,较旧销售的文档将移动到单独的集合。
步骤
1
填充示例数据
db.sales.insertMany( [ { customer_name: "Hiroshi Tanaka", products: [ { product_id: "P1001", name: "Wireless Headphones", quantity: 1, price: 59.99 }, { product_id: "P1002", name: "Phone Charger", quantity: 2, price: 14.99 } ], total_amount: 89.97, date: ISODate("2025-01-30T10:15:00Z") }, { customer_name: "Aisha Khan", products: [ { product_id: "P1003", name: "Laptop", quantity: 1, price: 899.99 } ], total_amount: 899.99, date: ISODate("2018-11-20T15:45:00Z") // Over 5 years ago }, { customer_name: "Fatima Al-Farsi", products: [ { product_id: "P1006", name: "Gaming Mouse", quantity: 1, price: 49.99 }, { product_id: "P1007", name: "Mechanical Keyboard", quantity: 1, price: 129.99 } ], total_amount: 179.98, date: ISODate("2017-06-15T12:00:00Z") // Over 5 years ago }, { customer_name: "Nguyen Minh", products: [ { product_id: "P1008", name: "Bluetooth Speaker", quantity: 2, price: 39.99 } ], total_amount: 79.98, date: ISODate("2025-01-26T09:20:00Z") } ] )
2
编写脚本以存档旧文档
注意
以下脚本使用MongoDB Shell语法。要查看驾驶员的聚合和查询语法,请参阅驾驶员文档。
// Set a variable to five years before the time that the script runs const fiveYearsAgo = new Date(); fiveYearsAgo.setFullYear(fiveYearsAgo.getFullYear() - 5); // Write old sales to the 'archived_sales' collection const writeOldSalesPipeline = [ { $match: { date: { $lt: fiveYearsAgo } } }, { $merge: { into: { db: "test", coll: "archived_sales", }, on: "_id" } } ] db.sales.aggregate(writeOldSalesPipeline) // Delete old sales from the active 'sales' collection try { db.sales.deleteMany( { date : { $lt: fiveYearsAgo } } ); } catch (e) { print (e); }
结果
运行脚本后,sales
集合将不再包含五年前的销售额。
db.sales.find()
输出:
[ { _id: ObjectId('679ced18fa29d32ca7d1abab'), customer_name: 'Hiroshi Tanaka', products: [ { product_id: 'P1001', name: 'Wireless Headphones', quantity: 1, price: 59.99 }, { product_id: 'P1002', name: 'Phone Charger', quantity: 2, price: 14.99 } ], total_amount: 89.97, date: ISODate('2025-01-30T10:15:00.000Z') }, { _id: ObjectId('679ced18fa29d32ca7d1abae'), customer_name: 'Nguyen Minh', products: [ { product_id: 'P1008', name: 'Bluetooth Speaker', quantity: 2, price: 39.99 } ], total_amount: 79.98, date: ISODate('2025-01-26T09:20:00.000Z') } ]
旧销售现在存在于 archived_sales
集合中。
db.archived_sales.find()
输出:
[ { _id: ObjectId('679ced18fa29d32ca7d1abac'), customer_name: 'Aisha Khan', products: [ { product_id: 'P1003', name: 'Laptop', quantity: 1, price: 899.99 } ], total_amount: 899.99, date: ISODate('2018-11-20T15:45:00.000Z') }, { _id: ObjectId('679ced18fa29d32ca7d1abad'), customer_name: 'Fatima Al-Farsi', products: [ { product_id: 'P1006', name: 'Gaming Mouse', quantity: 1, price: 49.99 }, { product_id: 'P1007', name: 'Mechanical Keyboard', quantity: 1, price: 129.99 } ], total_amount: 179.98, date: ISODate('2017-06-15T12:00:00.000Z') } ]