mongoose populate query doesn't show the desired results - mongodb

I'm new to MongoDB and Mongoose and I'm having some problems with it, to be more specific I've problems with populate, problem displayed below.
My Schema:
'use strict';
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
/* ------------------------------------- Field config ---------------------------------------- */
const UsersSchema = new Schema({
name: {
type: String,
required: true,
min: 3,
set: str => str.replace(/\b\w/g, l => l.toUpperCase())
},
lastname: {
type: String,
required: true,
min: 3,
set: str => str.replace(/\b\w/g, l => l.toUpperCase())
},
email: {
type: String,
required: true,
unique: true,
validade: {
validator: str => regExp.test(str)
}
},
password: {
type: String,
required: true,
min: 8
},
fcm:{
type: String,
required: true
},
birthDate: {
type: Date,
required: true,
get: convertToBR
},
gender: {
type: String,
enum: ['M', 'F'],
required: true
},
profileImage: {
type: String,
required: false,
get: alterUri
},
aboutMe: {
type: String,
max: 500
},
enabled: {
type: Boolean,
required: true,
default: true
},
createdAt: {
type: Date,
required: true,
default: new Date()
},
token: {
type: String,
required: true,
index: true
},
locations: {
type: [mongoose.Schema.Types.ObjectId],
require: false,
ref: 'Location'
},
lastVisitants: {
type: [{
user: mongoose.Schema.Types.ObjectId,
createAt: {
type: Date,
required: true,
default: new Date()
}
}],
required: false,
ref: 'Users'
}
}, {
toObject: {
virtuals: true,
getters: true,
setters: true
},
toJSON: {
virtuals: true,
getters: true,
setters: true
}
});
//Code bellow removed for make to easy know
Generated doc inside MongoDB:
{
"_id": "589288de533c9555163cf263",
"email": "luiz#sene.com",
"password": "CQziXoB6XrBFBTWe5s/kFsIGYqbtDPBBKQgADUZF9co=",
"name": "luiz Fernando",
"lastname": "Sene",
"birthDate": "1988-08-11T00:00:00.000Z",
"gender": "M",
"fcm": "34567890987654345678",
"token": "58979c08b048917ed8b434ac",
"createdAt": "2017-02-02T01:17:38.168Z",
"enabled": true,
"__v": 0,
"aboutMe": "algo sobre mim aqui mudar",
"locations": [
"5893e2e0c8a01b4ed21c8c39",
"5893e305c8a01b4ed21c8c3a",
"5893e32ac8a01b4ed21c8c3b",
"5893e34dc8a01b4ed21c8c3c",
"5893e92838bd205ba42c2c8a",
"5893ea888628c45d2bc6683a"
],
"profileImage": "images/589288de533c9555163cf263/1486330852976.png",
"lastVisitants": [
{
"createAt": "2017-02-05T19:23:17.697Z",
"_id": "58977ba99fc2b7485dbdbf26",
"user": "589778e22a9dd5449e4f92df"
}
]
}
My problem occurs when I try populate locations and lastVisitants.
My consult is below:
UsersSchema.findOne({_id: data.data.id}, {lastVisitants: true, locations: true})
.populate({
path: 'locations',
model: 'Location',
select: 'description',
options: {
limit: 1,
sort: {
createdAt: -1
}
}
})
.populate({
path: 'lastVisitants.user',
model: 'Users',
select: '_id lastVisitants',
options: {
limit: 5
//TODO: Add sort by createdAt
}
})
.exec((err, result) => {
if (err) {
Utils.callback(err, null, res);
return;
}
Utils.callback(null, result, res);
});
Result of my consult:
{
"_id": "589288de533c9555163cf263",
"lastVisitants": [
{
"_id": "58977c1c9fc2b7485dbdbf27",
"user": {
"_id": "589778e22a9dd5449e4f92df",
"lastVisitants": [
{
"_id": "58977c1c9fc2b7485dbdbf27",
"user": "589288de533c9555163cf263",
"createAt": "2017-02-05T19:23:17.697Z"
}
],
"profileImage": "http://192.168.0.19:3000/undefined",
"birthDate": {
"en": "NaN-NaN-NaN",
"br": "NaN/NaN/NaN"
},
"fullname": "undefined undefined",
"age": null,
"id": "589778e22a9dd5449e4f92df"
},
"createAt": "2017-02-05T19:23:17.697Z"
}
],
"profileImage": "http://192.168.0.19:3000/undefined",
"birthDate": {
"en": "NaN-NaN-NaN",
"br": "NaN/NaN/NaN"
},
"fullname": "undefined undefined",
"age": null,
"id": "589288de533c9555163cf263"
}
Result expected:
{
"_id": "589288de533c9555163cf263",
"locations":[
{
"_id": "5893ea888628c45d2bc6683a",
"description": "Cruzeiro - SP, Brasil"
}
]
"lastVisitants": [
{
_id: ""
user: {
"id": "58977ba99fc2b7485dbdbf26",
"fullname": "Fábio Pereira",
"profileImage": "http://192.168.0.19:3000/images/589288de533c9555163cf263/1486319528451.jpeg",
"gender": "M",
// more fields ...
},
createdAt: ""
}
]
}
My question is how can I make this query bring what I really desire?

