【问题标题】:Convert Mongoose docs to json将 Mongoose 文档转换为 json
【发布时间】:2012-04-14 17:01:58
【问题描述】:

我以这种方式将猫鼬文档作为 json 返回:

UserModel.find({}, function (err, users) {
    return res.end(JSON.stringify(users));
}

然而,user.__proto__ 也被返回了。没有它我怎么能回来?我试过了,但没有奏效:

UserModel.find({}, function (err, users) {
    return res.end(users.toJSON());    // has no method 'toJSON'
}

【问题讨论】:

    标签: json node.js object document mongoose


    【解决方案1】:

    考虑到这一定非常普遍,我有点笑这有多麻烦。

    没有费心去挖掘文档,而是一起破解了这个。

            const data =   await this.model.logs.find({ "case_id": { $regex: /./, $options: 'i' }})              
            let res = data.map(e=>e._doc)
            res.forEach(element => {
                //del unwanted data
                delete element._id
                delete element.__v
            });
            return res
    
    1. 首先,我获取所有对 case_id 字段具有任何值的文档(只需获取集合中的所有文档)
    2. 然后通过array.map从mongoose文档中获取实际数据
    3. 通过直接改变 i 来移除对象上不需要的道具

    【讨论】:

      【解决方案2】:

      试试这个选项:

        UserModel.find({}, function (err, users) {
          //i got into errors using so i changed to res.send()
          return res.send( JSON.parse(JSON.stringify(users)) );
          //Or
          //return JSON.parse(JSON.stringify(users));
        }
      

      【讨论】:

        【解决方案3】:

        它对我有用:

        Products.find({}).then(a => console.log(a.map(p => p.toJSON())))


        如果你想使用 getter,你也应该添加它的选项(在定义模式时):

        new mongoose.Schema({...}, {toJSON: {getters: true}})

        【讨论】:

          【解决方案4】:

          可能有点误入歧途,但如果有人想反其道而行之,您可以使用 Model.hydrate()(自 mongoose v4 起)将 javascript 对象 (JSON) 转换为 mongoose 文档。

          一个有用的例子是当你使用Model.aggregate(...)。因为它实际上返回的是纯 JS 对象,所以您可能希望将其转换为 mongoose 文档以便访问 Model.method(例如,您在架构中定义的虚拟属性)。

          附言。我认为它应该有一个像“Convert json to Mongoose docs”这样运行的线程,但实际上没有,因为我已经找到了答案,所以我认为自我发布不好-and-self-answer.

          【讨论】:

            【解决方案5】:

            您可以使用 res.json() 对任何对象进行 json 化。 lea() 将删除 mongoose 查询中的所有空字段。

            UserModel.find().lean().exec(function (err, users) { return res.json(users); }

            【讨论】:

              【解决方案6】:

              迟到的答案,但您也可以在定义架构时尝试这样做。

              /**
               * toJSON implementation
               */
              schema.options.toJSON = {
                  transform: function(doc, ret, options) {
                      ret.id = ret._id;
                      delete ret._id;
                      delete ret.__v;
                      return ret;
                  }
              };
              

              请注意,ret 是 JSON 对象,它不是 mongoose 模型的实例。您将直接在对象哈希上对其进行操作,而无需 getter/setter。

              然后:

              Model
                  .findById(modelId)
                  .exec(function (dbErr, modelDoc){
                       if(dbErr) return handleErr(dbErr);
              
                       return res.send(modelDoc.toJSON(), 200);
                   });
              

              编辑:2015 年 2 月

              因为我没有为缺少的 toJSON(或 toObject)方法提供解决方案,所以我将解释我的用法示例和 OP 的用法示例之间的区别。

              操作:

              UserModel
                  .find({}) // will get all users
                  .exec(function(err, users) {
                      // supposing that we don't have an error
                      // and we had users in our collection,
                      // the users variable here is an array
                      // of mongoose instances;
              
                      // wrong usage (from OP's example)
                      // return res.end(users.toJSON()); // has no method toJSON
              
                      // correct usage
                      // to apply the toJSON transformation on instances, you have to
                      // iterate through the users array
              
                      var transformedUsers = users.map(function(user) {
                          return user.toJSON();
                      });
              
                      // finish the request
                      res.end(transformedUsers);
                  });
              

              我的例子:

              UserModel
                  .findById(someId) // will get a single user
                  .exec(function(err, user) {
                      // handle the error, if any
                      if(err) return handleError(err);
              
                      if(null !== user) {
                          // user might be null if no user matched
                          // the given id (someId)
              
                          // the toJSON method is available here,
                          // since the user variable here is a 
                          // mongoose model instance
                          return res.end(user.toJSON());
                      }
                  });
              

              【讨论】:

              • 这是最好的方法。
              • @eAbi toJSON 和 toObject 都没有定义
              • @OMGPOP toJSON 和 toObject 都是在 mongoose 模型实例上定义的方法。您可以提供您的使用示例或在 stackoverflow 上发布另一个问题。据我所知,无论使用哪种 Mongoose 版本,toJSON 和 toObject 方法都没有被弃用/删除。
              • @eAbi 它不存在。提问者也有同样的问题。你确定你调用的是 toJSON 而不是 JSON.stringify()?
              • @OMGPOP 是的,我确定我使用的是 toJSON 方法。 OP 的使用示例和我的不同之处在于,在 OP 的问题中,返回的 users 变量是一个猫鼬实例数组。您必须遍历数组并在每个实例上调用 toJSON 方法。在我的示例中,我使用 findById 方法,该方法直接将找到的 mongoose 实例传递给回调函数。然后就可以直接在这个实例上调用toJSON(或toObject)方法了。
              【解决方案7】:
              model.find({Branch:branch},function (err, docs){
                if (err) res.send(err)
              
                res.send(JSON.parse(JSON.stringify(docs)))
              });
              

              【讨论】:

              • 这是这个问题的最佳答案。隐藏猫鼬技术领域的“魔法”似乎隐藏在 JSON.stringify 背后的某个地方。
              • 你知道为什么吗?
              【解决方案8】:

              你也可以试试 mongoosejs 的lean()

              UserModel.find().lean().exec(function (err, users) {
                  return res.end(JSON.stringify(users));
              }
              

              【讨论】:

              • 不应该是:JSON.stringify(users);,因为使用 lean() 返回的文档是普通的 JS 对象吗?
              • 是的,你是对的,谢谢。应该使用 JSON.stringify(users)。
              • 如果查询完数据库后,还想在回调函数中使用mongoose实例对象,就不应该使用lean函数。请参阅我的答案以获取解决方案。 :)
              • 当心,lean() 将删除虚拟属性
              • 缺少右括号
              【解决方案9】:

              我发现我犯了一个错误。根本不需要调用 toObject() 或 toJSON()。问题中的 __proto__ 来自 jquery,而不是猫鼬。这是我的测试:

              UserModel.find({}, function (err, users) {
                  console.log(users.save);    // { [Function] numAsyncPres: 0 }
                  var json = JSON.stringify(users);
                  users = users.map(function (user) {
                      return user.toObject();
                  }
                  console.log(user.save);    // undefined
                  console.log(json == JSON.stringify(users));    // true
              }
              

              doc.toObject() 从文档中删除 doc.prototype。但它在 JSON.stringify(doc) 中没有任何区别。在这种情况下不需要它。

              【讨论】:

                【解决方案10】:

                首先,试试toObject() 而不是toJSON() 可能吗?

                其次,您需要在实际文档而不是数组上调用它,所以不妨试试这样更烦人的方法:

                var flatUsers = users.map(function() {
                  return user.toObject();
                })
                return res.end(JSON.stringify(flatUsers));
                

                这是一个猜测,但我希望它有所帮助

                【讨论】:

                • 必须映射它很烦人,图书馆里没有东西可以做到吗?
                猜你喜欢
                • 2018-06-01
                • 1970-01-01
                • 2015-05-09
                • 1970-01-01
                • 2016-07-13
                • 2017-06-01
                相关资源
                最近更新 更多