I have a collection that one of it's fields is an array of strings. but when I query with find(), it returns null while in the MongoDB Compass I can see it.
here is my document:
{
"_id":"5d4894f23f86a41b84303795",
"position":1,
"garmentTitle":"My first Garment",
"garmentURL":"www.firstgarment.com",
"garmentPictureURL":"/images/first.png",
"brand":"5d49e60e4eface2a00ac58d7",
"garmentMaker":"5d49e8854eface2a00ac58d9",
"garmentPurpose":"5d49e8754eface2a00ac58d8",
"gender":"5d37546f2f8c280adc60b3fe",
"garmentCategory":"5d3a4c7f447a7a3afc71a746",
"fabricComposition":null,
"garmentSizes":["5d4d211f0fe9591facb9a268"] // <<== This is mentioned array
}
Here is my defined schema :
var mongoose = require('mongoose');
var gardataSchema = new mongoose.Schema({
position: {
type: Number,
unique: true,
required: true
},
garmentTitle: {
type: String,
unique: true,
required: true
},
garmentURL: {
type:String,
required:false
},
garmentPictureURL: {
type: String,
required:false,
},
brand:{
type: mongoose.Schema.Types.ObjectId,
ref: 'BR',
required: false
},
garmentMaker: {
type: mongoose.Schema.Types.ObjectId,
ref: 'GM',
required: false
},
garmentPurpose: {
type: mongoose.Schema.Types.ObjectId,
ref: 'GP',
required: false
},
garmentSizes: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'GS',
required: false
}],
gender: {
type: mongoose.Schema.Types.ObjectId,
ref: 'GN',
required: false
},
garmentCategory: {
type: mongoose.Schema.Types.ObjectId,
ref: 'GC',
required: false
},
fabricComposition: {
type: mongoose.Schema.Types.ObjectId,
ref: 'FC',
required: false
},
});
var collectionName = 'garmentData';
mongoose.model('GD', gardataSchema, collectionName);
And here is my controller:
module.exports.getOneGarmentDataByID = function (req, res) {
GD.find({_id:req.params.id})
.exec()
.then(result => {
res.status(200).json(result);
})
.catch(err => {
console.log(err);
res.status(500).json({error:err});
});
}
Requested route:
http://localhost:3000/gar/getonegarmentdatabyid/5d4894f23f86a41b84303795
And final result is :
[
{
"garmentSizes": null, <<== returns null!!!
"_id": "5d4894f23f86a41b84303795",
"position": 1,
"garmentTitle": "My first Garment",
"garmentURL": "www.firstgarment.com",
"garmentPictureURL": "/images/first.png",
"brand": "5d49e60e4eface2a00ac58d7",
"garmentMaker": "5d49e8854eface2a00ac58d9",
"garmentPurpose": "5d49e8754eface2a00ac58d8",
"gender": "5d37546f2f8c280adc60b3fe",
"garmentCategory": "5d3a4c7f447a7a3afc71a746",
"__v": 0,
"fabricComposition": null
}
]
As you can see it returns null instead of array object.
Do you have any idea?
Schema type is wrong. Should be:
garmentSizes: {
type: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'GS'
}
],
required: false
}
Related
for example I have two collections,
1st collection schema (test):
const testSchema = new mongoose.Schema(
{
_id: mongoose.Schema.Types.ObjectId,
name: {
type: String,
required: [true, "le nom d'examen est obligatoire!"],
},
year: {
type: Number,
required: [true, "l'année est obligatoire"],
},
questions: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Question",
},
],
clinicalCase: [
{
_id: {
type: mongoose.Schema.Types.ObjectId,
index: true,
required: true,
auto: true,
},
text: String,
},
],
},
{
timestamps: true,
}
);
2nd schema:
const questionSchema = new mongoose.Schema({
test: {
type: mongoose.Schema.Types.ObjectId,
ref: "Test",
},
questionString: {
type: String,
required: [true, "la question est obligatoire"],
},
explanation: String,
options: [option],
tag: {
type: mongoose.Schema.Types.ObjectId,
ref: "Tag",
},
clinicalCase: {
type: mongoose.Schema.Types.ObjectId,
}
});
so my problem here is when I query 2nd schema, I want to populate the clinicalCase field with 1st schema, is it possible to do it with populate method or not ? can you help me with it please
I tried to join three documents in mongodb using mongoose in nodejs, but unfortunately this error occurs. My mongoose version is 6.2.3
Declaring Schema
const mongoose = require('mongoose')
const declaringSchema = mongoose.Schema({
cniDeclaring: { type: Number, required: true },
father: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Father',
required: true,
},
mother: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Mother',
required: true,
},
name: { type: String, required: true },
surname: { type: String, required: true },
birthDay: { type: Date, required: true },
birthPlace: { type: String, required: true },
gender: { type: String, required: true },
address: { type: String, required: true },
relationShipDeclared: { type: String, required: true },
phone: { type: Number, required: true },
request: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Request',
}],
});
module.exports = mongoose.model('Declaring', declaringSchema);
Declared Schema
const mongoose = require('mongoose')
const declaredSchema = mongoose.Schema({
name: { type: String, required: true },
surname: { type: String, required: true },
father: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Father',
},
mother: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Mother',
},
birthDay: { type: Date, required: true },
birthPlace: { type: String, required: true },
gender: { type: String, required: true },
nationality: { type: String, required: true },
request: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Request',
},
});
module.exports = mongoose.model('Declared', declaredSchema);
Father Schema
const mongoose = require('mongoose')
const fatherSchema = mongoose.Schema({
cniFather: { type: Number, required: true },
nameP: { type: String, required: true },
surname: { type: String, required: true },
birthDay: { type: Date, required: true },
birthPlace: { type: String, required: true },
address: { type: String, required: true },
phone: { type: Number, required: true },
occupation: { type: String, required: true },
declaring: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Declaring',
}],
declared: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Declared',
}],
});
module.exports = mongoose.model('Father', fatherSchema);
Now I want to get all the fathers back
const Father = require('../models/Father');
exports.createFather = (req, res, next) => {
const father = new Father({
...req.body
});
father.save()
.then(() => res.status(201).json({ message: 'Father created !'}))
.catch(error => res.status(400).json({ error })
);
}
exports.getAllFathers = (req, res, next) => {
Father.find()
.populate('declarings')
.populate('declareds')
.exec((err, res) => {
if(err){
console.log(err);
}
});
};
and I have the following error:
MongooseError: Cannot populate path declarings because it is not in your schema. Set the strictPopulate option to false to override.
Below is my API for fetching all the orders of a specific restaurant from a mongoDB database.
My search is based on the restaurant id which I am getting from params and passing it to the query object.
query1 is working but query2 does not return my data.
It is returning an empty array. If I pass a simple object in find() then I am getting a response. But when i use a nested object for getting data I get nothing.
exports.getOrders = async (req, res) => {
const restId = req.params.restId;
console.log("restaurant id", restId);
if (!restId) return res.status(404).send("No restaurant ID found in params");
const query1 = {grandTotal: 600};
const query2 = { restaurant: { restaurantId: restId } };
const response = await Orders.find(query2);
console.log("Printing response inside API function", response);
}
Below is my MongoDB Schema of Orders.
const mongoose = require("mongoose");
const orderSchema = mongoose.Schema({
customer: {
name: {
type: String,
required: true,
},
contact: {
type: String,
required: true,
},
customerId: {
type: mongoose.Schema.Types.ObjectId,
ref: "Customer",
required: true,
},
customerAddress: {
type: String,
required: true,
},
},
restaurant: {
restaurantName: {
type: String,
required: true,
},
contact: {
type: String,
required: true,
},
restaurantId: {
type: mongoose.Schema.Types.ObjectId,
ref: "Restaurant",
required: true,
},
},
/*date: {
day: {
type: Number,
required: true,
},
month: {
type: String,
required: true,
},
year: {
type: Number,
required: true,
},
},
type: {
type: String,
enum: ["delivery","takeaway"],
required: true,
},*/
items: [
{
itemId: { type: String, required: true },
itemName: { type: String, required: true },
itemDescription: { type: String, required: true },
price: {type: Number, required: true},
quantity: { type: Number, required: true },
total: {type: Number, required: true},
},
],
grandTotal: {type: Number, required: true},
status: {
type: String,
enum: ["pending", "rejected","cancelled","accepted","received"],
required: true,
},
});
orderSchema.virtual("booking", {
ref: "Booking",
localField: "_id",
foreignField: "orderId",
});
orderSchema.set("toObject", { virtual: true });
orderSchema.set("toJSON", { virtual: true });
const Orders = mongoose.model("Orders", orderSchema);
exports.Orders = Orders;
change query2 to this
const query2 = { "restaurant.restaurantId": restId } };
My schema is as shown below:
const order = new Schema({
order_status: Number,
foodtruck_id: { type: Schema.Types.ObjectId, ref: 'foodtruck' },
customer_id: { type: Schema.Types.ObjectId, ref: 'user' },
items: [{ type: Schema.Types.ObjectId, ref: 'items' }],
user_type: Boolean,
order_time: Date,
order_rating: { type: Number, default: 5.0 },
order_issue_comments: String,
order_special_instruction: String,
order_total: Number,
order_location: String,
order_coupon_code: String,
payment_id: { type: Schema.Types.ObjectId, ref: 'payment' },
order_meta: { type: Schema.Types.Mixed, ref: 'order_sub_info', default: {} }
}, { versionKey: false }, { minimize: false });
my query is as shown below:
order.find({
'foodtruck_id': foodtruck_id.trim()
}).populate('customer_id', {
'_id': 1,
'user_name': 1,
'email_id': 1,
'ph_no': 1,
'login_type': 1
}).populate('items').
populate('order_meta', 'order_otp').exec((err, orderList) => {
if (err) res.json({
status: '500',
message: err
});
else {
console.log("called");
res.json({
status: '200',
message: 'Order list',
data: orderList
});
}
});
For this query,it is giving me Cast to ObjectId failed for value at path _id as order_meta has default value {}. How to have effective populate query so that It can take care of this testcase?
It is not good idea to put empty object in a place, where reference id is expected. Both - for having problem with populate and for common sense too (if it is field which has reference, it should be null/undefined or reference itself).
It is common that you want to transform your data at some endpoint, but it should not interfere with database or business logic of application.
You can defined toJSON method that should be used for your model. In your case
const order = new Schema({
order_status: Number,
foodtruck_id: { type: Schema.Types.ObjectId, ref: 'foodtruck' },
customer_id: { type: Schema.Types.ObjectId, ref: 'user' },
items: [{ type: Schema.Types.ObjectId, ref: 'items' }],
user_type: Boolean,
order_time: Date,
order_rating: { type: Number, default: 5.0 },
order_issue_comments: String,
order_special_instruction: String,
order_total: Number,
order_location: String,
order_coupon_code: String,
payment_id: { type: Schema.Types.ObjectId, ref: 'payment' },
order_meta: { type: Schema.Types.ObjectId, ref: 'order_sub_info'}
}, { versionKey: false }, { minimize: false });
order.options.toJSON = {
transform(zipRequestDocument, ret, options) { // eslint-disable-line no-unused-vars
if (!ret.order_meta){
ret.order_meta = {};
}
},
};
I am trying to delete one array element when I click delete button on jade view page.
When clicked, it's going to send selected instructor objected as req.body.
At sever side, it will find courses that contain the instructor objectId.
Any idea for me?
Thank you for reading it.
here is my code:
var id = req.body._id;
clist.find({ instructors: { $in: [id] } }).exec(function (err, result) {
result.forEach(function (obj) {
clist.update(
{ _id: new mongoose.Types.ObjectId(obj._id)},
{ $pull: { instructors : [new mongoose.Types.ObjectId(id)] } }
);
console.log(new mongoose.Types.ObjectId(obj._id) + ' was deleted');
});
});
Schema Clist and ilist:
var instructorlist = mongoose.Schema({
name: { type: String, required: true },
age: { type: Number, required: true },
gender: { type: String, required: true },
DOB: { type: Date, required: true, default: Date.now },
email: { type: String, required: true },
phone: { type: Number, required: true },
address: { type: String, required: true },
dateofstart: { type: Date, required: true},
courses: [{
type: mongoose.Schema.Types.ObjectId,
ref: "clist"
}]
});
var courselist = mongoose.Schema({
coursename: { type: String, required: true },
coursenumber: { type: String, required: true },
coursecredit: { type: Number, required: true },
courseroom: { type: String, required: false },
courseregisteddate: {type: Date, default: Date.now},
students: [{
type: mongoose.Schema.Types.ObjectId,
ref: "slist"
}],
instructors: [{
type: mongoose.Schema.Types.ObjectId,
ref: "ilist"
}]
});
one example for mongodb :
{
"_id": {
"$oid": "591a7a3b391a1842e8a69e23"
},
"coursename": "JDKD",
"coursenumber": "COMP4483",
"coursecredit": 4,
"courseroom": "sdaf",
"instructors": [
{
"$oid": "591a374422a3a13d38c0bbe5"
}
],
"students": [],
"courseregisteddate": {
"$date": "2017-05-16T04:04:11.848Z"
},
"__v": 0
}
When I add instructor objectID in Course.
var newcourse = new clist({
'coursename': req.body.coursename, 'coursenumber': req.body.coursenumber, 'coursecredit': req.body.coursecredit
, 'courseroom': req.body.room, 'instructors': instructors._id
});
Use same operation to find and update multiple
clist.update(
{ instructors: { $in: [id] }},
{ $pull: { instructors : { _id : new mongoose.Types.ObjectId(id) } } }, //or{ $pull: { instructors: mongoose.Types.ObjectId(id) } }
{
multi:true
},
function(error, success){
if(error){
console.log("error",error)
}
console.log("success",success)
});