【问题标题】:Fatest way to check if an item exist in a collection?检查集合中是否存在项目的最快方法?
【发布时间】:2023-03-22 03:32:01
【问题描述】:

我对性能问题有些担心。我有一个每分钟运行一次的 cron,它会更新一个集合。

每分钟从外部 API 获取 10,000 笔新交易。其中一些交易记录已经在我的数据库中。

for (transaction in transactions) {
    if (Transaction.findOne(_id: transactionId, { _id: 1}))
        console.log("Already in db");
    else
        Transaction.insert(transaction)    

为了加快速度,我将整个集合加载到内存中,并且只插入到我的脚本末尾。

const toInsert = [];

const transactions = await Transaction.find().select(_id);
// I transform array of transactions to an object of transaction where key is _id, thus i can avoid using a find at every iteration
const transactionsObject = transactions.reduce((obj, transaction) => {
     obj[transaction.id] = true;
     return obj;
   }, {})

for (transaction in transactions) {
    if (transactionsObject[transactionId])
        console.log("Already in db");
    else {
        toInsert.push(transaction);
        transactionsObject[transaction._id] = true;
}

Transaction.insertMany(toInsert);

使用我的脚本的这个版本,脚本非常快,但我对可伸缩性有些担心,因为我需要大量内存,如果我需要线程化,我需要在线程之间共享所有内容。

您将如何优化脚本?

【问题讨论】:

  • 交易是指“货币交易”而不是 ACID 交易,对吧? (这就是它的样子——我只是想澄清一下)
  • 我的意思是货币交易是的
  • “集合”在哪里(在“加载到内存”之前)?

标签: arrays mongodb performance optimization find


【解决方案1】:

让 mongo 计算它丢失的文档可能是有意义的。一种优化是只找到您关心的交易的 id:

const transactionIds = await Transaction.find({_id: {$in: listOfIds}}).select(_id);

更快的替代方法是在您的 id 上创建一个唯一索引(默认 _id 字段已经有一个唯一索引),然后尝试插入所有带有 {ordered: false} 的文档。有些插入会失败,但让 mongo 进行计算会更快。

ordered [set] 为 false 时,插入操作 [将] 继续处理任何剩余的文档。 https://docs.mongodb.com/manual/reference/method/db.collection.insertMany/

> db.test.insertMany([{_id: 1}], { ordered: false })
{ "acknowledged" : true, "insertedIds" : [ 1 ] }
> db.test.insertMany([{_id: 1}, {_id: 2}], { ordered: false })
2019-07-03T16:25:54.402+0000 E QUERY    [js] BulkWriteError: write error at item 0 in bulk operation :
BulkWriteError({
    "writeErrors" : [
        {
            "index" : 0,
            "code" : 11000,
            "errmsg" : "E11000 duplicate key error collection: test.test index: _id_ dup key: { : 1.0 }",
            "op" : {
                "_id" : 1
            }
        }
    ],
    "writeConcernErrors" : [ ],
    "nInserted" : 1,
    "nUpserted" : 0,
    "nMatched" : 0,
    "nModified" : 0,
    "nRemoved" : 0,
    "upserted" : [ ]
})

【讨论】:

    猜你喜欢
    • 2013-08-12
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 2017-05-11
    • 2010-11-07
    • 2012-03-10
    • 2022-06-06
    • 1970-01-01
    相关资源
    最近更新 更多