Related

How to find entire records using populated fields in mongoose

This are my schemas
var employeesSchema = new schema({
companyName: { type: String },
employeeName: { type: String },
employeeCode: { type: String, unique: true },
designation: { type: String },
department: { type: String },
officeLocation: { type: String },
workLocation: { type: String },
emailID: { type: String , unique: true},
managerName: { type: String },
managerEmail: { type: String },
countryCode: { type: String },
mobile: { type: String },
password: { type: String },
createdDate: { type: Date, default: new Date() }
})
var leaveRequests = new schema({
leaveRequestID: { type: String, unique: true },
employeeCode: { type: String, required: true },
requestedBy: { type: mongoose.Schema.Types.ObjectId, ref: "employees_master", required: true },
leaveType: { type: mongoose.Schema.Types.ObjectId, ref: "leavetypes", required: true },
startDate: { type: Date },
endDate: { type: Date },
remarks: { type: String },
documentUrl: { type: String },
status: { type: String, enum: ['pending', 'rejected', 'approved'], default: 'pending' },
statusUpdatedBy: { type: mongoose.Schema.Types.ObjectId, ref: "manager_or_lead_master" },
reason: { type: String },
isActive: { type: Boolean, default: true },
createdDate: { type: Date, default: new Date() },
});
Im trying to filter data with managerEmail: req.body.emailID
exports.getTeamLevelLeaveRequest = async (req, res) => {
try {
const getQuery = leaverequests.find({})
.populate('leaveType')
.populate('statusUpdatedBy')
.populate({
path: 'requestedBy',
match: {
managerEmail: req.body.emailID
}
})
.sort({ _id: -1 })
const resp = await getQuery;
const resAfterMap = resp.filter(u => u.requestedBy !== null)
responseHandler.successResponse(res, resAfterMap, "Leave Requests")
} catch (err) {
responseHandler.errorResponse(res, err, commonErrorMessage)
}
}
But Im receiving resp like
[{
"_id": "634e7459f78e446637a70ac6",
"leaveRequestID": "LR10",
"employeeCode": "MLI637",
"requestedBy": null,
"leaveType": {
"_id": "634d8d7ab69f5a80c4c98216",
"leaveType": "Compensatory Off",
"__v": 0,
"name": "Compensatory Off"
},
"startDate": "2022-10-18T18:30:00.000Z",
"endDate": "2022-10-18T18:30:00.000Z",
"remarks": "test",
"status": "pending",
"isActive": true,
"createdDate": "2022-10-18T08:27:42.042Z",
"__v": 0
},
{
"_id": "634e719c71313319a6da2432",
"leaveRequestID": "LR9",
"employeeCode": "MLI699",
"requestedBy": null,
"leaveType": {
"_id": "634d8d7ab69f5a80c4c98216",
"leaveType": "Compensatory Off",
"__v": 0,
"name": "Compensatory Off"
},
"startDate": "2022-10-18T18:30:00.000Z",
"endDate": "2022-10-18T18:30:00.000Z",
"remarks": "test",
"status": "pending",
"isActive": true,
"createdDate": "2022-10-18T08:25:04.220Z",
"__v": 0
},
{
"_id": "634e719c71313319a6da2432",
"leaveRequestID": "LR9",
"employeeCode": "MLI699",
"requestedBy": {
**populated data came ----**
},
"leaveType": {
"_id": "634d8d7ab69f5a80c4c98216",
"leaveType": "Compensatory Off",
"__v": 0,
"name": "Compensatory Off"
},
"startDate": "2022-10-18T18:30:00.000Z",
"endDate": "2022-10-18T18:30:00.000Z",
"remarks": "test",
"status": "pending",
"isActive": true,
"createdDate": "2022-10-18T08:25:04.220Z",
"__v": 0
},
]
I want to get data without filtering requestedBy is not equal to null
Im using filter method to do.
Is there any option to find filter data....

