Merge two result into one result- mongodb - node.js

I making an API using MongoDB, Nodejs and ExpressJS.I have a collection called membership
const membershipSchema = new Schema(
{
membership_id: {
type: Number,
required: [true, "ID is required"],
unique: true,
},
member_detail: [{ type: Schema.Types.ObjectId, ref: "user" }],
validity: {
type: Number,
enum: [30, 90, 180, 365],
required: true,
},
fee: {
type: Number,
required: [true, "fee is required"],
},
registration_fee: {
type: Number,
required: [true, "registration fee is required"],
},
total_fee: {
type: Number,
required: [true, "total_fee fee is required"],
},
// status: {
// type: Boolean,
// required: [true, "status fee is required"],
// },
startDate: {
type: Date,
required: [true, "Start date is required"],
},
endDate: {
type: Date,
required: [true, "End date is required"],
},
added_by: { type: String, required: true },
last_update: {
type: Date,
default: Date.now,
},
}
);
After adding membership and requesting with GET, I get the following response
{
"member_detail": [
{
"_id": "5ea1e43dd401c828f4d1cf7d",
"name": "member421"
}
],
"_id": "5ea1e4a3d401c828f4d1cf7f",
"last_update": "2020-04-23T18:55:31.311Z",
"membership_id": 421,
"added_by": "admin",
"validity": 30,
"fee": 3500,
"registration_fee": 500,
"total_fee": 4000,
"startDate": "2020-04-18T06:21:04.869Z",
"endDate": "2020-07-18T06:21:04.869Z",
"createdAt": "2020-04-23T18:55:31.313Z",
"updatedAt": "2020-04-23T18:55:31.313Z",
"__v": 0
}
Now I am sending another GET request to membership collection with a query to test and to get the difference between two date (endDate - Current Date(24/04/2020)) and its working fine and gives following response
router.route("/alert").get((req, res) => {
Membership.aggregate(
[
{
$project: {
dayssince: {
$trunc: {
$divide: [
{ $subtract: ["$endDate", new Date()] },
1000 * 60 * 60 * 24,
],
},
},
},
},
],
(err, document) => {
if (err) {
return res.status(404).json({ error: true, message: err });
}
res.status(200).json({ data: document });
}
);
});
the above code returns me this result
{
"data": [
{
"_id": "5ea1e4a3d401c828f4d1cf7f",
"dayssince": 85
}
]
}
Now I want to merge the above result for every membership that I create
Expected output
{
"member_detail": [
{
"_id": "5ea1e43dd401c828f4d1cf7d",
"name": "member421"
}
],
"_id": "5ea1e4a3d401c828f4d1cf7f",
"last_update": "2020-04-23T18:55:31.311Z",
"membership_id": 421,
"added_by": "admin",
"validity": 30,
"fee": 3500,
"registration_fee": 500,
"total_fee": 4000,
"startDate": "2020-04-18T06:21:04.869Z",
"endDate": "2020-07-18T06:21:04.869Z",
"createdAt": "2020-04-23T18:55:31.313Z",
"updatedAt": "2020-04-23T18:55:31.313Z",
"__v": 0
**"dayssince": 85**
}
I've come accross aggregate function but I dont know how to implement with my query.If you need any other code from my project, feel free to comment.

Why request the DB just to calculate a time difference?
Once you have your first result... Why not just do the math right away?
// The result of the first query to DB
let firstResult = {
"member_detail": [
{
"_id": "5ea1e43dd401c828f4d1cf7d",
"name": "member421"
}
],
"_id": "5ea1e4a3d401c828f4d1cf7f",
"last_update": "2020-04-23T18:55:31.311Z",
"membership_id": 421,
"added_by": "admin",
"validity": 30,
"fee": 3500,
"registration_fee": 500,
"total_fee": 4000,
"startDate": "2020-04-18T06:21:04.869Z",
"endDate": "2020-07-18T06:21:04.869Z",
"createdAt": "2020-04-23T18:55:31.313Z",
"updatedAt": "2020-04-23T18:55:31.313Z",
"__v": 0
}
// NOW
let now = new Date();
// Create a date object from the endDate found in the DB result
let endDate = new Date(firstResult.endDate);
// Calculate the difference in rounded days
let result = Math.round((endDate-now) / (1000*60*60*24));
// Output
console.log(result)
// Then... Yes, you can add this to the initial response object
firstResult.dayssince = result;
console.log(firstResult)

Related

Need help in writing an aggregate query

