Nodejs mongoose有熟悉的吗?求教

Nodejs mongoose有熟悉的吗?求教

我最近用mongoose从mongodb取数据遇到下面这样的问题,求高手解答。

Order.find(query, function(err, orders) {
  if(err) console.log(err);
  orders.forEach(function(order){
    order.friendly_date = dateUtil.format_date(order.date, true);
  });
  res.send(orders);
});

这里我发现friendly_date 根本写不进去,传到页面上的orders里 压根没这个key。这是为什么呢?我看nodeClub也这样用,为什么它就可以?

多谢多谢


6 回复

当然可以!让我们来详细分析一下这个问题,并提供一些示例代码来帮助你理解。

问题描述

你在使用 Mongoose 查询 MongoDB 数据时,发现将 friendly_date 添加到查询结果中的 order 对象时,该字段并没有被保存或传递到前端。这可能是由于 Mongoose 文档对象的特性导致的。

分析

Mongoose 是一个用于 Node.js 的对象模型工具(ODM),它为 MongoDB 提供了一种更方便的数据操作方式。当你通过 Mongoose 查询数据库时,返回的是一个 Mongoose 文档对象,而不是普通的 JavaScript 对象。这些文档对象有一些特殊的属性和方法,可能会导致一些意想不到的行为。

在你的代码中,你尝试直接修改 order 对象的属性 friendly_date,但因为 Mongoose 文档对象的特殊性,这种修改可能不会被持久化或者在发送响应时丢失。

解决方案

你可以将 Mongoose 文档对象转换为普通 JavaScript 对象,然后再进行修改。Mongoose 文档对象有一个 toObject 方法,可以将其转换为普通的 JavaScript 对象。这样修改后的属性就会被正确地包含在最终的响应中。

示例代码

const Order = require('./models/Order'); // 假设你的 Order 模型定义在这个路径下
const dateUtil = require('./utils/dateUtil'); // 假设你的日期格式化工具定义在这个路径下

// 查询订单数据
Order.find(query, function(err, orders) {
  if (err) {
    console.error(err);
    return res.status(500).send('Internal Server Error');
  }

  // 将每个 Mongoose 文档对象转换为普通 JavaScript 对象
  const ordersObj = orders.map(order => order.toObject());

  // 遍历每个订单并添加 friendly_date 属性
  ordersObj.forEach(order => {
    order.friendly_date = dateUtil.format_date(order.date, true);
  });

  // 发送最终的响应
  res.send(ordersObj);
});

解释

  1. 查询订单数据:使用 Order.find 方法查询 MongoDB 中的订单数据。
  2. 错误处理:如果查询过程中发生错误,立即返回错误信息。
  3. 转换为普通对象:使用 map 方法将每个 Mongoose 文档对象转换为普通的 JavaScript 对象。
  4. 添加 friendly_date 属性:遍历每个订单对象并添加 friendly_date 属性。
  5. 发送响应:将修改后的订单数组发送给客户端。

通过这种方式,你可以确保 friendly_date 属性能够正确地被添加到每个订单对象中,并且在发送响应时不会丢失。希望这个解决方案能解决你的问题!


貌似mongose不能赋值schame中没有的,可以先复制出来,再赋值。 clone()

多谢 是的我现在就是这么做的,我用的是 var orderJson = order.toObject(). orderJson.xx = xx; 感觉有点麻烦。

实际上我察看了一下,如果直接给order.friendly_date赋值的话,内存里也能看到,就是res.send(model)貌似调用了model的什么方法,不会直接把model的属性拷贝出来。

vitual path来代替吧,避免每个逻辑里面都去做赋值操作。

用虚拟属性,没有定义的属性是不会写进去的。虚拟属性的好处就是写不进数据库~还能让你想用就用

根据你的描述,friendly_date 没有被正确地添加到 orders 数组中的每个 order 对象里,可能是因为 Mongoose 文档对象在被发送到客户端之前已经被克隆或序列化了。Mongoose 文档对象有一些特殊的属性和方法,在转换为普通 JavaScript 对象时,这些特殊属性和方法可能会丢失。

你可以尝试将 Mongoose 文档对象转换成普通的 JavaScript 对象,然后再进行操作:

Order.find(query, function(err, orders) {
  if (err) {
    console.log(err);
    return res.status(500).send({ message: 'Error fetching orders' });
  }

  // 将 Mongoose 文档转换为普通对象
  const ordersObj = orders.map(order => order.toObject());

  ordersObj.forEach(order => {
    order.friendly_date = dateUtil.format_date(order.date, true);
  });

  res.send(ordersObj);
});

解释:

  1. 查询订单:使用 Order.find 查询数据库中的所有订单。
  2. 错误处理:如果查询过程中发生错误,返回一个包含错误信息的响应,并设置状态码为 500。
  3. 转换文档:使用 map 方法将 Mongoose 文档转换为普通 JavaScript 对象。order.toObject() 方法会返回一个普通对象,这样就可以对这个对象进行任意修改。
  4. 格式化日期:遍历每个订单对象并添加 friendly_date 属性。
  5. 发送响应:将处理后的订单数组发送给客户端。

这样做可以确保你在修改对象时不会因为 Mongoose 文档的特殊性而导致数据丢失。希望这能解决你的问题!

回到顶部