gpt4 book ai didi

node.js - 如何为大量条目提高 Mongoose/MongoDB 创建和更新性能

转载 作者:行者123 更新时间:2023-12-04 08:26:26 25 4
gpt4 key购买 nike

我有一个使用 Mongoose/MongoDB 的 Express 应用程序,我希望找到最有效的方法来批量创建/更新(如果可能,所有这些都在单个数据库操作中?)。
用户在前端上传 CSV,该 CSV 转换为对象的 JSON 数组并发送到 Express 后端。该数组的范围从~3000 个条目到~50,000 个以上,通常是需要创建的新条目和需要更新的现有条目的组合。每个条目称为一个交易。
这是我目前的(性能不是很好)解决方案:

const deals = [
{ deal_id: '887713', foo: 'data', bar: 'data' },
{ deal_id: '922257', foo: 'data', bar: 'data' }
] // each deal contains 5 key/value pairs in the real data array
const len = deals.length
const Model = models.Deal
let created = 0
let updated = 0
let errors = 0
for (let i = 0; i < len; i++) {
const deal = deals[i]
const exists = await Model.findOne({ deal_id: deal.deal_id })
if (exists) {
exists.foo = deal.foo
exists.bar = deal.bar
await exists.save()
updated += 1
} else {
try {
await Model.create(deal)
created += 1
} catch (e) {
errors += 1
}
}
}
目前 findOne/save 或 findOne/create 的组合对于每笔交易大约需要 200-300 毫秒。对于 3000 个条目的低端,需要 10-15 分钟来处理。
如果有帮助,我对绕过 Mongoose 和直接使用 Mongo 并不公正。
如果可能的话,我想保持计算更新和创建的项目数量以及错误数量的能力(这是在响应中发送的,目的是让用户对成功和失败的事情有一些感觉)——但这不重要。
提前致谢! :)

最佳答案

您希望以尽可能少的数据库请求来执行此操作。
首先,您可以在一个 find 中获取所有相关文档。陈述。 https://docs.mongodb.com/manual/reference/operator/query/in/

const deals = [
{ deal_id: '887713', foo: 'data', bar: 'data' },
{ deal_id: '922257', foo: 'data', bar: 'data' }
]
const ids = deals.map(deal => deal.deal_id) // An array of all deal_id
const documents = await Model.find({ deal_id: { $in: ids }})
现在我们将使用属性 upsert 进行一个查询来更新所有内容。设置为 true . https://docs.mongodb.com/manual/reference/method/db.collection.update/
这将确保如果文档不存在,则自动创建它。
通过批量更新(同时更新多个),最有效的方法是绕过 mongoose 并通过命令 bulkWrite 直接使用 mongodb 驱动程序。 . https://docs.mongodb.com/manual/reference/method/db.collection.bulkWrite/
const operations = deals.map(deal => {
updateOne: {
filter: {
deal_id: deal.deal_id
},
update: {
$set: deal
},
upsert: true
}
})

const result = await Model.collection.bulkWrite(operations, { ordered: false })
上面我也设置了 { ordered: false }它只是告诉 MongoDB“尽可能快地插入,而不考虑我刚刚给你的数组的顺序”。
它还会继续插入其余的文档,即使其中一个失败。在bulkWrite 文档页面下也有说明。
批量写入的结果对象如下所示
{
"acknowledged" : true,
"deletedCount" : 1,
"insertedCount" : 2,
"matchedCount" : 2,
"upsertedCount" : 0,
"insertedIds" : {
"0" : 4,
"1" : 5
},
"upsertedIds" : {

}
}
这意味着您将获得一个列表,其中包含您获得的匹配项、更新了多少项以及创建了哪些文档 (upsertedIds)。这在bulkWrite 的文档中也有说明。
大型数据集的一个好做法是将 bulkWrite 分块到较少操作的数组中以提高性能。一个中小型 MongoDB 服务器应该可以同时处理几千个文档。
请注意,没有测试任何代码示例。但目标是为您指明正确的方向并了解一些好的做法。祝你好运!

关于node.js - 如何为大量条目提高 Mongoose/MongoDB 创建和更新性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65242537/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com