Save Array Mongoose - arrays

I can't save an array of strings into my DB using Mongoose
The schema:
const TrombinoSchema = new mongoose.Schema({
Name: [String]
});
const Trombino = mongoose.model('Trombino', TrombinoSchema);
and for save:
var trombino = new Trombino ({
Name: req.query.name
});
trombino.save(callback);
Array.isArray(req.query.name) => true;
I tried different statement
Name: [{type : String}] , Name: [{type : String}] or Name: []
but in my DB i found the empty Array

In the trombino schema you need to change the name field:
const mongoose = require('mongoose');
const TrombinoSchema = new mongoose.Schema({
Name: {type:[String]}
});
const Trombino = mongoose.model('Trombino', TrombinoSchema);
let trombinoItem = new Trombino({
Name: ['test name 1','test name 2','test name 3']
});
trombinoItem.save().then((result)=>{
console.log(result);
});
Here the print of execution:
This the data in the database. You can see the name as a array of string:

Related

nodejs mongoose push to an array inside schema [duplicate]

This question already has answers here:
pushing object into array schema in Mongoose
(2 answers)
Closed 5 years ago.
I have a mongoose schema inbox-model:
var schema = mongoose.Schema({
email: String,
data: [{
from: String,
to: String,
msg: String
}]
})
var Inbox = module.exports = mongoose.model('Inbox',schema);
module.exports.addData = function(inbox, callBack){
inbox.save(callBack);
}
I need to add to data[] array for a specific email when there's new data for that email address.
I can add data this way, through my router by calling:
var Inbox = require('inbox-model');
var inbox = new Inbox({
email: 'some#email.com',
data:[{
from: 'from',
to: 'to',
msg: 'msg'
})
Inbox.addData(inbox, Inbox);
though it doesn't add to data[] but keeps adding a whole row.
Help is much appreciated, I've searched for similar questions, but I couldn't find on adding data, just creating models with arrays.
This question has been answered a lot of time on StackOverflow. However, I'm answering it again
// Schema File - userSchema.js
const userSchema = new Schema({
email: { type: String, required: true },
data: [{
from: String,
to: String,
msg: String
}]
})
const user = mongoose.model('user', userSchema)
module.exports = user
// Service File
const user = require('./userSchema')
function someFunction(email, from, to, message) {
user.findOne({ email: email }, function(err, document) {
if (document) {
document.data.push({
from: from,
to: to,
msg: message
})
document.save(function(err) {
err != null ? console.log(err) : console.log('Data updated')
})
}
})
}

Mongo schema, array of string with unique values

I'm creating the schema for a mongo document and I can do everything except prevent duplicates in a non-object array.
I'm aware of the addToSet, but I'm referring to Mongo Schema.
I don't want to check on Update using $addToSet, rather I want this to be part of my schema validation.
Example below.
let sampleSchema = {
name: { type: 'String', unique: true },
tags: [{ type: 'String', unique: true }]
}
The above snippet prevents name from having duplicate values. It allows tags to be stored as a string array.
But.. I cannot limit the array to be unique strings.
{ name: 'fail scenario', tags: ['bad', 'bad', 'array']}
I'm able to insert this record which should be a fail scenario.
const express = require('express');
const router = express.Router();
const mongoose = require('mongoose');
const _ = require('underscore');
let sampleSchema = new mongoose.Schema({
name: {
type: 'String',
unique: true
},
tags: [{
type: 'String'
}]
})
sampleSchema.pre('save', function (next) {
this.tags = _.uniq(this.tags);
next();
});
const Sample = mongoose.model('sample', sampleSchema, 'samples');
router.post('/sample', function (req, res, next) {
const sample = new Sample(req.body);
sample.save()
.then((sample) => {
return res.send(sample);
})
.catch(err => {
return res.status(500).send(err.message);
})
});
I've come to the conclusion that this is impossible to do via Mongoose Schema.
JSON schema is done like so.
let schema = {
name: { type: 'string' }
tags: {
type: 'array',
items: { type: 'string', uniqueItems: true }
}
}
I'll validate with JSON schema before creating Mongo Document.
This method builds on Med's answer, handles references, and done completely in scheme validation.
let sampleSchema = new mongoose.Schema({
strings: [{type: 'String'}],
references: [{type: mongoose.Schema.Types.ObjectId, ref: 'Reference'],
});
sampleSchema.pre('save', function (next) {
let sample = this;
sample.strings = _.uniq(sample.strings, function(i) {return (i._id) ? i._id.toString() : i;});
sample.references = _.uniq(sample.references, function(i) {return (i._id) ? i._id.toString() : i;});
return next();
});
I'm a little late, but maybe this will help someone in the future.
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
name: {
type: String,
},
reference: {
type: [mongoose.Schema.Types.ObjectId],
ref: 'SomeOtherSchema',
// Add a custom validator.
validate: {
// The actual validator function goes here.
// "arr" will be the value that's being validated (so an array of
// mongoose new ObjectId statements, in this case).
validator: arr => {
// Convert all of the items in the array "arr", to their string
// representations.
// Then, use those strings to create a Set (which only stores unique
// values).
const s = new Set(arr.map(String));
// Compare the Set and Array's sizes, to see if there were any
// duplicates. If they're not equal, there was a duplicate, and
// validation will fail.
return s.size === arr.length;
},
// Provide a more meaningful error message.
message: p => `The values provided for '${ p.path }', ` +
`[${ p.value }], contains duplicates.`,
}
},
});
The above commented code should be pretty self explanatory.
With the newer version(s) of MongoDB, you can use $addToSet to append to an array if and only if the new value is unique compared to the items of the array.
Here's the reference: https://www.mongodb.com/docs/manual/reference/operator/update/addToSet/
Here's an example:
const SampleSchema = new mongoose.Schema({
tags: [String]
});
const Sample = mongoose.model('Sample', SampleSchema);
// append to array only if value is unique
Sample.findByIdAndUpdate({_id: 1, {$addToSet: {tags: "New Tag"}}});
This will effectively update the tags if the "New Tag" is not already present in the tags array. Otherwise, no operation is done.

Mongoose how to save document inside an array

I have a model which looks like this:
User.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var memberSchema = new Schema({
email: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true,
min: 8
}
});
var userSchemaPrimary = new Schema({
team_code : {
type: String,
required: true,
unique: true
},
members:[memberSchema],
});
var User = mongoose.model('User', userSchemaPrimary);
module.exports = User;
And this is how am trying to save
var User = require('../models/user');
var newTeam = new User({
team_code : 'CODE01',
members:
{
email: req.body.email,
password: pass
}
});
newTeam.save(function(err) {
if (err) throw err;
console.log('User saved successfully!');
return res.send("Done");
});
When executed, throws model validation error.
Well I tried to save data without the array documents, then its saves successfully. But when I try to save the array (array "members"), it throws validation error.
I WANT TO
Store data in the following way:
{
team_code: "CODE01",
members: [
{
email: "test01#email.com",
password: "11111111"
},
{
email: "test02#email.com",
password: "22222222"
}
{
email: "test03#email.com",
password: "33333333"
}
]
}
I dont understand what is going wrong. Any help is appreciated.
You are assigning object to members field, but it's an array
var newTeam = new User({
team_code : 'CODE01',
members: [{
email: req.body.email,
password: pass
}] // <-- note the array braces []
});

