Populate inside JSON object Mongoose - node.js

i want to populate inside JSON object, but it doesnt work. Here is the code. The response i still get is the objectId when i log the response of the Group variable
population
var Groups = await GroupModel.find({ownerUser : user.battletag}).populate([
{
path: "selectedInstance",
model: "Instances"
},
{
path: "createdAs",
model: "Characters",
populate: {
path: "race",
model: "Races"
}
},
{
path: "characters",
populate: {
path: "character",
model: "Characters"
}
}
]).exec();
schema
var GroupSchema = new Schema({
createdAs: {type: Schema.Types.ObjectId, ref: 'Characters'},
description: String,
minimumItemLevel: Number,
voiceChat: String,
completedAchievements: [{ type: Schema.Types.ObjectId, ref: 'Achievements' }],
selectedInstance: { type: Schema.Types.ObjectId, ref: 'Instances' },
instanceDifficulty: String,
private: Boolean,
characters: [{character: { type: Schema.Types.ObjectId, ref: 'Characters' }, role: String}],
queue: [{ type: Schema.Types.ObjectId, ref: 'Characters' }],
ownerUser: String,
groupSignature: String,
status: {type: String, default: "Open"},
maxPlayers: Number,
minPlayers: Number,
expansion: String,
createDate: {type: Date, default: Date.now}
});

I have found the solution for the problem, now it works!
var Groups = await GroupModel.find({ownerUser : user.battletag}).populate([
{
path: "selectedInstance",
model: "Instances"
},
{
path: "createdAs",
model: "Characters",
populate: {
path: "race",
model: "Races"
}
},
{
path: "characters.character",
model: "Characters"
}
]).exec();
return Groups

Related

Field with custom schema type not getting created in database

I have the following code inside the file user.model.js in my Node + EpxressJS application's source.
"use strict";
const { ObjectId } = require("bson");
const mongoose = require("mongoose");
const uniqueValidator = require("mongoose-unique-validator");
const wordSchema = new mongoose.Schema({
word: { type: String, trim: true },
match: { type: String, enum: ["exact", "startsWith", "endsWith", "contains"] }
});
const muteSchema = new mongoose.Schema({
users: [{ type: ObjectId, ref: "User" }],
words: [{ type: wordSchema }],
posts: [{ type: ObjectId, ref: "Post" }]
});
const userSchema = new mongoose.Schema(
{
handle: { type: String, trim: true, required: true, unique: true },
password: { type: String, trim: true, required: true, select: false },
posts: [{ type: ObjectId, ref: "Post", select: false }],
favourites: [{ type: ObjectId, ref: "Post", select: false }],
following: [{ type: ObjectId, ref: "User", select: false }],
followers: [{ type: ObjectId, ref: "User", select: false }],
muteList: { type: muteSchema, select: false },
blockList: [{ type: ObjectId, ref: "User", select: false }],
isDeactivated: { type: Boolean, default: false },
isDeleted: { type: Boolean, default: false }
},
{
timestamps: true
}
);
userSchema.plugin(uniqueValidator);
module.exports = mongoose.model("User", userSchema);
I create a new user using the User model like this:
const user = new User({ handle: "asdf", password: "[passwordHash]" });
await user.save();
Now when I run db.users.find(), all the other fields exist in the database, except muteList. Why is this happening?
Okay, figured it out. I just needed to provide a default value.
muteList: { type: muteSchema, default: {}, select: false }

I want to list users and all user's comments in MongoDB. Is it possible?

I want to list the users and search for comments in another collection using the same query.
That's my users Schema:
Schema({
cod: {
type: String,
require: true
},
name: {
type: String,
required: true
}
})
And that's my comments Schema:
Schema({
user: {
type: Schema.Types.ObjectId,
ref: 'users'
},
post: {
type: Schema.Types.ObjectId,
ref: 'posts'
},
comment: {
type: String,
required: true
}
})
I want get some like this:
{
_id: 5eee97c18b83e338bcbfa8f9,
name: 'Cool Name',
cod: 'CN001',
comments: [{
_id: ObjectId(...)
post: ObjectId(...),
comment: 'comment 1'
},
{
_id: ObjectId(...)
post: ObjectId(...),
comment: 'comment 2'
}
]
}
is it possible?
Thank you!
you might need to change your schema to:
Users:
Schema({
cod: {
type: String,
require: true
},
name: {
type: String,
required: true
},
comments: {
type: Schema.Types.ObjectId,
ref: 'comments'
}
})
Comments:
Schema({
post: {
type: Schema.Types.ObjectId,
ref: 'posts'
},
comment: {
type: String,
required: true
},
user: { // in case you want to query comments and populate the user
type: Schema.Types.ObjectId,
ref: 'users'
}
})
Then query:
users.findById({'your user id here'})
.populate({path:'comments',select:['post','comment']})
.then((response)=>{
// do anything you want with the data here
})

