Reputation: 349
I've been looking around and haven't seen any obvious answer to this question; sorry if there is and I missed it.
So I have a regular NodeJS + Mongo stack up right now, and it's working in general.
I'm working with a schema like such (simplified for the purposes of this question):
var ObjSchema = new Schema({
name: {
type: String,
default: '',
trim: true
},
description: String,
images: [ImageSchema],
...
});
Now, I don't want to go to the trouble of making actual images matching ImageSchema in the database, and according to this, you can apparently insert documents into a db even if they don't match the collection schema. So, instead of a list of objects matching the ImageSchema, for testing purposes, I'm just putting a list of URLs when I insert (manually, again for testing purposes).
In the interactive mongo shell, I've done the equivalent of:
db.objects.insert( { name: "Object", description: "My Collection", images: ["http://www.blah.com/img.jpg", "http://foo.com/another.jpg"]... })
The interactive mongo shell tells me that this is fine, and gives me the "Inserted into db" jazz. When I do db.objects.find(), the BSON shows up correctly as I entered it, with a list of strings for 'images' instead of something matching the ImageSchema specified.
Now here's the rub. I do the exact same command in Node instead of the interactive shell, and the BSON object I get is the equivalent of this:
{
_id: 54a9ede2da41c93989d3258d,
description: 'My Collection',
images:[], // THIS IS THE PROBLEM
name: 'Object'
}
As you can see, the other fields are fine; the search is properly retrieving the object and all the fields which match the schema are okay. However, in the Node search, the images attribute of this document is an empty list, whereas db.objects.find() gives me the list of URLs I inserted for testing purposes.
What's going on? Any idea how to get the URLs in the image attribute when pulling with Node?
The command I'm using is the equivalent of:
Object.find({'name': 'object'}, function(err, obj) {
and I'm using console.log(obj).
Upvotes: 0
Views: 2233
Reputation: 151072
The very short case here is the MongoDB is "schemaless" but Mongoose as an ODM layer is not. It is intended to enforce schema rules such as types and expected fields.
If you want to add data that does not match the schema you can always use the strict
option as in:
var ObjSchema = new Schema({
name: {
type: String,
default: '',
trim: true
},
description: String,
images: [ImageSchema],
...
},{ "strict": false }); // Last line is important here
But actually considering your sample data, this only differs in how the sub-document array is concerned where these are only strings. Using a "schema" for the array elements, you can omit the required "_id
" values by a similar property on the schema creation:
var ImageSchema = new Schema({
"url": String
},{ "_id": false });
var ObjSchema = new Schema({
name: {
type: String,
default: '',
trim: true
},
description: String,
images: [ImageSchema],
...
},{ "strict": false }); // Last line is important here
That is okay for data like:
[{ "url": "http://www.blah.com/img.jpg" }, { "url": "http://foo.com/another.jpg" }]
But for pure strings, then just define a String
type without the schema definition:
var ObjSchema = new Schema({
name: {
type: String,
default: '',
trim: true
},
description: String,
images: [String],
...
},{ "strict": false }); // Last line is important here
So choose what you need, but for the data you are presenting this is just an array of String
data and does not require a schema definition for it.
Upvotes: 1