将猫鼬文档转换为json


76

我以这种方式将猫鼬文档作为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'
}

Answers:


148

您也可以尝试mongoosejs的lean()

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

1
好的,这似乎是答案。
Trantor Liu

9
应该不是:JSON.stringify(users);因为与一起返回的文档lean()是普通的JS对象?
enyo 2013年

是的,您说得对,谢谢。应该使用JSON.stringify(users)。
ecdeveloper 2013年

查询数据库后,如果仍要在回调函数中使用猫鼬实例对象,则不应使用该lean函数。见我的答案的解决方案。:)
eAbi 2014年

1
提防,lean()将删除虚拟属性
Emmanuel NK

53

答案较晚,但在定义架构时也可以尝试此操作。

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

请注意,这ret是JSON编辑的对象,它不是猫鼬模型的实例。您将直接在对象散列上对其进行操作,而无需使用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的用法示例之间的区别。

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());
        }
    });

3
这是最好的方法。
Daniel Kmak 2014年

toJSON()未定义
OMGPOP,2015年

没有定义
@JSON

@OMGPOP toJSON和toObject都是在猫鼬模型实例上定义的方法。您可以提供使用示例,也可以在stackoverflow上发布另一个问题。据我所知,无论使用什么Mongoose版本,都不会弃用/删除toJSON和toObject方法。
eAbi 2015年

2
@OMGPOP是的,我确定我正在使用toJSON方法。OP的用法示例和我的用法之间的区别在于,在OP的问题中,返回的users变量是猫鼬实例的数组。您必须遍历数组,并在每个实例上调用toJSON方法。在我的示例中,我使用的是findById方法,该方法将找到的猫鼬实例直接传递给回调函数。然后,您可以直接在此实例上调用toJSON(或toObject)方法。
eAbi 2015年

25

首先,尝试toObject()而不是尝试toJSON()

其次,您需要在实际文档上而不是在数组上调用它,因此也许尝试这样更烦人的事情:

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

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


必须映射它太烦人了,图书馆中没有要做的事情吗?
安东尼

15
model.find({Branch:branch},function (err, docs){
  if (err) res.send(err)

  res.send(JSON.parse(JSON.stringify(docs)))
});

这是此问题的最佳答案。隐藏猫鼬技术领域的“魔术”似乎隐藏在JSON.stringify之后。
mischka

8

我发现自己做错了。根本不需要调用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)中没有区别。在这种情况下是不需要的。


3

答案可能有些误入歧途,但是如果有人想采用其他方法,则可以使用Model.hydrate()(自mongoose v4起)将javascript对象(JSON)转换为mongoose文档。

使用时会是一个有用的情况Model.aggregate(...)。因为它实际上返回的是普通的JS对象,所以您可能需要将其转换为猫鼬文档才能访问Model.method(例如,在模式中定义的虚拟属性)。

PS。我以为它应该有一个像“将json转换为Mongoose docs ”那样运行的线程,但实际上没有,并且因为我已经找到了答案,所以我认为做自我发布和自我回答是不好的。


2

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

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


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));
  }

1

它为我工作:

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


另外,如果要使用getter,还应该添加其选项(在定义架构时):

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.