最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Is there a native feature to convert string based JSON into Mongoose Schema object instance? - Stack Overflow

programmeradmin0浏览0评论

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):

{
  "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???

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):

{
  "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???

Share Improve this question asked Aug 21, 2012 at 3:31 Renato GamaRenato Gama 16.5k12 gold badges60 silver badges98 bronze badges 3
  • 1 "Notice that the first object comes from the request, so its made entirely by Strings." - Why don't you change it to return a number and a boolean in the appropriate places? Your use of "so" in the sentence I quoted implies only strings are permitted, but that's not true if it is JSON. (That is, JSON itself is a string-based format, but it can represent numbers and booleans, and when the JSON is parsed such properties become numbers and booleans...) – nnnnnn Commented Aug 21, 2012 at 3:59
  • Are the properties in your schema fixed, or do you need them dynamic? – Mahn Commented Aug 21, 2012 at 4:07
  • @nnnnnn Well, the problem is that Express grabs the info from the form myObject[name]:name, myObject[someNumber]:23, and Express itself constructs the myObject by default setting every property to an String! – Renato Gama Commented Aug 21, 2012 at 4:08
Add a comment  | 

3 Answers 3

Reset to default 11

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

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!

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:

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

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

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:

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.

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.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论