node.js - MongoDB:如何插入子文档?

标签 node.js mongodb subdocument

我在 MEAN 项目中使用子文档来处理订单和每个订单的项目。

这些是我的(简化的)架构:

var itemPerOrderSchema = new mongoose.Schema({
  itemId: String,
  count: Number
});
var OrderSchema = new mongoose.Schema({
  customerId: String,
  date: String,
  items: [ itemPerOrderSchema ]
});

要在 itemPerOrderSchema 数组中插入项目,我目前正在执行以下操作:

var orderId = '123';
var item = { itemId: 'xyz', itemsCount: 7 };
Order.findOne({ id: orderId }, function(err, order) {
  order.items.push(item);
  order.save();
});

问题是我显然想要每个 itemId 一个项目,这样我就可以为每个项目获取许多子文档...
一种解决方案可能是循环遍历所有 order.items,但这当然不是最佳选择(order.items 可以很多.. .)。 查询 order.items...

时可能会出现同样的问题

问题是:如何在 itemPerOrderSchema 数组中插入项目,而不必循环遍历订单中已插入的所有项目?

最佳答案

如果您可以使用对象而不是数组来存储项目,也许您可​​以稍微更改架构以进行单查询更新。

类似这样的事情:

{
  customerId: 123,
  items: {
     xyz: 14,
     ds2: 7
  }
}

因此,每个 itemId 都是对象中的键,而不是数组的元素。

let OrderSchema = new mongoose.Schema({
  customerId: String,
  date: String,
  items: mongoose.Schema.Types.Mixed
});

那么更新您的订单就非常简单了。假设您要向客户 123 添加 3 个编号为“xyz”的商品。

db.orders.update({
  customerId: 123
},
{
  $inc: {
    'items.xyz': 3
  }
}, 
{
  upsert: true
});

即使客户没有条目,也可以在此处传递 upsert 以创建订单。

这样做的缺点:

  • 如果您使用聚合框架,则无法迭代您的项目,或者如果您有一组有限的已知 itemId,则非常冗长。您可以使用 mapReduce 来解决这个问题,这可能会慢一点,具体取决于您有多少个,所以 YMMB。

  • 您在客户端上没有干净的 items 数组。您可以通过任一客户端提取此信息来解决此问题(一个简单的 let items = Object.keys(order.items).map(key => ({ key: order.items[key] })); 或者使用 mongoose 虚拟字段或 schema.path(),但这可能是另一个问题,已经回答了。

关于node.js - MongoDB:如何插入子文档?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34706536/

相关文章:

node.js - 在不注册路由模块的情况下创建 ExpressJS 路由

node.js - 如何保护 express.js 中的路由?

node.js - 阻止 Mongoose 为子文档数组项创建 _id 属性

mongodb - 如何自动更新插入子文档?

javascript - 使用 JSON 格式的 Node.JS 从 MySQL 中检索数据

node.js - 使用 docker 镜像的 Azure Linux 应用服务中的 Mongo 连接错误

mongodb - Chef cookbook 创建 MongoDB 用户

node.js - 使用代理后面的 Mongoose 连接到 MongoDB 数据库

node.js - Mongoose for var in loop 在子文档中

javascript - 使用 NodeJS 保存填充模型