I was wondering how can we add an array of string in a moongoose schema.
I have the following code but it is not working:
var message = new Schema({
topic: String,
content: String,
restriction:String,
sender:String,
reciever:String,
users:[String],
read:{type: String, default: 'no'},
like:{ type: Number, default: 0 },
created_at: {type: Date, default: Date.now}
});
I am talking about users. Can you help?
Cobbling together what you said in your comments and the main post, I can't help but think you're missing the modeling step of mongoose.
First you define the schema:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
var MessageSchema = new Schema({
topic: String,
content: String,
restriction:String,
sender:String,
reciever:String,
users:[String],
read:{type: String, default: 'no'},
like:{ type: Number, default: 0 },
created_at: {type: Date, default: Date.now}
});
Then you have to tell mongoose about it:
const Message = mongoose.model('Message', MessageSchema);
Then you can create an instance to put data into:
mongoose.connect('mongodb://localhost:27017/mydb'); // assuming that's a working mongo instance
let message = new Message();
message.users.push('Juliana');
message.save((e,u) => { console.log('New user saved!'); });
If I'm wrong, please post more info about what's not working.
var message = new Schema({
topic: String,
content: String,
restriction:String,
sender:String,
reciever:String,
users:[{
type: String
}],
read:{type: String, default: 'no'},
like:{ type: Number, default: 0 },
created_at: {type: Date, default: Date.now}
});
try this
var message = new Schema({
topic: String,
content: String,
restriction:String,
sender:String,
reciever:String,
users:[
{name: String}],
read:{type: String, default: 'no'},
like:{ type: Number, default: 0 },
created_at: {type: Date, default: Date.now}
});
Related
I need to query documents from two collections together on mongoose.
I am familiar with SQL query and but not familiar with mongoDB.
I have two schema for Users, Messages like following.
Users
const UserSchema = new mongoose.Schema({
name: String,
email: {type: String, unique: true},
password: String,
avatar: {type: String, default: ""},
created_at: { type: Date, default: Date.now() }
});
module.exports = mongoose.model('User', UserSchema);
Messages
const MessageSchema = new mongoose.Schema({
message: { type: String, default: "" },
from: { type: String, default: "" },
to: { type: String: default: "" },
is_read: { type: Boolean, default: false },
channel: { type: String, default: ''},
created_at: { type: Date, required: true, default: Date.now }
});
module.exports = mongoose.model('Message', MessageSchema);
I need to get messages with "is_read" is "false".
I want to get "user name" and "avatar" together.
The "from" value of message should be matched with "_id" of User.
I think this post sums it up well: Mongoose - query to get data from multiple collections
Specifically the second upvoted answer mentions similarities between sql and mongodb, and goes on to explain how to link collections in mongoose queries.
I have the following query working with mongo, it returns the expected result
db.getCollection('trainings').find({"sections.employees.employee":ObjectId("5d3afa1a58a7160ea451d1db")})
but when I try the following call with mongoose, it returns an empty array
Training.find({'section.employees.employee': "5d3afa1a58a7160ea451d1db"})
Need some helping to translate the mongo query to mongoose.
If you need anything else just add a comment and I will post here.
It's worth mentioning that I have already tried passing a new ObjectId with the String value, but it also returns an empty array.
Edit: Query usage
return await Training.find({'section.employees.employee': "5d3afa1a58a7160ea451d1db"})
Edit: Model
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const EmployeeSection = new Schema({
employee: {type: Schema.Types.ObjectId, ref: 'Employee', required: true},
fulfilled: {type: Boolean, default: null},
});
const Section = new Schema({
order: {type: Number, required: true},
date: {type: Date},
employees: {type: [EmployeeSection]},
answers: {type: Number},
hits: {type: Number}
});
const GoalSchema = new Schema({
understanding: {type: Number, required: true},
fixation: {type: Number, required: true}
});
const Evidence = new Schema({
description: {type: String, required: true},
file: {type: String}
});
const Question = new Schema({
participants: {type: Number},
answers: {type: Number},
hits: {type: Number}
});
const TrainingSchema = new Schema({
company: {type: Schema.Types.ObjectId, ref: 'Company', required: true, index: true},
creationDate: { type: Date, default: Date.now },
title: {type: String},
obs: {type: String},
questionNumber: {type: Number},
reference: {type: String},
sections: {type: [Section]},
goals: {
answers: {type: GoalSchema, required: true},
hits: {type: GoalSchema, required: true}
},
evidences: {type: [Evidence]},
questions: {type: [Question]},
area: {type: Schema.Types.ObjectId, ref: 'TrainingArea', required: true},
});
const Training = mongoose.model('Training', TrainingSchema);
module.exports = Training;
I am willing to change the Model schema, if the problem really lays there, but didn't really want to do it.
Why its always a typo?
db.getCollection('trainings').find({"sections.employees.employee":ObjectId("5d3afa1a58a7160ea451d1db")})
Training.find({'section.employees.employee': "5d3afa1a58a7160ea451d1db"})
Forgot s on sections
Made the problem a bit easier for me.
const mongoose = require("mongoose");
mongoose.connect("mongodb://localhost/training", { useNewUrlParser: true })
const util = require("util")
const Schema = mongoose.Schema;
const EmployeeSection = new Schema({
employee: {type: Schema.Types.ObjectId, ref: 'Employee', required: true}
});
const Section = new Schema({
employees: {type: [EmployeeSection]}
});
const TrainingSchema = new Schema({
sections: {type: [Section]}
});
const Training = mongoose.model('Training', TrainingSchema);
Training.find(
{
"sections.employees.employee": mongoose.Types.ObjectId("5d3afa1a58a7160ea451d1db")
})
.exec()
.then(result => {
console.log(util.inspect(result, false, null, true /* enable colors */))
}).catch(err =>{
console.log(err)
})
I am trying to create a nested mongoose schema that uses 'type' to create a nested array.
The schema that I think I am having an issue with is "chorePerson".
Here is the data that I am trying to put into a schema:
{
"chart": [
{
"ordinal": 0,
"chorePerson": [
{
"person": "emily",
"chore": "Catbox"
},
{
"person": "Steve",
"chore": "Dishes"
}
]
}
]
Here is my current schema. Note the use of "type" for "chart" and "chorePerson"
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const chorePersonSchema = new mongoose.Schema({
person: {type: String, requried: true},
chore: {type: String, required: true},
});
const chartSchema = new mongoose.Schema({
ordinal: {type: Number, required: true},
chorePerson:{ type: chorePersonSchema },
});
// create the schema
const ChoreChartSchema = new Schema({
affiliation: {type: String, required: true},
currentWeekNumber: {type: Number, required: true},
currentYear: {type: Number, required: true},
chart:{ type: chartSchema },
date: {type: Date, default: Date.now},
})
module.exports = ChoreChart = mongoose.model('cm_chorechart', ChoreChartSchema)
When I run my code this is what I get before the crash:
{ _id: 5c742ed116a095522c38ddfc,
affiliation: 'family',
currentYear: 2019,
currentWeekNumber: 9,
date: 2019-02-25T20:26:33.914Z,
chart: [ { ordinal: 0, chorePerson: [Array] } ] }
I think... chorePerson is causing the error... but I don't know how to fix it.
Here is the exception:
(node:6728) UnhandledPromiseRejectionWarning: ObjectExpectedError: Tried to set nested object field `chart` to primitive value `[object Object]` and strict mode is set to throw.
What I have tried
I tried this schema:
const chartSchema = new mongoose.Schema({
ordinal: {type: Number, required: true},
chorePerson : [{
person : String,
chore : String
}]
});
Update:
OK... so I went back to basics and this works, but it's not how I want the final schema to be. Can anybody help out with nesting this ?
// create the schema
const ChoreChartSchema = new Schema({
affiliation: {type: String, required: true},
currentWeekNumber: {type: Number, required: true},
currentYear: {type: Number, required: true},
// chart:{ type: chartSchema },
chart:[{
ordinal: 0,
chorePerson : [{
person : String,
chore : String
}]
}],
date: {type: Date, default: Date.now},
})
Turns out it was easier than I thought:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const chorePersonSchema = new mongoose.Schema({
person: {type: String, requried: true},
personID: {type: String, required: true},
chore: {type: String, required: true},
choreID: {type: String, required: true},
});
const chartSchema = new mongoose.Schema({
ordinal: {type: Number, required: true},
chorePerson : [{ type:chorePersonSchema }]
});
// create the schema
const ChoreChartSchema = new Schema({
affiliation: {type: String, required: true},
weekNumber: {type: Number, required: true},
year: {type: Number, required: true},
chart:[{type: chartSchema}],
date: {type: Date, default: Date.now},
})
module.exports = ChoreChart = mongoose.model('cm_chorechart', ChoreChartSchema)
just started learning mongodb, currently i have this schema
var BlogSchema = new mongoose.Schema({
title: String,
image: String,
body: String,
created: {
type: Date,
default: Date.now
}});
and i wanted to update it to be like this, but currently its not working right now, when i checked it on the mongo console the schema is still the old one
var BlogSchema = new mongoose.Schema({
title: String,
image: String,
body: String,
created: {
type: Date,
default: Date.now
},
author: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
username: String
}
});
this is the best i've come up with after reading this post, but it throw me an error TypeError: Undefined type undefined at author.required Did you try nesting Schemas? You can only nest using refs or arrays.
var BlogSchema = new mongoose.Schema({
title: String,
image: String,
body: String,
created: {
type: Date,
default: Date.now
},
author: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
username: {
type: String,
required: true,
default: null
}
}
});
You can't use Schema like that instead just make another authorSchema and use it as array.
var mongoose = require('mongoose');
var authorSchema = new mongoose.Schema({
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
username: {
type: String,
required: true,
}
})
var BlogSchema = new mongoose.Schema({
title: String,
image: String,
body: String,
created: {
type: Date,
default: Date.now
},
author: [authorSchema]
})
I have 2 schemas:
var pollSchema = new mongoose.Schema({
title: String,
created: {
type: Date, default: Date.now
},
options: [{
label: String,
count: {
type: Number, default: 0
},
backgroundColor: {
type: String, default: '#fff'
}
}],
author:{
id:{
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
username: String
}
});
var userSchema = new Schema({
username: {type: String, unique:true},
email: {type: String, unique:true, lowercase: true},
password: String
});
Now each poll will store data of it's author.
Questions:
How can I redesign my schemas - so I will be able to find all the polls belong to particular user?
Or should I leave the schemas the same and find another approach?
you can still find all the polls belonging to a particular user . You have the author.id for that.
Also you can keep an array as var userSchema = new Schema({
username: {type: String, unique:true},
email: {type: String, unique:true, lowercase: true},
password: String,
polls: []
});
And every time a user polls, push the userId inside the polls array, which you can later populate or get the count.