How to get distinct values of objects in mongoDb?

Hello I want to return recent 5 documents with only pickup objects with distinct values of pickup.loc in it.
Here is my schema:
const schema = new Schema<IShipment>({
shipper: { type: Schema.Types.ObjectId, ref: "USER" },
pickup: {
loc: { type: String, required: true }, // pickup address
date: { type: Date, default: new Date() },
time: {
from: { type: String },
to: { type: String },
},
latlng: {
type: { type: String, enum: [ "Point", "LineString", "Polygon" ], default: "Point" },
coordinates: { type: [Number], index: "2dsphere" }
},
person: {
name: { type: String },
phone: { type: String },
},
companyName: { type: String, required: true },
zip: { type: String, required: true },
}
}
Currently I m just getting recent 5 documents with pickup objects in it. Here is my query:
const select = { "pickup.companyName": 1, "pickup.loc": 1, "pickup.person": 1, "pickup.zip": 1, _id: 0 };
ShipmentModel.find({ shipper: userId }, select).sort({ $natural: -1 }).limit(5)
How can I get distinct values of pickup.loc and return recent documents with pickup objects? I m attaching the required response with comments in it
required response
[
{
"person": {
"name": "Ali",
"phone": "123456789"
},
"loc": "ELA Logistics pickup4, Uthal, 90150", //should be distinct
"companyName": "ELA Logistics pickup4",
"zip": "90150"
},
{
"person": {
"name": "Ali",
"phone": "123456789"
},
"loc": "ELA Logistics pickup4, Uthal, 90150", //should be distinct
"companyName": "ELA Logistics pickup4",
"zip": "90150"
},
]

sequelize return only first row ( through the include association)

i am using sequelize include to associate the next three models
"moldsets" has many "molds" and "molds" has many "moldstatus"
// moldsets.model.js
const Sequelize = require("sequelize");
const DataTypes = Sequelize.DataTypes;
module.exports = function (app) {
const sequelizeClient = app.get("sequelizeClient");
const moldsets = sequelizeClient.define(
"moldsets",
{
name: {
type: DataTypes.STRING,
allowNull: false,
},
vendor: {
type: DataTypes.STRING,
allowNull: false,
},
status: {
type: DataTypes.STRING,
allowNull: false,
},
number_of_blanks: {
type: DataTypes.INTEGER,
allowNull: false,
},
number_of_blows: {
type: DataTypes.INTEGER,
allowNull: false,
},
date_of_reception: {
type: DataTypes.DATE,
allowNull: false,
},
date_of_scrap: {
type: DataTypes.DATE,
allowNull: true,
},
},
{
hooks: {
beforeCount(options) {
options.raw = true;
},
},
}
);
// eslint-disable-next-line no-unused-vars
moldsets.associate = function (models) {
// Define associations here
// See http://docs.sequelizejs.com/en/latest/docs/associations/
const { molds } = models;
// Define associations here
// See http://docs.sequelizejs.com/en/latest/docs/associations/
moldsets.hasMany(molds, { foreignKey: "moldsetId" });
};
return moldsets;
};
//molds.model.js
const Sequelize = require("sequelize");
const DataTypes = Sequelize.DataTypes;
module.exports = function (app) {
const sequelizeClient = app.get("sequelizeClient");
const molds = sequelizeClient.define(
"molds",
{
number: {
type: DataTypes.INTEGER,
allowNull: false,
},
kind: {
type: DataTypes.STRING,
allowNull: false,
},
moldsetId: {
type: DataTypes.INTEGER,
allowNull: false,
},
numberOfTotalGobs: {
type: DataTypes.INTEGER,
allowNull: false,
},
statusId: {
type: DataTypes.INTEGER,
allowNull: false,
},
note: {
type: DataTypes.STRING,
allowNull: false,
},
},
{
hooks: {
beforeCount(options) {
options.raw = true;
},
},
}
);
// eslint-disable-next-line no-unused-vars
molds.associate = function (models) {
// Define associations here
// See http://docs.sequelizejs.com/en/latest/docs/associations/
console.log(models);
const { moldsets, moldstatus } = models;
molds.belongsTo(moldsets);
molds.hasMany(moldstatus, { as: "status" });
};
return molds;
};
// moldstatus.model.js
const Sequelize = require("sequelize");
const DataTypes = Sequelize.DataTypes;
module.exports = function (app) {
const sequelizeClient = app.get("sequelizeClient");
const moldstatus = sequelizeClient.define(
"moldstatus",
{
moldId: {
type: DataTypes.INTEGER,
allowNull: false,
},
status: {
type: DataTypes.STRING,
allowNull: false,
},
startdate: {
type: DataTypes.DATE,
allowNull: false,
},
enddate: {
type: DataTypes.DATE,
allowNull: true,
},
note: {
type: DataTypes.STRING,
allowNull: true,
},
lineId: {
type: DataTypes.INTEGER,
allowNull: false,
},
section: {
type: DataTypes.STRING,
allowNull: false,
},
defect: {
type: DataTypes.STRING,
allowNull: true,
},
numberOfGobs: {
type: DataTypes.INTEGER,
allowNull: false,
},
operatorId: {
type: DataTypes.INTEGER,
allowNull: false,
},
},
{
hooks: {
beforeCount(options) {
options.raw = true;
},
},
}
);
// eslint-disable-next-line no-unused-vars
moldstatus.associate = function (models) {
// Define associations here
// See http://docs.sequelizejs.com/en/latest/docs/associations/
const { molds } = models;
moldstatus.belongsTo(molds, { foreignKey: "statusId" });
};
return moldstatus;
};
but when i query the moldset ( i am using feathersjs so i am using it in the before find hook )
const related = async (context) => {
const sequelize = context.app.get("sequelizeClient");
const { molds, moldstatus } = sequelize.models;
context.params.sequelize = {
include: [
//{ all: true, nested: true },
{
model: molds,
attributes: ["number", "statusId"],
required: false,
order: [[molds, "number", "ASC"]],
include: [
{
model: moldstatus,
as: "status",
required: false,
attributes: ["status"],
//order: [[moldstatus, "created_at", "DESC"]],
},
],
raw: false,
},
],
raw: false,
};
return context;
};
module.exports = {
before: {
all: [
authenticate("jwt"),
(context) => {
related(context);
},
],
find: [],
get: [],
create: [],
update: [],
patch: [],
remove: [],
},
};
the result is i got all the moldsets with its molds but i got only the first mold status for the first mold only in each moldset ( the other molds got empty array )
i tried setting raw to true but i still got the status for the first mold in each moldset only ...
//result
[{
"id": 2,
"name": "fruity250ml1",
"vendor": "jacob",
"status": "mounted",
"number_of_blanks": 30,
"number_of_blows": 28,
"date_of_reception": "2021-04-26T13:22:00.000Z",
"date_of_scrap": null,
"createdAt": "2021-04-26T13:22:00.000Z",
"updatedAt": "2021-04-26T13:22:00.000Z",
"molds": [
{
"number": 1,
"statusId": 3,
"status": [
{
"status": "mounted"
}
]
},
{
"number": 2,
"statusId": 4,
"status": []
}
],
"mounted": null
},
{
"id": 1,
"name": "seles250ml1",
"vendor": "omco",
"status": "avalible",
"number_of_blanks": 30,
"number_of_blows": 28,
"date_of_reception": "2021-07-26T13:22:00.000Z",
"date_of_scrap": null,
"createdAt": "2021-07-26T13:22:00.000Z",
"updatedAt": "2021-07-26T13:22:00.000Z",
"molds": [
{
"number": 2,
"statusId": 2,
"status": []
},
{
"number": 3,
"statusId": 3,
"status": []
},
{
"number": 1,
"statusId": 3,
"status": [
{
"status": "avalible"
}
]
}
]
}
]
database :
molds:
moldstatus:
moldsets:
First of all, if you indicate a foreign key field in some association explicitly you should indicate it for the reversed association as well:
moldsets.hasMany(molds, { foreignKey: "moldsetId" });
...
molds.belongsTo(moldsets, { foreignKey: "moldsetId" });
molds.hasMany(moldstatus, { as: "status", foreignKey: "statusId" });
...
moldstatus.belongsTo(molds, { foreignKey: "statusId" });
And you indicated incorrect foreign key field for molds.hasMany(moldstatus so the above associations should be like this:
molds.hasMany(moldstatus, { as: "status", foreignKey: "moldId" });
...
moldstatus.belongsTo(molds, { foreignKey: "moldId" });

How to query to get all documents referenced to another collection based on one field as username

In my Node API and MongoDB, I'm trying to make an endpoint to get all the posts associated with one username of a profile. In my Profile schema, I have a reference to the Post Schema and in my Post schema, I have a reference to the Username from Profile schema.
My issue I don't know how to get all the posts for that username. I did similarly but with embedded for the Experience schema but I'm not sure how to do that for the referenced collections.
Post model:
const { Connect } = require("../db");
const reactionSchema = {
likedBy: {
type: String,
unique: true,
sparse: true
}
};
const postSchema = {
text: {
type: String,
required: true,
unique: true,
sparse: false
},
username: {
type: Connect.Schema.Types.String,
ref: "Profile"
},
image: {
type: String,
default: "https://via.placeholder.com/150",
required: false
},
createdAt: {
type: Date,
default: Date.now,
required: false
},
updatedAt: {
type: Date,
default: Date.now,
required: false
},
reactions: [reactionSchema],
comments: {
type: Connect.Schema.Types.ObjectId,
ref: "Comment",
required: false
}
};
const collectionName = "post";
const postSchemaModel = Connect.Schema(postSchema);
const Post = Connect.model(collectionName, postSchemaModel);
module.exports = Post;
Profile model:
// Here defining profile model
// Embedded we have the Experience as []
const { Connect } = require("../db");
const { isEmail } = require("validator");
const postSchema = {
type: Connect.Schema.Types.ObjectId,
ref: "Post"
};
const experienceSchema = {
role: {
type: String,
required: true
},
company: {
type: String,
required: true
},
startDate: {
type: Date,
required: true
},
endDate: {
type: Date,
required: false
},
description: {
type: String,
required: false
},
area: {
type: String,
required: true
},
createdAt: {
type: Date,
default: Date.now,
required: false
},
updatedAt: {
type: Date,
default: Date.now,
required: false
},
username: {
type: String,
required: false
},
image: {
type: String,
required: false,
default: "https://via.placeholder.com/150"
}
};
const profileSchema = {
firstname: {
type: String,
required: true
},
surname: {
type: String,
required: true
},
email: {
type: String,
trim: true,
lowercase: true,
unique: true,
required: [true, "Email is required"],
validate: {
validator: string => isEmail(string),
message: "Provided email is invalid"
}
},
bio: {
type: String,
required: true
},
title: {
type: String,
required: true
},
area: {
type: String,
required: true
},
imageUrl: {
type: String,
required: false,
default: "https://via.placeholder.com/150"
},
username: {
type: String,
required: true,
unique: true
},
experience: [experienceSchema],
posts: [postSchema],
createdAt: {
type: Date,
default: Date.now,
required: false
},
updatedAt: {
type: Date,
default: Date.now,
required: false
}
};
const collectionName = "profile";
const profileSchemaModel = Connect.Schema(profileSchema);
const Profile = Connect.model(collectionName, profileSchemaModel);
module.exports = Profile;
I was able to make this for the embedded experience but not sure that correct for referenced collection:
const profileWithExperiences = await Student.aggregate([
{ $match: { username: res.username.username } },
{
$unwind: "$experience"
},
{
$match: {
"experience._id": new ObjectID(req.params.experienceId)
}
},
{
$project: {
username: 1,
experience: 1,
_id: 0
}
}
]);
I would like to see an example for referenced collections as it is confusing me how should I do that
[EDIT]
JSON for Profiles and Posts
{
"_id": ObjectId("5e2c98fc3d785252ce5b5693"),
"imageUrl": "https://i.pravatar.cc/300",
"firstname": "Jakos",
"surname": "Lemi",
"email": "lemi#email.com",
"bio": "My bio bio",
"title": "Senior IT developer",
"area": "Copenhagen",
"username": "Jakos",
"experience": [
{
"image": "https://via.placeholder.com/150",
"_id": ObjectId("5e3975f95fbeec9095ff3d2f"),
"role": "Developer",
"company": "Google",
"startDate": ISODate("2018-11-09T23:00:00.000Z"),
"endDate": ISODate("2019-01-05T23:00:00.000Z"),
"area": "Copenhagen",
"createdAt": ISODate("2020-02-04T13:47:37.167Z"),
"updatedAt": ISODate("2020-02-04T13:47:37.167Z")
},
{
"image": "https://via.placeholder.com/150",
"_id": ObjectId("5e3978bf5e399698e20c56d4"),
"role": "Developer",
"company": "IBM",
"startDate": ISODate("2018-11-09T23:00:00.000Z"),
"endDate": ISODate("2019-01-05T23:00:00.000Z"),
"area": "Copenhagen",
"createdAt": ISODate("2020-02-04T13:59:27.412Z"),
"updatedAt": ISODate("2020-02-04T13:59:27.412Z")
}
],
"createdAt": ISODate("2020-01-25T19:37:32.727Z"),
"updatedAt": ISODate("2020-02-04T23:14:37.122Z"),
"__v": NumberInt("0")
}
Post
{
"_id": ObjectId("5e3beb639e072afedd19dcef"),
"username": ObjectId("5e2c98fc3d785252ce5b5693"),
"image": "https://via.placeholder.com/150",
"text": "My awesome post",
"createdAt": ISODate("2020-02-06T10:33:07.22Z"),
"updatedAt": ISODate("2020-02-06T10:33:07.22Z"),
"reactions": [ ],
"__v": NumberInt("0")
}
Output expected:
{
"username": "Jakos",
"postsCount": [1],
"posts": [
{
"_id": ObjectId("5e3beb639e072afedd19dcef"),
"image": "https://via.placeholder.com/150",
"text": "My awesome post",
"createdAt": ISODate("2020-02-06T10:33:07.22Z"),
"updatedAt": ISODate("2020-02-06T10:33:07.22Z"),
"reactions": [ ],
"__v": NumberInt("0")
}
]
}
I want to see all the posts related to that username
You can use the $lookup aggregation to join collections.
db.profiles.aggregate([
{
$match: {
username: "Jakos"
}
},
{
$lookup: {
from: "posts", //the name of the posts collection, change this if it is different
localField: "_id",
foreignField: "username",
as: "posts"
}
},
{
$project: {
username: 1,
posts: 1,
postsCount: {
$size: "$posts"
},
_id: 0
}
}
])
Playground
For mongoose it should be like this in your app:
const profileWithExperiences = await Student.aggregate([
{ $match: { username: res.username.username } },
{
$unwind: "$experience"
},
{
$lookup: {
from: "posts", //the name of the posts collection, change this if it is different
localField: "_id",
foreignField: "username",
as: "posts"
}
},
{
$project: {
username: 1,
posts: 1,
postsCount: {
$size: "$posts"
},
_id: 0
}
}
]);
Try to get like this i am getting data from two table with the use of node and mongodb.
var param = {};
param['user_id']=id;
var search={ user_id:param.user_id,status: [ 'Pending', 'Accepted' ] };
var output={};
output = await JobRequest.find(search);
if(output !=0)
{
var JSon=await JobRequest.aggregate([
{$match: { user_id: {$gte:id}} },
{
"$project": {
"employee_id": {
"$toObjectId": "$employee_id"
},
"service_id": {
"$toObjectId": "$service_id"
},
"createdDate": {
"$toString": "$createdDate"
},
"chat_status": {
"$toString": "$chat_status"
},
"status": {
"$toString": "$status"
},
"delivery_address": {
"$toString": "$delivery_address"
},
"delivery_lat": {
"$toString": "$delivery_lat"
},
"delivery_lang": {
"$toString": "$delivery_lang"
},
}
},
{
$lookup:
{
from: "employees",
localField: "employee_id",
foreignField: "_id",
as: "employee_details"
}
},
{
$lookup:
{
from: "services",
localField: "service_id",
foreignField: "_id",
as: "service_details"
}
}
]);

Mongoose .populate() doesn't populate whole user model

I am trying to use mongodb query .populate() to populate user data in my allocations response.
But i looks like it is not working. It is not populating user data but only id (take a look at response below). I have tride to use "user" or "users" but when i use "user" it return user as null
User model
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const UserSchema = new Schema({
email: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
},
allocations: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'allocation'
}],
admin: {
type: Boolean,
default: false
},
date: {
type: Date,
default: Date.now
},
});
module.exports = mongoose.model('users', UserSchema);
Allocations models
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const AllocationSchema = new Schema({
name: {
type: String,
default: 'New'
},
jan: {
type: String,
default: 0
},
feb: {
type: String,
default: 0
},
mar: {
type: String,
default: 0
},
apr: {
type: String,
default: 0
},
may: {
type: String,
default: 0
},
jun: {
type: String,
default: 0
},
jul: {
type: String,
default: 0
},
aug: {
type: String,
default: 0
},
sep: {
type: String,
default: 0
},
nov: {
type: String,
default: 0
},
oct: {
type: String,
default: 0
},
dec: {
type: String,
default: 0
},
})
const AllocationsSchema = new Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
refs: 'users'
},
year: {
type: String,
},
allocations: [AllocationSchema],
date: {
type: Date,
default: Date.now
}
});
module.exports = mongoose.model('allocation', AllocationsSchema);
exports.getAllUsersAndAllocations = async (req, res) => {
try {
let users = await AllocationModel.find({
year: "2019"
}).populate(
'user'
)
return res.json(users)
} catch (error) {
console.error(error.message)
return res.status(500).send('Server error')
}
}
response:
{
"_id": "5d76ceb0e1fa5c2b6f8f5bed",
"user": "5d7671c446c7ba228ca1382b",
"year": "2019",
"allocations": [
{
"name": "New",
"jan": "0",
"feb": "0",
"mar": "0",
"apr": "0",
"may": "0",
"jun": "0",
"jul": "0",
"aug": "0",
"sep": "0",
"nov": "0",
"oct": "0",
"dec": "0",
"_id": "5d76ceb3e1fa5c2b6f8f5bef"
},
{
"name": "New",
"jan": "0",
"feb": "0",
"mar": "0",
"apr": "0",
"may": "0",
"jun": "0",
"jul": "0",
"aug": "0",
"sep": "0",
"nov": "0",
"oct": "0",
"dec": "0",
"_id": "5d76ceb0e1fa5c2b6f8f5bee"
}
],
"date": "2019-09-09T22:14:08.573Z",
"__v": 1
},
It looks like it may just be a typo in your AllocationSchema. Under 'User' you have written refs: 'users' when it should be ref: 'users' i.e. 'ref' instead of 'refs'