Error adding array to MongoDB / Mongoose collection

I am trying to add an array to a Mongo document, and I'm getting the error "Cast to Array failed for value "[object Object],[object Object]" at path "vendors""
Here is my model:
module.exports = {
attributes: {
vendors: {
type: [String]
},
description: {
type: String
}
}
};
Here is my code to create:
var vendors = ko.observableArray(['foo','bar']);
var desc = ko.observable('yadda yadda yadda');
var dto = {
data: {
vendors: vendors(),
description: description()
}
};
DataService.quoteRequest.create(dto);
Musical Shore,
I'm not familiar with knockout.js, but in regards to Mongoose it doesn't look like you are defining your Schema and Model. You would need to do the following:
Define Schema
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var attributesSchema = new Schema({
vendors: [String],
description: String
});
Create a Model
var Attributes = mongoose.model('Attribute',attributesSchema);
Create and Save a Document
//create an attribute document
var attribute = new Attributes(
{
vendors: vendorsArray,
description: desc
}
);
attribute.save(function(err){
if(!err) console.log('Success');
}

Allow users to add items to their profiles Mongoose

I am building a mean stack app with express and mongoose. I have two schemas, userSchema and courseSchema:
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var courseSchema = mongoose.Schema({
title:{type:String, required:'{PATH} is required!'},
featured:{type:Boolean, required:'{PATH} is required!'},
published:{type:Date, required:'{PATH} is required!'},
courseLink:{type:String, required:'{PATH} is required!'},
user: [{type:Schema.Types.ObjectId, ref : 'User'}]
});
var Course = mongoose.model('Course', courseSchema);
module.exports = Course;
var userSchema = mongoose.Schema({
firstName: {type: String, required: true},
lastName: {type: String, required: true},
username: {
type: String,
required: true,
unique: true // creates unique index inside MongoDB
},
salt: {type: String, required: true},
hashed_pwd: {type: String, required: true},
roles:[String],
courses:[{type: Schema.ObjectId,
ref: 'Course' }]
});
I am able to create users and and courses (as an admin). What I want to do now is to allow each user add a course to his list of courses (or just click a 'like' button beside the course and that course would be added to his profile).
On the side of the controller, I have tried to check for the user id from the session, find that user and add the course to his document. But that's where I am stuck,
exports.addMyCourse = function(req, res){
console.log('user id', req.session.passport.user);
console.log('id', req.body._id);
var currentUserId = req.session.passport.user;
User.findOne({'_id':currentUserId}, function(err, doc){
console.log(doc);
});
Most of the solutions I looked at are not very clear about this. Any help would be appreciated.
RESOLVED:
I used $addToSet to add the course objects into the courses array inside the User model:
This might be useful for people searching for similar soutions:
My User schema:
var userSchema = mongoose.Schema({
firstName: {type: String, required: true},
lastName: {type: String, required: true},
username: {
type: String,
required: true,
unique: true // creates unique index inside MongoDB
},
salt: {type: String, required: true},
hashed_pwd: {type: String, required: true},
roles:[String],
courses:[{
type:Schema.ObjectId, ref:'Course'
}]
});
var User = mongoose.model('User', userSchema);
My Course schema:
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var courseSchema = mongoose.Schema({
title:{type:String, required:'{PATH} is required!'},
featured:{type:Boolean, required:'{PATH} is required!'},
published:{type:Date, required:'{PATH} is required!'},
courseLink:{type:String, required:'{PATH} is required!'}
});
var Course = mongoose.model('Course', courseSchema);
Inside my controllers folder, I have users.js and courses.js:
In the courses.js file, I created the addMyCourses middleware to update the User model's courses array by first retrieving the current user's id from the session and using $addToSet to insert the object and avoid duplicates at the same time. Also I made sure I am adding only the ObjectId's of the courses and not the entire course document so I won't have future problems with too much data in one document:
exports.addMyCourse = function(req, res){
var myCourse = {
title: req.body.title,
featured: req.body.featured,
published: req.body.published,
courseLink: req.body.courseLink
};
var currentUserId = req.session.passport.user;
var courseId = req.body._id;
User.update({_id:currentUserId},
{$addToSet: {"courses": courseId}},
{safe: true, upsert: true, new : true},
function(err, model) {
console.log(model);
}
);
};
Since I only had the ObjectId's of the courses inside the courses array of the User model, I had to use mongoose's populate() method to do a joint query on both models so that I get the corresponding course documents of the ids.
In users.js file:
exports.getUserCourses = function(req, res, next){
var currentUserId = req.session.passport.user;
User.findById(currentUserId).populate('courses')
.exec(function(err, data){
if(err) {
console.log(err);
}
console.log('user courses', data);
res.send(data);
})
};

Resources