I'm new to mongodb, node and express. I I'm trying to save these data in mongodb.
I have staff.model.js as follows
let StaffSchema = new Schema({
staffcode:String,
firstname:String,
lastname: String,
type: String,
department:String,
dateofjoin:Date,
lastworkingday:Date,
teaching:[ {type:Schema.Types.ObjectId, ref:'Teaches'} ]
});
I have another schema named teaches as follows
let TeachesSchema = new Schema({
standard:{type: Schema.Types.ObjectId, ref: 'Standard'},
subjects:[{type: Schema.Types.ObjectId, ref: 'Subject'}]
});
another schema of standards as follows
let StandardSchema = new Schema({
name:String,
medium:String,
section:String
});
another schema subjects as follows
let SubjectSchema = new Schema({
name:{ type: String, required: true, max: 25 }
});
finally I'm trying to save data in mogodb as like
exports.staff_create = function(req, res){
let staff = new Staff({
staffcode:req.body.staffcode,
firstname:req.body.firstname,
lastname: req.body.lastname,
type: req.body.type,
department:req.body.department,
dateofjoin:req.body.dateofjoin,
teaching:req.body.teaching
});
staff.save(function(err){
if(err){
return next(err);
}
res.send('Staff created successfully');
});
};
making api call from postman with input like this
{
"staffcode": "STF0003",
"firstname": "Joh Doe",
"lastname": "Moy",
"type": "teaching",
"department": "physics",
"dateofjoin": "2018-06-01",
"teaching": {
"standard": {
"_id": "5cb8ff551a1c1a2514fa467c",
"name": "1",
"medium": "English",
"section": "A"
},
"subjects": [
{
"_id": "5cb8ed65c068b22f5489d050"
},
{
"_id": "5cb8ed6bc068b22f5489d051"
}
]
}
}
what is wrong in this? I'm not able to get success response in postman request.
your schema design is coming from relational databases. However you can do what you ask by using populate.
a better way would be to use embedded documents instead of referrals in some places check this answer about MongoDB relationships: embed or reference?
Related
I am creating a basic schema document to read data that should mirror the following document structure:
Document1:
Customer: {
_id: "61fa6cb1a0f4d684063aa66e"
"customerName": "Sam Dobson",
"email": "same#example.com",
"Orders": [
{
"id": "620146f0cbafd7ba64c09daa",
"orderDate": 2022-03-02T14:29:41.523Z,
"image": {
"id": "620146d770ee1e897f245230",
"name": "Cola",
"thumbnail": "cola.jpeg",
"type": "image"
},
"video": null,
"qty": 1
},
{
"id": "620a89b7cbafd7ba64c28930",
"orderDate": 2022-03-07T11:915:12.125Z,
"image": {
"id": "620a8aa170ee1e897f2458fe",
"name": "Pizza",
"thumbnail": "pizza.jpeg",
"type": "image"
},
"video": {
"id": "620a8aa170ee1e897f2458fe",
"name": "PizzaVideo",
"thumbnail": "pizzaVideo.mp4",
"type": "video"
},
qty: 2
}
]
}
Data already exist in a MongoDB instance and I've to read this data for further processing. So far, I've created the following schema:
Customer.js:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const FileSchema = Schema({
name:{type: String},
thumbnail: {type: String},
type: {type: String}
});
const OrderSchema = Schema({
orderDate: {type: Date},
image:{ type: FileSchema},
video:{type: FileSchema},
qty: {type: Number}
});
const CustomerSchema = Schema({
customerName: {type: String},
email: {type: String},
Orders: [OrderSchema],
});
module.exports = mongoose.model('Customer', CustomerSchema);
Code:
In order to populate data, I'm reading it using Model.find() query.
const findCustomers = async () => {
try{
const customer = await Customer.find().exec();
return customer;
}
catch(err){
return 'error occurred!';
}
}
However, when I run the program it shows the subdocument as:
Customer:{
_id: new ObjectId("62c59c55d8f8fc1b77777b39"),
customerName:"Sam Dobson",
email:"same#example.com",
Orders:[[Object], [Object]]
}
My questions are:
Does the schema correctly reflects the document structure?
What do I need to change in my query to read data from Customer document to populate the order object?
I am struggling to get subdocument removed from the parent.
I am using Mongoose findOneAndUpdate.
unitRouter.delete('/:id/contracts/:cid', async (req, res) => {
Unit.findOneAndUpdate(
{ id: req.params.id },
{$pull: {contracts: { id: req.params.cid }}},
function(err, data){
console.log(err, data);
});
res.redirect(`/units/${req.params.id}`);
});
Schema is as follows:
const unitSchema = new mongoose.Schema({
address: {
type: String,
required: true
}
contracts: [{type: mongoose.Schema.Types.ObjectId, ref: 'Contract'}]
});
And it doesn't remove it from the list, neither from the contract collection.
I have checked similar topics, but didn't got it to work. What am I missing?
First of all, your schema does not match with your query.
Your schema doesn't have any id. Do you mean _id created by default?
contracts field is an array of ObjectId, not an object like { id: XXX }
So, starting from the schema you can have a collection similar to this:
[
{
"contracts": [
"5a934e000102030405000000",
"5a934e000102030405000001",
"5a934e000102030405000002"
],
"_id": "613bd938774f3b0fa8f9c1ce",
"address": "1"
},
{
"contracts": [
"5a934e000102030405000000",
"5a934e000102030405000001",
"5a934e000102030405000002"
],
"_id": "613bd938774f3b0fa8f9c1cf",
"address": "2"
}
]
With this collection (which match with your schema) you need the following query:
Unit.updateOne({
"_id": req.params.id
},
{
"$pull": {
"contracts": req.params.cid
}
})
Example here.
Also, the inverse way, your query is ok but your schema doesn't. Then you need a schema similar to this:
new mongoose.Schema(
{
id:{
type: mongoose.Schema.Types.ObjectId,
required: true
},
address: {
type: String,
required: true
},
contracts: [{
id:{
type: mongoose.Schema.Types.ObjectId,
ref: 'Contract'
}
}]
});
Example here
By the way, take care to not confuse between id and _id. By default is created the field _id.
I am trying to query for records in my database but I am getting an empty array. I don't know what I am doing wrong? I have a feeling the issue could be my schema, here it is:
my schema
const QuizSchema = new Schema({
question: {
type:String,
default:''
},
answers: [{
type: {
type: String,
default:''
},
content: {
type: String,
default:''
},
}]
});
module.exports=Quiz=mongoose.model('quizes',QuizSchema,'quiz');
Here is the mongoose query
const Quiz = require('../../models/Quiz');
router.get('/',(req,res)=>{
Quiz.find({},null)
.then(data=>res.json(data))
.catch(err=>console.log(err))
});
module.exports = router;
And here is a sample JSON data
{
"question": "What is a Mongoose ? ",
"answers": [
{ "type": "Smart","content": "Animal" }, {"type": "Subpar", "content": "Software"}, { "type": "Confused", "content": "Poem" }]
}
Would appreciate your assistance. Thanks in advance!
<query>.then doesn't return the data. You should use <query>.exec().then to access the data returned by the query. So change your code to something like:
Quiz.find({},null)
.exec()
.then(data=>res.json(data))
.catch(err=>console.log(err))
});
module.exports = router;
Source: Mongoose docs
Modify Schema like this: Inside the array, field name like 'type' is not accepted.
const QuizSchema = new Schema({
question: {
type:String,
default:''
},
answers: [{
ans_type: { // CHANGE HERE
type: String,
default:''
},
content: {
type: String,
default:''
},
}]
});
module.exports=Quiz=mongoose.model('quizes',QuizSchema,'quiz');
UserSchema
const UserSchema = new Schema({
name:{
type:String,
validate: {
validator: (name) => name.length>2,
message:'Name must be longer than 2 characters'
},
},
postCount:{
type:Number,
default:0
},
posts:
type:[PostSchema],
});
PostSchema
const PostSchema = new Schema({
title:{
type:String,
required:true
}
});
Post method to insert data into user document(mongodb)
app.post('/user',(req,res)=>{
console.log(req.body.posts);
var user = new User({
name:req.body.name,
posts: req.body.posts
});
user.save().then((doc)=>{
res.status(200).send(doc);
},(e)=>{
res.status(400).send(e);
});
});
Creating POST request using this JSON Data
{
"name":"TIM",
"posts":[
{"title":"abc", "name":"xxx"},
{"title":"xyz", "name":"xxx"}]
}
After requesting POST method on above JSON data
{
"postCount": 0,
"_id": "5c32301725d0c965bd5fa82e",
"name": "TIM",
"posts": [
{
"_id": "5c32301725d0c965bd5fa830"
},
{
"_id": "5c32301725d0c965bd5fa82f"
}
],
"__v": 0
}
I have created a userschema and sub-documented posts, now i am trying to insert data from postman using post method, but the title is not updating and only the id is generating for an indivisual posts. please help.
I should be able to add name of the user along side the array of posts and their titles.
Try
posts: [PostSchema]
Reference
https://mongoosejs.com/docs/subdocs.html
Also your post schema doesnt contain name field.
You are trying to insert a name via post.
In the code below I am trying to findByIdAndUpdate and for updating I want to add to two arrays of objectIds and pull from another. However, only the first command for the update is being executed. So $push: {Group1: groupId, Group2: groupId} is being executed but $pull: {Group3: groupId} is not.
Is there a way to make both operations work together?
Code
User.findByIdAndUpdate(
userId,
{
$push: {Group1: groupId, Group2: groupId},
$pull: {Group3: groupId},
},
{'new': true, 'multi':true},
function (err, user) {
if (err)
console.log(err);
else {
res.json({
success: true,
message: 'Success.'
});
}
}
);
Schema
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var bcrypt = require('bcrypt-nodejs');
var ObjectId = Schema.Types.ObjectId;
//user schema
var UserSchema = new Schema({
username: {type: String, required: true, index:{unique:true}},
phoneNumber: {type: String, required: true, index:{unique:true}},
password: {type: String, required: true, select: false},
name: String,
Group1: [{ type : ObjectId, ref: 'Group' }],
Group2: [{ type : ObjectId, ref: 'Group' }],
Group3: [{ type : ObjectId, ref: 'Group' }],
});
module.exports = mongoose.model('User', UserSchema);
here is the json representation on the User object
{
"_id": ObjectId('564a4a24f63d409f526659c4'),
"password": "$2a$10$YYEdr4kavrB2w8dRWHqWC.hAUd1pRzKM6YQt9iLtkrLDk0cRg24Wa",
"phoneNumber": "222",
"username": "222",
"Group1": [
ObjectId('564a2ac4e982c8bb5122a96e')
],
"Group2": [],
"Group3": [],
"__v": 0
}
when I execute my code the json object looks like
{
"_id": ObjectId('564a4a24f63d409f526659c4'),
"password": "$2a$10$YYEdr4kavrB2w8dRWHqWC.hAUd1pRzKM6YQt9iLtkrLDk0cRg24Wa",
"phoneNumber": "222",
"username": "222",
"Group1": [
ObjectId('564a2ac4e982c8bb5122a96e')
],
"Group2": [
ObjectId('564a2acae982c8bb5122a970')
],
"Group3": [
ObjectId('564a2acae982c8bb5122a970')
],
"__v": 0
}
So the objectID from Group3 is not being removed.
My thought on the matter was that i am not using the correct findByIdAndUpdate correctly when it comes to doing a pull and a push at the same time.
This makes me lean towards just using a findById and then doing the update in the callback. Would there be a disadvantage in doing that vs using findByIdAndUpdate?