Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 基于对象中的值更新MongoDB集合_Javascript_Node.js_Mongodb_Typescript_Mongoose - Fatal编程技术网

Javascript 基于对象中的值更新MongoDB集合

Javascript 基于对象中的值更新MongoDB集合,javascript,node.js,mongodb,typescript,mongoose,Javascript,Node.js,Mongodb,Typescript,Mongoose,我有一个MongoDB集合,看起来像这样: [ { "stock": "GOOGLE", "price": 0 }, { "stock": "FACEBOOK", "price": 0 } ] { "GOOGLE": { "price": 31.35 }, "

我有一个MongoDB集合,看起来像这样:

[
  {
    "stock": "GOOGLE",
    "price": 0
  },
  {
    "stock": "FACEBOOK",
    "price": 0
  }
]
{
  "GOOGLE": {
    "price": 31.35
  },
  "FACEBOOK": {
    "price": 10.75
  }
}
我有一个
股价
对象如下:

[
  {
    "stock": "GOOGLE",
    "price": 0
  },
  {
    "stock": "FACEBOOK",
    "price": 0
  }
]
{
  "GOOGLE": {
    "price": 31.35
  },
  "FACEBOOK": {
    "price": 10.75
  }
}
我需要使用Node.js从
stock\u Prices
对象更新集合中的每个股票

我想到了以下方法:

  • 迭代收集文档
  • 对于每个文档,获取“股票”字段值(谷歌、FACEBOOK)
  • 股票价格[document.Stock].price中提取价格
  • 更新文档
这是一个不可接受的方法,因为我有成千上万的记录,需要立即更新

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


我该怎么做?

我将从帖子中选取一个库存对象,并演示如何更新:

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\u price\u doc
现在有这个值:
{“field”:“GOOGLE”,“value”:{“price”:31.35}

收藏的文档(从邮件中):

更新操作:

db.stocks.update(
  { stock: stock_price_doc.field },
  { $set: { price: stock_price_doc.value.price } }
)
更新后的文件(结果):

如果更新是增加股票价格,则使用以下方法代替设置值:

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

您必须将对象转换为数组并将其传递到聚合管道

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"
            ]
          }
        }
      }
    }
  }
])


如果您不想更新文档,可以将
库存
放入另一个集合中,并改用
$lookup
。这应该更有效。

你不能循环使用
Stock\u Prices
键并更新每个文档,而不检索所有文档,比如:
YourModel.updateOne(Stock,{price})
?这会有什么区别?我还在一个接一个地更新。你更新的报价中的最后一句话我还不太清楚。您想更新还是可以有一个聚合输出?非常感谢,但我仍然必须为每个公司创建
股票价格\u文档
,对吗?这仍然是一个一步一步的过程,对吗?你可以尝试不同的方法。一种方法是,您可以创建一个对象数组,对它们进行迭代,处理数组中的每个元素,并一次更新一个。这将需要多次访问服务器。为了避免这些错误,您可以使用(查找批量更新)将所有更新批量发送到服务器(这将是一个高效的操作)。谢谢我来看看!