根据对象中的值更新MongoDB集合

时间:2020-07-17 19:34:11

标签: javascript node.js mongodb typescript mongoose

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

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

我有一个Stock_Prices 对象,像这样:

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

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

我想到了以下方法:

  • 遍历收集文件
  • 对于每个文档,获取“库存”字段值(GOOGLE,FACEBOOK)
  • Stock_Prices[document.stock].price提取价格
  • 更新文档

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

更新:没有必要,应该进行更新操作-如果是查找,那么也可以完成我认为的工作

我该怎么做?

2 个答案:

答案 0 :(得分:1)

您必须将您的对象转换为数组,然后将其传递到聚合管道。

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。那应该更有表现。

答案 1 :(得分:0)

我将从帖子中取出一个股票对象,并演示如何更新:

var stock_price =  { "GOOGLE": { "price": 31.35 } }  // this is the input

var stock_price_doc = Object.keys(stock_price).map (k => ( {field: k, value: stock_price[k] } ) )[0]

stock_price_doc现在具有此值:{ "field" : "GOOGLE", "value" : { "price" : 31.35 } }

收藏集的文档(来自帖子):

{
    "stock": "GOOGLE",
    "price": 0
}

更新操作:

db.stocks.update(
  { stock: stock_price_doc.field },
  { $set: { price: stock_price_doc.value.price } }
)

更新后的文档(结果):

{ "stock" : "GOOGLE", "price" : 31.35 }

如果更新是为了增加股价,而不是设置,请使用以下值:

{ $inc: { price: stock_price_doc.value.price } }