How can I fetch data from more than one collections in Mongo using mongoose

How I can display details data of a profile when those data stored in more than one collections
tried this link
const profile = await userKushala
.find({_id: '5cd407c741f9e7373f10362c'})
.populate({
path: 'settingId',
populate : {
path : 'specialty',
populate : {
path: 'hospital_attached'
}
}
})
// First Collection(Basic Info.)
const userRegisterSchema = new Schema({
userType: {
type: String,
required: true
},
mobile: {
type: Number,
required: true,
unique: true
},
userId: {
type: String,
required: true
},
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
age: {
type: Number,
required: true
},
gender: {
type: String,
required: true
},
settingId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'providerSetting'
}
})
// Second Collection(Detailed Info.)
const serviceProfileUpdate = new Schema({
specialty :[{
type: mongoose.Schema.Types.ObjectId,
ref: 'specialtyMasterCsv'
}],
category: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'categoryMasterCsv'
}],
subscriptionPlan: {
type: mongoose.Schema.Types.ObjectId,
ref: 'planMasterCsv'
},
medicine: {
type : mongoose.Schema.Types.ObjectId,
ref: 'kushalaUser'
}
})
//Data in Mongo
{
"_id":{
"$oid":"5cd93ea6bd96e43664f49bf3"
},
"specialty":[
{
"$oid":"5cda85f26ffe60259a75ba17"
},
{
"$oid":"5cda85f26ffe60259a75ba18"
}
],
"category":[
{
"$oid":"5cda85f26ffe60259a75ba17"
},
{
"$oid":"5cda85f26ffe60259a75ba18"
}
],
"subscriptionPlan":{
"$oid":"5cda85f26ffe60259a75ba17"
},
"medicine":{
"$oid":"5cd407c741f9e7373f10362c"
},
"__v":{
"$numberInt":"0"
}
}
Expected Result will be from all the collections data should fetch but with the code I have it's giving the result till specialty but after that it's printing only ObjectID
This is what I have done and it's working still if anyone has a better solution, most welcome. Hope it helps someone.
const profile = await userKushala
.find({_id: '5cd407c741f9e7373f10362c'})
.populate({
path: 'settingId',
populate : {
path : 'specialty category subscriptionPlan medicine'
}
})
Try to populate like this:
.populate([
{path:'category',model:'categoryMasterCsv'},
{path:'subscriptionPlan',model:'planMasterCsv'},
{path:'medicine',model:'kushalaUser'}])
This is the method I use daily.

mongoose is not able to populate ref id with default value empty object

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 = {};
}
},
};

Mongoose populated is not working

Mongoose populated documentation:
Model.findOne().populate('author').exec(function (err, doc) {
console.log(doc.author.name) // Dr.Seuss
console.log(doc.populated('author')) // '5144cf8050f071d979c118a7'
})
My code:
Job.find({operator: user.operator, status: {$nin: ['assigned', 'unassigned', 'completed']}})
.populate('version', 'results.routes')
.exec(function(err, jobs)
{
console.log(jobs.populated('version'))
...
I have been getting this error when the code runs:
TypeError: jobs.populated is not a function
Why am I getting this error? What am I doing wrong here? Thanks in advance.
EDIT: Posting Job model:
var JobSchema = new Schema(
{
created: Date,
received: Date,
due_date: Date,
freight: Number,
creator: { type: mongoose.Schema.ObjectId, ref: 'User' },
operator: { type: mongoose.Schema.ObjectId, ref: 'Operator' },
routing: { type: mongoose.Schema.ObjectId, ref: 'Routing' },
version: {
type: mongoose.Schema.ObjectId, ref: 'Version',
validate: [validateStarredVersion, 'You must star this route before monitoring it.']
},
...
The version model:
var VersionSchema = mongoose.Schema(
{
routing: { type: mongoose.Schema.ObjectId, ref: 'Routing' },
name: String,
number: Number,
date: Date,
tags: [String],
results:
{
routes:
[ resultSchema ],
...
resultsSchema:
var resultSchema = new Schema(
{
name: String,
vehicle: mongoose.Schema.Types.Mixed,
distance: Number,
weight: Number,
volume: Number,
capacity_weight: Number,
capacity_volume: Number,
occupancy_weight: Number,
occupancy_volume: Number,
job: { type: mongoose.Schema.ObjectId, ref: 'Job' },
operator: mongoose.Schema.Types.Mixed,
delivery_order:
[
{
delivery: mongoose.Schema.Types.Mixed,
depot: mongoose.Schema.Types.Mixed,
arrival_time: Date
}
],
directions: [ directionSchema ]
});
I have not edited with the entired object because it's too large. I put only the related information.
The documentation uses findOne(), while your code uses find(). This means the variable jobs isn't a mongoose document, but an array of mongoose documents. The native Array doesn't have a method .populated()

Resources