是否有一个本地特性可以将基于JSON的字符串转换为Mongoose Schema对象实例?

时间:2021-09-24 02:35:28

I am using Express and I am looking for a convenient way to convert this kind of object (which comes on the request req.body.myObject):

我正在使用Express,我正在寻找一种方便的方式来转换这类对象(请求req.body.myObject):

{
  "name": "Foo",
  "someNumber": "23",
  "someBoolean": "on"
}

Into an instance of this Schema:

将它转换为这个模式的一个实例:

var myObjectSchema = new Schema({
    name: String,
    someNumber: Number,
    someBoolean: Boolean
});

Notice that the first object comes from the request, so its made entirely by Strings.

注意,第一个对象来自请求,因此它完全由字符串构成。

Is there some nice way to achieve this? If not, would you have any suggestions on how to implement this feature as a middleware???

有什么好办法可以做到这一点吗?如果没有,您对如何将这个特性作为中间件来实现有什么建议吗?

3 个解决方案

#1


10  

By referring to this thread Mongoose : Inserting JS object directly into db I figured out that yes, theres a built in feature for this.

通过引用这个线程Mongoose:将JS对象直接插入到db中,我发现是的,这是内置的特性。

You simply build a new model passing request values (from the form) as parameters:

您只需构建一个新模型,将请求值(从表单)传递为参数:

function add(req, res){
    new Contact(req.body.contact).save(function(err){
        console.log("Item added");
        res.send();
    });
};

It automatically converts stuff for you!

它自动为你转换东西!

#2


2  

I know this answer has already been accepted, but I wanted to point out that mongoose takes care of most of the casting for you... most of the time. While it's convenient that mongoose does this, it abstracts away the true behavior of mongo. For example, mongoose lets you do something like this:

我知道这个答案已经被接受了,但我想指出的是,猫鼬会照顾你的大部分角色。大部分的时间。蒙古鹿这样做很方便,但它将蒙哥的真实行为抽象了出来。例如,mongoose允许你做以下事情:

PersonModel.findById("4cdf00000000000000007822", ...);

However, if you tried to query the database directly (without mongoose), this would not work:

但是,如果您试图直接查询数据库(没有mongoose),这将不起作用:

PersonCollection.find({_id: "4cdf00000000000000007822"}, ...);

This is because ObjectIds are not strings... they are objects. Internally, mongoose converts that string to an ObjectId and then performs a query against the database so that the final query looks kinda like this:

这是因为objective不是字符串。它们是对象。在内部,mongoose将该字符串转换为一个objective,然后对数据库执行查询,这样最终的查询看起来就像这样:

PersonCollection.find({_id: ObjectId("4cdf00000000000000007822")}, ...);

Also, each path in a schema has a "caster" method. This is a private method, but it's darn handy when you need it. PLEASE NOTE THAT THE caster METHODS DESCRIBED BELOW ARE UNDOCUMENTED AND CAN CHANGE WITHOUT WARNING. USE AT YOUR OWN RISK (sorry for yelling):

此外,模式中的每个路径都有一个“脚轮”方法。这是一个私有方法,但是当您需要它时,它非常方便。请注意,下面描述的施法者方法没有文档说明,可以在没有警告的情况下更改。用在你自己的风险(抱歉大声喊出来):

// Use PersonModel.schema.paths() to get all paths and loop over them if you want
var key = "name";
var pathObj = PersonModel.schema.path( key );
if( !pathObj ) pathObj = PersonModel.schema.virtualpath( key );
if( !pathObj ) { /* not found: return, continue, exit, whatever */ }

// UNDOCUMENTED: USE AT YOUR OWN RISK
var caster = pathObj.caster || pathObj;
var castedValue = caster.cast( req.body.name );

Why do I know this? Because if you want to use some of the more advanced features of mongo such as aggregation, you will need to cast your own values as you build the pipeline. I have also needed to manually cast values for certain queries which used the $in operator... maybe this is not needed any more. Point is, if you are having trouble getting the results you expect, try casting the values yourself.

为什么我知道这个?因为如果您想要使用mongo的一些更高级的特性,比如聚合,您需要在构建管道的过程中使用自己的值。我还需要为使用$in操作符的某些查询手动转换值……也许这已经不再需要了。重点是,如果您在获得预期的结果时遇到了困难,那么您可以自己尝试转换这些值。

#3


0  

Provided the schema is static, one could theoretically go the lazy, non-sophisticated way and just hardcode the values instead of passing the object itself:

假设模式是静态的,理论上可以采用惰性的、不复杂的方式,只对值进行硬编码,而不是传递对象本身:

