首页 > 解决方案 > 根据对象的值更新 MongoDB 集合

问题描述

我有一个 MongoDB 集合,如下所示:

[
  {
    "stock": "GOOGLE",
    "price": 0
  },
  {
    "stock": "FACEBOOK",
    "price": 0
  }
]

我有一个这样的Stock_Prices 对象

{
  "GOOGLE": {
    "price": 31.35
  },
  "FACEBOOK": {
    "price": 10.75
  }
}

我需要Stock_Prices使用 Node.js 从对象更新集合中的每个股票。

我想到了以下方法:

这是一种不可接受的方法,因为我有成千上万的记录,并且需要立即更新。

更新:没有必要,它应该是一个更新操作——如果它是一个查找,那么我相信它也会做这个工作

我该怎么做?

标签: javascriptnode.jsmongodbtypescriptmongoose

解决方案


您必须获取对象并将其转换为数组并将其传递给聚合管道。

const stocksMap = {
  "GOOGLE": {
    "price": 31.35
  },
  "FACEBOOK": {
    "price": 10.75
  }
}

const stocks = Object.entries(stocksMap).map(([stock, price]) => ({ stock, price : price.price }))

/* You will get something like this
[{
  "stock": "GOOGLE",
  "price": 31.35
}, {
  "stock": "FACEBOOK",
  "price": 10.75
}]
*/

/* If you want to just read the data, without updating */

db.stocks.aggregate([
  {
    $set: {
      price: {
        $reduce: {
          input: stocks,
          initialValue: 0,
          in: {
            $cond: [
              { $eq: ["$$this.stock", "$stock"] },
              "$$this.price",
              "$$value"
            ]
          }
        }
      }
    }
  }
])

/* If you want to update the existing data, you can use the same pipeline in an aggregation (available from v4.2) */

db.stocks.update({}, [
  {
    $set: {
      price: {
        $reduce: {
          input: stocks,
          initialValue: 0,
          in: {
            $cond: [
              { $eq: ["$$this.stock", "$stock"] },
              "$$this.price",
              "$$value"
            ]
          }
        }
      }
    }
  }
])

如果您不想更新文档,可以放入stocks另一个集合并使用$lookup。那应该更高效。


推荐阅读