I want only that data in "present" which is matched with student _id. But for now by this query I'm getting all student counts in every individual students data.
Student Schema
const StudentSchema = new mongoose.Schema(
{
name: {
type: String,
required: [true, "Please Provide Name"],
maxlength: 100,
minlength: 2,
},
email: {
type: String,
required: [true, "Please Provide Email"],
match: [
/^(([^<>()[\]\\.,;:\s#"]+(\.[^<>()[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
"Please Provide a Valid Email",
],
unique: true,
},
number: {
type: String,
required: [true, "Please Provide Number"],
match: [
/^(?:(?:\+|0{0,2})91(\s*[\-]\s*)?|[0]?)?[789]\d{9}$/,
"Please Provide a Valid Number",
],
unique: true,
},
rollNumber: {
type: Number,
required: [true, "Please Provide Roll Number"],
maxlength: 5,
},
departmentID: {
type: mongoose.Types.ObjectId,
ref: "Department",
required: [true, "Please Provide departmentID"],
},
classID: {
type: mongoose.Types.ObjectId,
ref: "Class",
required: [true, "Please Provide classID"],
},
position: {
type: String,
required: [true, "Please Provide Position"],
enum: ["Student"],
default: "Student",
},
password: {
type: String,
required: [true, "Please Provide Password"],
minlength: 6,
},
},
{ timestamps: true }
);
Attendance Schema
const mongoose = require("mongoose");
const { Schema } = mongoose;
const AttendanceSchema = new Schema(
{
date: {
type: String,
required: [true, "Please Provide Date"],
maxlength: 15,
minlength: 5,
},
subjectID: {
type: mongoose.Types.ObjectId,
ref: "Subject",
required: [true, "Please Provide Subject"],
},
studentID: [
{
type: mongoose.Types.ObjectId,
ref: "Student",
required: [true, "Please Provide Student"],
},
],
teacherID: {
type: mongoose.Types.ObjectId,
ref: "Faculty",
required: [true, "Please Provide Teacher"],
},
classID: {
type: mongoose.Types.ObjectId,
ref: "Class",
required: [true, "Please Provide Class"],
},
departmentID: {
type: mongoose.Types.ObjectId,
ref: "Department",
required: [true, "Please Provide Department"],
},
},
{ timestamps: true }
);
module.exports = mongoose.model("Attendance", AttendanceSchema);
The Query I'm Writing
await StudentSchema.aggregate([
{
$match: {
classID: mongoose.Types.ObjectId(`${req.params.id}`),
},
},
{
$project: { createdAt: 0, updatedAt: 0, __v: 0, password: 0 },
},
{
$lookup: {
from: "attendances",
pipeline: [
{
$match: {
subjectID: mongoose.Types.ObjectId(`${req.params.Sid}`),
},
},
{ $unwind: "$studentID" },
{ $group: { _id: "$studentID", count: { $sum: 1 } } },
],
as: "present",
},
},
Data I'm Getting From This Query
{
"subject1": [
{
"_id": "635d40803352895afffdc294",
"name": "D R",
"email": "dugu#gmail.com",
"number": "9198998888",
"rollNumber": 202,
"departmentID": "635a8ca21444a47d65d32c1a",
"classID": "635a92141a081229013255b4",
"position": "Student",
"present": [
{
"_id": "635d40803352895afffdc294",
"count": 3
},
{
"_id": "635eb8898dea5f437789b751",
"count": 2
}
]
},
{
"_id": "635eb8898dea5f437789b751",
"name": "V R",
"email": "v#gmail.com",
"number": "9198998899",
"rollNumber": 203,
"departmentID": "635a8ca21444a47d65d32c1a",
"classID": "635a92141a081229013255b4",
"position": "Student",
"present": [
{
"_id": "635d40803352895afffdc294",
"count": 3
},
{
"_id": "635eb8898dea5f437789b751",
"count": 2
}
]
}
]
}
This type of data I'm trying to achieve. Only that data which will be matched with _id in present array.
{
"subject1": [
{
"_id": "635d40803352895afffdc294",
"name": "D R",
"email": "dugu#gmail.com",
"number": "9198998888",
"rollNumber": 202,
"departmentID": "635a8ca21444a47d65d32c1a",
"classID": "635a92141a081229013255b4",
"position": "Student",
"present": [
{
"_id": "635d40803352895afffdc294",
"count": 3
}
]
},
{
"_id": "635eb8898dea5f437789b751",
"name": "V R",
"email": "v#gmail.com",
"number": "9198998899",
"rollNumber": 203,
"departmentID": "635a8ca21444a47d65d32c1a",
"classID": "635a92141a081229013255b4",
"position": "Student",
"present": [
{
"_id": "635eb8898dea5f437789b751",
"count": 2
}
]
}
]
}
You can just use the let option in the $lookup and pass the studentId, then you could match the proper attendances as part of the $lookup stage, like so:
{
$lookup: {
from: "attendances",
let: {
studentID: "$_id"
},
pipeline: [
{
$match: {
subjectID: 2,
$expr: {
$eq: [
"$$studentID",
"$studentID"
]
}
}
},
{
$unwind: "$studentID"
},
{
$group: {
_id: "$studentID",
count: {
$sum: 1
}
}
}
],
as: "present"
}
}
Mongo Playground
Another alternative would be to filter out the present array at the end but that would be less efficient and will uglify the code.

How can I filter data based on populated fields

Product Schema
const ProductSchema = new mongoose.Schema(
{
name: {
type: String,
trim: true,
required: [true, "Please provide product name"],
maxlength: [100, "Product name cannot be more than 100 characters"],
minlength: [5, "Product name cannot be less than 10 characters"],
},
description: {
type: String,
required: [true, "Please provide product description"],
maxlength: [
1000,
"Product description cannot be more than 1000 characters",
],
},
price: {
type: Number,
required: [true, "Please provide product price"],
min: [100, "Minimum price of a product cannot be less than 100"],
},
discountPercentage: {
type: Number,
default: 0,
min: [
0,
"You cannot provide discount percentage of a product less than 0.",
],
},
category: {
type: mongoose.Schema.ObjectId,
ref: "Category",
},
brand: {
type: mongoose.Schema.ObjectId,
ref: "Brand",
},
stock: {
type: Number,
required: false,
default: 15,
},
rating: {
type: Number,
default: 4.5,
min: [1, "Rating must be above 1.0"],
max: [5, "Rating must be below 5.0"],
set: (value) => Math.round(value * 10) / 10,
},
numberOfReviews: {
type: Number,
default: 0,
},
thumbnail: {
type: String,
required: [true, "Please provide thumbnail for your product"],
},
images: {
type: [String],
required: false,
},
seller: {
type: mongoose.Schema.ObjectId,
ref: "User",
},
active: {
type: Boolean,
default: true,
},
slug: {
type: String,
default: function () {
return slugify(this.name, { lower: true });
},
},
},
{
timestamps: true,
toJSON: { virtuals: true },
toObject: { virtuals: true },
}
);
Document without populated fields
{
"discountPercentage": 5.92,
"category": "5c8a38c714eb5c17645c911b",
"brand": "5c8a3abc14eb5c17645c9128",
"stock": 44,
"rating": 5,
"numberOfReviews": 0,
"images": [
"https://dummyjson.com/image/i/products/98/1.jpg",
"https://dummyjson.com/image/i/products/98/2.jpg",
"https://dummyjson.com/image/i/products/98/3.jpg",
"https://dummyjson.com/image/i/products/98/4.jpg",
"https://dummyjson.com/image/i/products/98/thumbnail.jpg"
],
"seller": 62dd1a1ace415b229452393e",
"active": true,
"_id": "62e2d0324971c94a30715b44",
"name": "3 lights lndenpant kitchen islang",
"description": "3 lights lndenpant kitchen islang dining room pendant rice paper chandelier contemporary led pendant light modern chandelier",
"price": 34,
"thumbnail": "https://dummyjson.com/image/i/products/98/thumbnail.jpg",
"slug": "3-lights-lndenpant-kitchen-islang",
"createdAt": "2022-07-28T18:06:43.006Z",
"updatedAt": "2022-07-28T18:06:43.006Z",
"discountedPrice": 32,
"id": "62e2d0324971c94a30715b44"
},
Document with populated fields (brand and category)
{
"discountPercentage": 5.92,
"category": {
"_id": "5c8a38c714eb5c17645c911b",
"name": "lighting",
"slug": "lighting"
},
"brand": {
"_id": "5c8a3abc14eb5c17645c9128",
"name": "dadawu",
"slug": "dadawu"
},
"stock": 44,
"rating": 5,
"numberOfReviews": 0,
"images": [
"https://dummyjson.com/image/i/products/98/1.jpg",
"https://dummyjson.com/image/i/products/98/2.jpg",
"https://dummyjson.com/image/i/products/98/3.jpg",
"https://dummyjson.com/image/i/products/98/4.jpg",
"https://dummyjson.com/image/i/products/98/thumbnail.jpg"
],
"seller": "62dd1a1ace415b229452393e",
"active": true,
"_id": "62e2d0324971c94a30715b44",
"name": "3 lights lndenpant kitchen islang",
"description": "3 lights lndenpant kitchen islang dining room pendant rice paper chandelier contemporary led pendant light modern chandelier",
"price": 34,
"thumbnail": "https://dummyjson.com/image/i/products/98/thumbnail.jpg",
"slug": "3-lights-lndenpant-kitchen-islang",
"createdAt": "2022-07-28T18:06:43.006Z",
"updatedAt": "2022-07-28T18:06:43.006Z",
"discountedPrice": 32,
"id": "62e2d0324971c94a30715b44"
},
I'm using a middleware to populate all fields whenever a request is made to an API
ProductSchema.pre(/^find/, function (next) {
this.populate({
path: "category",
select: "name _id slug",
}).populate({
path: "brand",
select: "name _id slug -categories",
});
next();
});
My question is that how can I filter the data based on populated fields.
For example: If I want to filter data based on category and brand, /products?catergory=smartphones&brand=apple
How to fulfill the above condition?
Mongoose version: ^5.13.14

MongoDB: How to aggregate and $group then filter specific date

Employee Schema
const employeeSchema = new mongoose.Schema(
{
name: {
type: String,
required: true,
trim: true,
},
email: {
type: String,
unique: true,
required: true,
trim: true,
lowercase: true,
validate(value) {
if (!validator.isEmail(value)) {
throw new Error('Email is invalid');
}
},
},
password: {
type: String,
required: true,
trim: true,
minLength: 6,
validate(value) {
if (value.toLowerCase().includes('password')) {
throw new Error("Password can not contain a word 'password'.");
}
},
},
birthdate: {
type: Date,
required: true,
},
cellphone: {
type: String,
required: true,
trim: true,
},
gender: {
type: String,
enum: ['남성', '여성'],
required: true,
},
hourly_wage: {
type: Number,
trim: true,
default: 0,
},
timeClocks: [
{
type: new mongoose.Schema({
start_time: {
type: Date,
required: true,
},
end_time: {
type: Date,
},
wage: {
type: Number,
required: true,
},
total: {
type: Number,
},
totalWorkTime: {
type: Number
}
}),
},
],
role: {
type: String,
enum: ['staff'],
default: 'staff',
},
stores: [
{
location: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: 'Location',
},
},
],
status: {
//현재 재직상태
type: String,
enum: ['재직자', '퇴직자'],
default: '재직자',
},
tokens: [
{
token: {
type: String,
required: true,
},
},
],
},
{
timestamps: true,
}
);
What I have done so far
const employees = shifts.map((d) => d.owner._id);
//timeclock
const temp = await Employee.aggregate([
{
$match: {
_id: { $in: employees },
},
},
{
$sort: { 'timeClocks.start_time': 1 },
},
{
$unwind: { path: '$timeClocks', preserveNullAndEmptyArrays: true },
},
{
$group: {
_id: '$_id',
name: { $first: '$name' },
timeClock: {
$push: '$timeClocks',
},
},
},
]);
My result
{
"shifts": [
{
"_id": "60e05b188be53900280bcdf2",
"date": "2021-07-09T00:00:00.000Z",
"day": "Fri",
"start": "2021-07-09T09:41:00.000Z",
"end": "2021-07-09T21:42:00.000Z",
"owner": {
"_id": "60cd9a3cb4ddcc00285b0df9",
"name": "Dr. dd"
},
"location": "60cd99b1b4ddcc00285b0df3",
"__v": 0
}
],
"timeClock": [
{
"_id": "60cd9a3cb4ddcc00285b0df9",
"name": "Dr. dd",
"timeClock": [
{
"_id": "60def63d19648a00286f0539",
"start_time": "2021-05-04T02:19:00.000Z",
"end_time": "2021-05-04T14:42:00.000Z",
"wage": 8720,
"total": 107735,
"totalWorkTime": 743
},
{
"_id": "60def63f19648a00286f053d",
"start_time": "2021-05-02T08:12:00.000Z",
"end_time": "2021-05-02T22:24:00.000Z",
"wage": 8720,
"total": 123540,
"totalWorkTime": 852
},
{
"_id": "60def64119648a00286f0541",
"start_time": "2021-05-10T20:14:00.000Z",
"end_time": "2021-05-10T22:17:00.000Z",
"wage": 8720,
"total": 17835,
"totalWorkTime": 123
},
}
]
Expected Result(2021-05-10)
{
"shifts": [
{
"_id": "60e05b188be53900280bcdf2",
"date": "2021-07-09T00:00:00.000Z",
"day": "Fri",
"start": "2021-07-09T09:41:00.000Z",
"end": "2021-07-09T21:42:00.000Z",
"owner": {
"_id": "60cd9a3cb4ddcc00285b0df9",
"name": "Dr. dd"
},
"location": "60cd99b1b4ddcc00285b0df3",
"__v": 0
}
],
"timeClock": [
{
"_id": "60cd9a3cb4ddcc00285b0df9",
"name": "Dr. dd",
"timeClock": {
"_id": "60def64119648a00286f0541",
"start_time": "2021-05-10T20:14:00.000Z",
"end_time": "2021-05-10T22:17:00.000Z",
"wage": 8720,
"total": 17835,
"totalWorkTime": 123
},
}
]
I am receiving the 'date string' example('URL/2021-05-10') via params and trying to query all employees that have the same date timeClocks.
also trying to send back everything I queried without different dates from timeClocks.
How can I filter out non-same dates?
You have string 2021-05-10 now you need a $match stage before your group so you can filter out timeClock. Something like:
{ $match: { 'timeClocks.start_time': new Date('2021-05-10') } }
Modify the match stage to your requirements like maybe add $gte or $lte or something like that.

Mongoose: How to query nested document and return String result?

Did a query Product.findOne({'variation.sku': req.params.productVariationSKU },{'_id': 0, 'variation.price' :1}) to find the price of a product variation.
But result returned price of all product variations. Need help to find where went wrong!
Below is product schema:
var ProductSchema = new Schema({
productId: {
type: Number,
required: [true, 'Product ID is required'],
unique: true
},
sku: String,
category: [String],
language: {
type: String,
lowercase: true,
maxlength: 2,
required: [true, 'Language code required'],
index: true,
unique: true
},
name: {
type: String,
required: [true, 'Product name is required']
},
descLong: String,
descShort: String,
mainImageURL: String,
galleryImageURL: [String],
variation: [{
sku: String,
option: [{
label: String,
value: String,
}],
inventory: [{
name: String,
quantity: Number,
country: String
}],
inStock: Boolean,
price: mongoose.Types.Decimal128
}],
attribute: [{
label: String,
value: [String]
}],
inStock: Boolean,
currencySymbol: String,
slug: String,
metaTitle: String,
metaDescription: String,
relatedAccessory: [Number],
htmlContentBefore: String,
htmlContentAfter: String
});
Below is product object from Postman:
{
"category": [],
"galleryImageURL": [
"TEST.png"
],
"relatedAccessory": [],
"_id": "5feae4418d686300176dfbbd",
"productId": 1,
"language": "en",
"name": "TEST PRODUCT",
"descLong": "<p><strong>This is a long description</strong></p>",
"descShort": "Short Description",
"mainImageURL": "TEST.png",
"variation": [
{
"option": [
{
"_id": "5feae4418d686300176dfbbf",
"label": "Color",
"value": "Black"
}
],
"inventory": [],
"_id": "5feae4418d686300176dfbbe",
"sku": "P-1",
"inStock": true,
"price": "45"
},
{
"option": [
{
"_id": "5feae4418d686300176dfbc1",
"label": "Color",
"value": "White"
}
],
"inventory": [],
"_id": "5feae4418d686300176dfbc0",
"sku": "P-2",
"inStock": true,
"price": "45"
}
],
"attribute": [
{
"value": [
"Black",
"White"
],
"_id": "5feae4418d686300176dfbc2",
"label": "Color"
}
],
"currencySymbol": "£",
"slug": "test",
"metaTitle": "testmeta",
"metaDescription": "This is meta description",
"__v": 0
}
Below is API function:
app.get('/API/Product/GetProductVariationPrice/:productVariationSKU', async(req, res) => {
try{
res.send(await Product.findOne({'variation.sku': req.params.productVariationSKU },{'_id': 0, variation :1}));
} catch (err) {
res.status(500).send(err);
}
});
Returned result from Postman:
{
"variation": [
{
"price": "45"
},
{
"price": "45"
}
]
}
Question: How can I get just "45" of variation SKU "P-1"? As the result currently returns the price of variation 'P-2' as well which is not wanted. SKU should be based on the param passed to the API.
Generally it will return array of object when we project specific field from array of object,
Starting in MongoDB 4.4, as part of making find projection consistent with aggregation’s $project stage,
$reduce to iterate loop of variation array, check condition if sku match then it will return price
await Product.findOne(
{ "variation.sku": req.params.productVariationSKU },
{
"_id": 0,
variation: {
$reduce: {
input: "$variation",
initialValue: 0,
in: {
$cond: [
{ $eq: ["$$this.sku", req.params.productVariationSKU] },
"$$this.price",
"$$value"
]
}
}
}
})
Playground
MongoDB 4.4 or below versions try aggregate(),
let p = Product.aggregate();
p.match({ "variation.sku": req.params.productVariationSKU });
p.project({
_id: 0,
variation: {
$reduce: {
input: "$variation",
initialValue: 0,
in: {
$cond: [
{ $eq: ["$$this.sku", req.params.productVariationSKU] },
"$$this.price",
"$$value"
]
}
}
}
});
res.send(await p.exec());
Playground

Collections association with nested in Mongoose

I had a problem with the association of collections.
I spent 2 days and still did not solve the problem, it's new for me.
My models:
// Schema opened cases
const openedSchema = new Schema({
user: {
type: Schema.Types.ObjectId,
ref: 'user',
required: [true, 'user is required'],
index: true
},
weapon: {
type: Schema.Types.ObjectId,
ref: 'cases.weapons',
required: [true, 'weapon is required'],
index: true
},
sellPrice: {
type: Number,
default: null
},
status: {
type: Number,
default: 0
}
}, {
timestamps: true
});
const opened = mongoose.model('opened', openedSchema);
// list cases
const casesSchema = new Schema({
name: {
type: String,
unique: true,
required: [true, 'name is required']
},
price: {
type: Number,
required: [true, 'price is required']
},
weapons: [ {
weapon: {
type: Schema.Types.ObjectId,
ref: 'weapon',
index: true
}
} ]
}, {
timestamps: false
});
const cases = mongoose.model('cases', casesSchema);
// list weapons
const weaponSchema = new Schema({
name: {
type: String,
unique: true,
required: [true, 'name is required']
},
price: {
type: Number,
required: [true, 'price is required']
},
autoship: {
count: Number,
status: Boolean,
price: Number
}
}, {
timestamps: false
});
const weapon = mongoose.model('weapon', weaponSchema);
That's what documents look like
// cases
{
"_id": {
"$oid": "59653bcfa9ac622e1913e10c"
},
"name": "test case #1",
"price": 256,
"weapons": [
{
"weapon": {
"$oid": "59653bcfa9ac622e1913e10b"
},
"_id": {
"$oid": "59653bcfa9ac622e1913e10d"
}
},
{
"_id": {
"$oid": "59653d3279aeda2fda9fb490"
},
"weapon": {
"$oid": "59653c5d069f562eb0ba4ef3"
}
},
{
"_id": {
"$oid": "59653d38ba04de2fdddc459f"
},
"weapon": {
"$oid": "59653c893a772e2ef7b65a29"
}
}
],
"__v": 0
}
// opened
{
"_id": {
"$oid": "5965d134c8c95972a1a498f5"
},
"updatedAt": {
"$date": "2017-07-12T07:35:16.419Z"
},
"createdAt": {
"$date": "2017-07-12T07:35:16.419Z"
},
"user": {
"$oid": "5965d0d6ea9db872360db98b"
},
"weapon": {
"$oid": "59653bcfa9ac622e1913e10d"
},
"status": 0,
"sellPrice": null,
"__v": 0
}
// weapon
{
"_id": {
"$oid": "59653bcfa9ac622e1913e10b"
},
"name": "AWP | Fever Dream",
"price": 300,
"autoship": {
"status": true,
"price": 167,
"count": 5
},
"__v": 0
}
I need to get a list of open cases with weapons data.
opened -> cases -> weapon
So, I do this:
opened.find()
.populate('cases.weapons')
.then(_opened => {
console.log(_opened);
})
.catch(err => {
logger.error(err);
});
But populate does not work.
Unless I am mistaken, there is no relationship between openedSchema and casesSchema.
It is not opened -> cases -> weapon but opened -> weapon as openedSchema has no field called cases -- which means cases will never be populated.
Based on your schema definition, it should be opened.find().populate('weapon').

Resources