var someObject = {
    name: "Foo",
    someNumber: "23",
    someBoolean: "on"
}

var myObjectSchema = new Schema({
    name: someObject.name,
    someNumber: parseInt(someObject.someNumber, 10),
    someBoolean: (someObject.someBoolean == "on")
});

Possibly not the answer you were looking for, but might be something to consider if nothing better is available.

可能不是你想要的答案,但是如果没有更好的答案的话,可能是需要考虑的。

#1


10  

By referring to this thread Mongoose : Inserting JS object directly into db I figured out that yes, theres a built in feature for this.

通过引用这个线程Mongoose:将JS对象直接插入到db中,我发现是的,这是内置的特性。

You simply build a new model passing request values (from the form) as parameters:

您只需构建一个新模型,将请求值(从表单)传递为参数:

function add(req, res){
    new Contact(req.body.contact).save(function(err){
        console.log("Item added");
        res.send();
    });
};

It automatically converts stuff for you!

它自动为你转换东西!

#2


2  

I know this answer has already been accepted, but I wanted to point out that mongoose takes care of most of the casting for you... most of the time. While it's convenient that mongoose does this, it abstracts away the true behavior of mongo. For example, mongoose lets you do something like this:

我知道这个答案已经被接受了,但我想指出的是,猫鼬会照顾你的大部分角色。大部分的时间。蒙古鹿这样做很方便,但它将蒙哥的真实行为抽象了出来。例如,mongoose允许你做以下事情:

PersonModel.findById("4cdf00000000000000007822", ...);

However, if you tried to query the database directly (without mongoose), this would not work:

但是,如果您试图直接查询数据库(没有mongoose),这将不起作用:

PersonCollection.find({_id: "4cdf00000000000000007822"}, ...);

This is because ObjectIds are not strings... they are objects. Internally, mongoose converts that string to an ObjectId and then performs a query against the database so that the final query looks kinda like this:

这是因为objective不是字符串。它们是对象。在内部,mongoose将该字符串转换为一个objective,然后对数据库执行查询,这样最终的查询看起来就像这样:

PersonCollection.find({_id: ObjectId("4cdf00000000000000007822")}, ...);

Also, each path in a schema has a "caster" method. This is a private method, but it's darn handy when you need it. PLEASE NOTE THAT THE caster METHODS DESCRIBED BELOW ARE UNDOCUMENTED AND CAN CHANGE WITHOUT WARNING. USE AT YOUR OWN RISK (sorry for yelling):

此外,模式中的每个路径都有一个“脚轮”方法。这是一个私有方法,但是当您需要它时,它非常方便。请注意,下面描述的施法者方法没有文档说明,可以在没有警告的情况下更改。用在你自己的风险(抱歉大声喊出来):

// Use PersonModel.schema.paths() to get all paths and loop over them if you want
var key = "name";
var pathObj = PersonModel.schema.path( key );
if( !pathObj ) pathObj = PersonModel.schema.virtualpath( key );
if( !pathObj ) { /* not found: return, continue, exit, whatever */ }

// UNDOCUMENTED: USE AT YOUR OWN RISK
var caster = pathObj.caster || pathObj;
var castedValue = caster.cast( req.body.name );

Why do I know this? Because if you want to use some of the more advanced features of mongo such as aggregation, you will need to cast your own values as you build the pipeline. I have also needed to manually cast values for certain queries which used the $in operator... maybe this is not needed any more. Point is, if you are having trouble getting the results you expect, try casting the values yourself.

为什么我知道这个?因为如果您想要使用mongo的一些更高级的特性,比如聚合,您需要在构建管道的过程中使用自己的值。我还需要为使用$in操作符的某些查询手动转换值……也许这已经不再需要了。重点是,如果您在获得预期的结果时遇到了困难,那么您可以自己尝试转换这些值。

#3


0  

Provided the schema is static, one could theoretically go the lazy, non-sophisticated way and just hardcode the values instead of passing the object itself:

假设模式是静态的,理论上可以采用惰性的、不复杂的方式,只对值进行硬编码,而不是传递对象本身:

var someObject = {
    name: "Foo",
    someNumber: "23",
    someBoolean: "on"
}

var myObjectSchema = new Schema({
    name: someObject.name,
    someNumber: parseInt(someObject.someNumber, 10),
    someBoolean: (someObject.someBoolean == "on")
});

Possibly not the answer you were looking for, but might be something to consider if nothing better is available.

可能不是你想要的答案,但是如果没有更好的答案的话,可能是需要考虑的。