Mongoose - Save array of strings
node.jsMongodbExpressMongoosenode.js Problem Overview
I can't save an array of strings into my DB using Mongoose
.
(Note all code below is simplified for ease of writing here)
So i declare a variable of a person schema I have:
var newPerson = new Person ({
tags: req.body.tags
});
The schema itself looks like:
var personSchema = new mongoose.Schema({
tags: Array
});
And when it comes to saving its just a simple:
newPerson.save(function(err) {
//basic return of json
});
So using Postman I send in an array in the body - however everytime I check the DB, it just shows one entry with the array as a whole i.e. how I sent it:
Any ideas what extra I'm supposed to do?
node.js Solutions
Solution 1 - node.js
Write up from my comment:
The way to specify an array of strings in mongoose is like so:
var personSchema = new mongoose.Schema({
tags: [{
type: String
}]
However, the problem here is most-likely to do with Postman as it is sending the 'array' as a string. You can check this by checking the type of req.body.tags
like so:
console.log(typeof req.body.tags)
If this returns a String, make sure to set the content-type in Postman to JSON as seen in this screenshot rather than the default 'form-data' option.
Solution 2 - node.js
var schema = new Schema({
name: String,
binary: Buffer,
living: Boolean,
updated: { type: Date, default: Date.now },
age: { type: Number, min: 18, max: 65 },
mixed: Schema.Types.Mixed,
_someId: Schema.Types.ObjectId,
decimal: Schema.Types.Decimal128,
array: [],
ofString: [String],
ofNumber: [Number],
ofDates: [Date],
ofBuffer: [Buffer],
ofBoolean: [Boolean],
ofMixed: [Schema.Types.Mixed],
ofObjectId: [Schema.Types.ObjectId],
ofArrays: [[]],
ofArrayOfNumbers: [[Number]],
nested: {
stuff: { type: String, lowercase: true, trim: true }
},
map: Map,
mapOfString: {
type: Map,
of: String
}
})
// example use
var Thing = mongoose.model('Thing', schema);
var m = new Thing;
m.name = 'Statue of Liberty';
m.age = 125;
m.updated = new Date;
m.binary = Buffer.alloc(0);
m.living = false;
m.mixed = { any: { thing: 'i want' } };
m.markModified('mixed');
m._someId = new mongoose.Types.ObjectId;
m.array.push(1);
m.ofString.push("strings!");
m.ofNumber.unshift(1,2,3,4);
m.ofDates.addToSet(new Date);
m.ofBuffer.pop();
m.ofMixed = [1, [], 'three', { four: 5 }];
m.nested.stuff = 'good';
m.map = new Map([['key', 'value']]);
m.save(callback);
Solution 3 - node.js
Try changing the schema to
var personSchema = new mongoose.Schema({
tags: [{type: String}]
});
or you can use Mixed type
var personSchema = new mongoose.Schema({
tags: mongoose.Schema.Types.Mixed
});
EDIT
i think the problem is with assignment. Use:
person.tags.push("string to push");
Solution 4 - node.js
- On Schema:
( Since you have mentioned in the problem that it is an array of strings )
var personSchema = new mongoose.Schema({
tags:{
type:[String],
required: true
}
});
- On Postman:
{
"tags": ["css", "javascript", "mongoose", "node"]
}
- On MongoDB
{
"tags":["css", "javascript", "mongoose", "node"]
}
Similarly, you can create other types of primitive arrays and document arrays in the mongoose schema as:
({
toys: [ToySchema],
buffers: [Buffer],
strings: [String],
numbers: [Number]
// ... etc
});
Solution 5 - node.js
- On Schema
techs: Array
- On Postman
"techs": ["express","rect","html","css","scss"]
- On DB (MongoDB)
"techs" : [ "epxress", "rect", "html", "css", "scss" ]
Solution 6 - node.js
this will also work
var personSchema = new mongoose.Schema({
tags: {
type: [String], default: []
}
});
Solution 7 - node.js
var personSchema = new mongoose.Schema({
tags: [{type: String}]
});
Use this in the schema.
Saving the Array:
var etc = new modename({yourprimaryid: primaryid});
for (var i = 0; i < tag.length; i++) {
etc.tag.push(tag[i]);
}
etc.save(function(err) {
//whatever you want here
}
Solution 8 - node.js
Firstly, as many people have noted, the schema needs to change to indicate that the tags
field is intended to hold an array of strings, and not just a single one. So that needs to change to:
var personSchema = new mongoose.Schema({
tags: [String]
});
The other thing you need to keep in mind (and which caused me a lot of trouble), is that when saving, make sure to use a fresh array for the tags
field. For example, this won't work:
person.tags[0] = "new tag";
person.save();
Instead, you need to do something like:
person.tags = person.tags.slice(); // Clone the tags array
person.tags[0] = "new tag";
person.save();
Hope this helps.
Solution 9 - node.js
Define a Schema:
const schema = new Schema({
name: { type: String, required: true },
tags: [String]
});
In postman add each element separately using the array syntax below
name:Thing
tags[]:task
tags[]:other
tags[]:thing
Return Data:
{
"__v": 0,
"name": "Thing",
"_id": "5a96e8d0c7b7d1323c677b33",
"tags": [
"task",
"other",
"thing"
]
}
Solution 10 - node.js
I had a simialr problem, In the model, do this :
tags : {[String], default: undefined}
So that it defaults to undefined unstead of an empty array, and instead of this:
const person = new Person({
tags : req.body.tags
});
Do this :
const person = new Person();
person.tags = req.body.tags;