Currently am having a problem with a simple query.
Sequelize query:
db[TABLE_NAMES.BOOKING].findAll({
order: [
[ db[TABLE_NAMES.USER_BOOKING_RELATION], db[TABLE_NAMES.BOOKING_STATUS], sequelize.literal('status = \'Attention\''), 'desc'],
['created_at', 'desc']
],
offset,
limit: max,
attributes: ['id', 'created_at'],
where: { school_id: schoolId },
include: [
{
attributes: ['id'],
model: db[TABLE_NAMES.USER_BOOKING_RELATION],
include: [
{
required: true,
attributes: ['status'],
model: db[TABLE_NAMES.BOOKING_STATUS],
where: { status: { [Sequelize.Op.in]: ['Attention', 'Pending', 'Invited'] } }
},
]
}
]
});
Models
const booking = sequelize.define(TABLE_NAMES.BOOKING, {
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
unique: true
},
created_at: {
type: DataTypes.DATE,
defaultValue: sequelize.literal('NOW()')
},
updated_at: {
type: DataTypes.DATE,
defaultValue: sequelize.literal('NOW()')
},
deleted_at: {
type: DataTypes.DATE
}
});
const user_booking_relation = sequelize.define(TABLE_NAMES.USER_BOOKING_RELATION, {
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
unique: true
},
user_id: {
type: DataTypes.UUID,
allowNull: false
},
booking_id: {
type: DataTypes.UUID,
allowNull: false
},
booking_status_id: {
type: DataTypes.UUID,
allowNull: false,
},
created_at: {
type: DataTypes.DATE,
defaultValue: sequelize.literal('NOW()')
},
updated_at: {
type: DataTypes.DATE,
defaultValue: sequelize.literal('NOW()')
},
deleted_at: {
type: DataTypes.DATE
},
});
const booking_status = sequelize.define(TABLE_NAMES.BOOKING_STATUS, {
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
unique: true
},
status: {
type: DataTypes.STRING,
allowNull: false,
unique: true
},
created_at: {
type: DataTypes.DATE,
defaultValue: sequelize.literal('NOW()')
},
updated_at: {
type: DataTypes.DATE,
defaultValue: sequelize.literal('NOW()')
},
deleted_at: {
type: DataTypes.DATE
}
});
booking.hasMany(user_booking_relation, { foreignKey: 'booking_id', sourceKey: 'id' });
user_booking_relation.belongsTo(booking, { foreignKey: 'booking_id', targetKey: 'id' });
booking_status.hasMany(user_booking_relation, { foreignKey: 'booking_status_id', sourceKey: 'id' });
user_booking_relation.belongsTo(booking_status, { foreignKey: 'booking_status_id', targetKey: 'id' });
Generated sql
SELECT `booking`.*,
`user_booking_relations`.`id` AS `user_booking_relations.id`,
`user_booking_relations->booking_status`.`id` AS `user_booking_relations.booking_status.id`,
`user_booking_relations->booking_status`.`status` AS `user_booking_relations.booking_status.status`
FROM (SELECT `booking`.`id`, `booking`.`created_at`
FROM `booking` AS `booking`
WHERE (`booking`.`deleted_at` IS NULL AND `booking`.`school_id` = 'a97b42e5-c864-4a4a-870b-737dd9700124')
AND (SELECT `user_booking_relations`.`booking_id`
FROM `user_booking_relation` AS `user_booking_relations`
INNER JOIN `booking_status` AS `booking_status`
ON `user_booking_relations`.`booking_status_id` = `booking_status`.`id` AND
(`booking_status`.`deleted_at` IS NULL AND
`booking_status`.`status` IN ('Invited', 'Pending', 'Attention'))
WHERE ((`user_booking_relations`.`deleted_at` IS NULL) AND
`user_booking_relations`.`booking_id` = `booking`.`id`)
LIMIT 1) IS NOT NULL
ORDER BY `booking`.`created_at` DESC
LIMIT 0, 10) AS `booking`
LEFT OUTER JOIN ( `user_booking_relation` AS `user_booking_relations` INNER JOIN `booking_status` AS `user_booking_relations->booking_status` ON
`user_booking_relations`.`booking_status_id` = `user_booking_relations->booking_status`.`id` AND
(`user_booking_relations->booking_status`.`deleted_at` IS NULL AND
`user_booking_relations->booking_status`.`status` IN ('Invited', 'Pending', 'Attention')) )
ON `booking`.`id` = `user_booking_relations`.`booking_id` AND
(`user_booking_relations`.`deleted_at` IS NULL)
ORDER BY `user_booking_relations->booking_status`.status = 'Attention' DESC, `booking`.`created_at` DESC;
Result
// first page
// first page
[
{
"id": "4c74c307-3f7c-40c6-ba26-6d0e9f510bcc",
"created_at": "2020-05-30T20:15:07.000Z",
"user_booking_relations": [
{
"id": "7cb183c7-77cf-4fc8-9c98-eb2b8abf8d39",
"booking_status": {
"status": "Attention"
}
}
]
},
{
"id": "1e8c9250-61b5-4610-b913-bd7aee866d5d",
"created_at": "2020-06-01T14:48:00.000Z",
"user_booking_relations": [
{
"id": "0a9ba1a0-0929-4979-ba15-12c4903fd8a5",
"booking_status": {
"status": "Invited"
}
},
]
},
{
"id": "a1624f59-ebaa-4bc7-95b8-d0e96c1ec917",
"created_at": "2020-06-01T08:45:12.000Z",
"user_booking_relations": [
{
"id": "fdbc677b-2035-44d2-8d9a-ab304e5624ee",
"booking_status": {
"status": "Pending"
}
}
]
}
]
// second page
[
{
"id": "d18abf5c-c986-4c2c-a08d-02e1488745d8",
"created_at": "2020-05-30T20:14:10.000Z",
"user_booking_relations": [
{
"id": "585c0674-13cf-45ac-91bc-087b345a7b31",
"booking_status": {
"status": "Attention"
}
}
]
},
{
"id": "692ccef9-12b4-4aed-955b-11ce65512469",
"created_at": "2020-05-30T20:12:45.000Z",
"user_booking_relations": [
{
"id": "5c3d214d-833a-482d-aeb5-272af750f3bb",
"booking_status": {
"status": "Attention"
}
}
]
},
{
"id": "1a5a56a9-4a6e-4548-a4d8-b388e6a9ac02",
"created_at": "2020-05-30T20:09:43.000Z",
"user_booking_relations": [
{
"id": "cea240f4-2529-44ae-a82d-f53d2dbbd0fc",
"booking_status": {
"status": "Attention"
}
}
]
}
]
Expected result
// first page
[
{
"id": "4c74c307-3f7c-40c6-ba26-6d0e9f510bcc",
"created_at": "2020-05-30T20:15:07.000Z",
"user_booking_relations": [
{
"id": "7cb183c7-77cf-4fc8-9c98-eb2b8abf8d39",
"booking_status": {
"status": "Attention"
}
}
]
},
{
"id": "d18abf5c-c986-4c2c-a08d-02e1488745d8",
"created_at": "2020-05-30T20:14:10.000Z",
"user_booking_relations": [
{
"id": "585c0674-13cf-45ac-91bc-087b345a7b31",
"booking_status": {
"status": "Attention"
}
}
]
},
{
"id": "692ccef9-12b4-4aed-955b-11ce65512469",
"created_at": "2020-05-30T20:12:45.000Z",
"user_booking_relations": [
{
"id": "5c3d214d-833a-482d-aeb5-272af750f3bb",
"booking_status": {
"status": "Attention"
}
}
]
}
]
// second page
[
{
"id": "1a5a56a9-4a6e-4548-a4d8-b388e6a9ac02",
"created_at": "2020-05-30T20:09:43.000Z",
"user_booking_relations": [
{
"id": "cea240f4-2529-44ae-a82d-f53d2dbbd0fc",
"booking_status": {
"status": "Attention"
}
}
]
},
{
"id": "1e8c9250-61b5-4610-b913-bd7aee866d5d",
"created_at": "2020-06-01T14:48:00.000Z",
"user_booking_relations": [
{
"id": "0a9ba1a0-0929-4979-ba15-12c4903fd8a5",
"booking_status": {
"status": "Invited"
}
},
]
},
{
"id": "a1624f59-ebaa-4bc7-95b8-d0e96c1ec917",
"created_at": "2020-06-01T08:45:12.000Z",
"user_booking_relations": [
{
"id": "fdbc677b-2035-44d2-8d9a-ab304e5624ee",
"booking_status": {
"status": "Pending"
}
}
]
}
]
As we can see from the generated SQL, bookings with any of those statuses are initially selected and then sorted. I need Attention bookings to go first. How can I get around this or fix it? Any thoughts will be much appreciated.
Thanks,
Alex.
Related
None of the other SO articles got me a solution.
Schema Definition:
const jobSchema = new (require("mongoose").Schema)(
{
userID: { type: require("mongoose").Schema.Types.ObjectId, ref: "User" },
emailID: { type: String, trim: true, required: false },
jobTitle: { type: String, trim: true, required: false },
jobDescription: { type: String, trim: true, required: false },
company: { type: String, required: false },
position: { type: String, required: false },
noOfYearsExperience: { type: String, required: false },
domain: { type: String, required: false },
link: { type: String, required: false },
location: { type: String, required: false },
jobCreationStatus: { type: String, required: false },
isActive: { type: Boolean, default: true, required: false },
isFeatured: { type: Boolean, default: false, required: false },
ttl: { type: String, required: false },
expiryDate: { type: Date, required: false },
expired: { type: Boolean, default: false, required: false },
applicants: [{ userId: { type: require("mongoose").Schema.Types.ObjectId, ref: "User" } }],
},
{
timestamps: true,
}
);
jobSchema.index({ jobTitle: "text", domain: "text", location: "text" }, { weights: { jobTitle: 3, domain: 2, location: 1 } });
Query Function:
module.exports.getJobs = async (filters, searchText, pageNo, isAuth) => {
try {
if (!filters["expired"]) filters["expired"] = false;
if (!searchText) searchText = null;
return await Job.aggregate([
// { $match: { $or: [filters, { $text: { $search: "Kolkata" } }] } },
{ $match: { $text: { $search: "Kolkata" } } },
{
$facet: {
metadata: [{ $count: "total" }, { $addFields: { page: pageNo } }],
data: [{ $skip: pageNo * 30 }, { $limit: 30 }],
},
},
]);
} catch (err) {
console.log(err);
}
};
The exact behavior I want:
If searchText is null, match the filters. Else, just return the documents that match the searchText on the indexed fields. "Kolkata" is to be replaced by searchText.
The problem:
If the given $match are removed from the aggregate above, the query works fine. Response in Postman:
{
"status": "success",
"message": [
{
"metadata": [
{
"total": 1,
"page": 0
}
],
"data": [
{
"_id": "620aa56f5966e4052229232c",
"emailID": "roy.srijan#gmail.com",
"company": "SpaceShift",
"noOfYearsExperience": "4",
"domain": "Angulaar, React",
"location": "Kolkata",
"jobCreationStatus": "job",
"isActive": true,
"ttl": "2 week",
"expired": false,
"createdAt": "2022-02-14T18:54:39.275Z",
"updatedAt": "2022-02-14T18:54:39.275Z",
"__v": 0,
"jobTitle": "Frontend Developer"
}
]
}
]
}
Using { $match: { $text: { $search: "Kolkata" } } } returns:
{
"status": "success",
"message": [
{
"metadata": [],
"data": []
}
]
}
Using { $match: { $or: [filters, { $text: { $search: "Kolkata" } }] } } returns:
MongoServerError: error processing query: ns=job-database.jobsTree: $or
expired $eq false
TEXT : query=Kolkata, language=english, caseSensitive=0, diacriticSensitive=0, tag=NULL
Sort: {}
Proj: {}
Collation: { locale: "simple" }
planner returned error :: caused by :: Failed to produce a solution for TEXT under OR - other non-TEXT clauses under OR have to be indexed as well.
at MessageStream.messageHandler (/home/deep/Personal/job-qna/node_modules/mongoose/node_modules/mongodb/lib/cmap/connection.js:467:30)
at MessageStream.emit (events.js:375:28)
at processIncomingData (/home/deep/Personal/job-qna/node_modules/mongoose/node_modules/mongodb/lib/cmap/message_stream.js:108:16)
at MessageStream._write (/home/deep/Personal/job-qna/node_modules/mongoose/node_modules/mongodb/lib/cmap/message_stream.js:28:9)
at writeOrBuffer (internal/streams/writable.js:358:12)
at MessageStream.Writable.write (internal/streams/writable.js:303:10)
at TLSSocket.ondata (internal/streams/readable.js:726:22)
at TLSSocket.emit (events.js:375:28)
at addChunk (internal/streams/readable.js:290:12)
at readableAddChunk (internal/streams/readable.js:265:9) {
ok: 0,
code: 291,
codeName: 'NoQueryExecutionPlans',
'$clusterTime': {
clusterTime: new Timestamp({ t: 1645314629, i: 1 }),
signature: {
hash: new Binary(Buffer.from("0fa1bccca48bef06c203ef8c5a16857f5cdf16af", "hex"), 0),
keyId: new Long("7035651653462130689")
}
},
operationTime: new Timestamp({ t: 1645314629, i: 1 })
}
I have a debate collection, which holds all the debates and another collection holds the votes against each debate. So I wanted to retrieve all the debates with a new user flag (isVoted) if I found any user in the vote collection against each debate.
Vote model:
var voteSchema = new Schema({
user: { type: Schema.Types.ObjectId, required: true, ref: 'User' }, // One who votes
debate: { type: Schema.Types.ObjectId, required: true, ref: 'Debate' }
}, { timestamps: true });
Debate Model:
var debateSchema = new Schema({
category: { type: Schema.Types.ObjectId, required: true, ref: 'Category' },
question: { type: String, required: true },
Votes: { type: Number, default: 0 },
}, { timestamps: true });
Query
DebateData.aggregate([
{
$match: query
},
{
$sort : { createdAt : -1 }
},
{
$lookup: {
from: "votes", // must be the PHYSICAL name of the collection
localField: "_id",
foreignField: "debate",
as: "votes"
}
},
{
$addFields: {
'isVoted': {
$cond: { if: { $eq: [ '$votes.user', ObjectId(req.query.userId) ] }, then: 'true', else: 'false' }
}
}
},
{
$project: {
'_id': 1,
'question': 1,
'isVoted': 1,
'createdAt': 1
}
},
]).then(result => {
res.status(200).json({ success: true, status: 200, message: 'Debate videos', data: result});
}).catch(err => {
res.status(500).json({ success: false, status: 500, message: err.message })
});
Expected output:
{
"data": [
{
"_id": "60e81f8299a4809658290d80",
"votes": 10,
"category": [
{
"name": "Hockey"
}
],
"question": "What is football?",
"isVoted": true,
"createdAt": "2021-07-09T10:05:54.498Z"
},
{
"_id": "60e438f1194949add0cc2074",
"votes": 12,
"category": [
{
"name": "Cricket"
}
],
"question": "What is football?",
"isVoted": false,
"createdAt": "2021-07-06T11:05:21.654Z"
}
]
}
Current output:
{
"data": [
{
"_id": "60e81f8299a4809658290d80",
"votes": 10,
"category": [
{
"name": "Hockey"
}
],
"question": "What is football?",
"createdAt": "2021-07-09T10:05:54.498Z"
},
{
"_id": "60e438f1194949add0cc2074",
"votes": 12,
"category": [
{
"name": "Cricket"
}
],
"question": "What is football?",
"createdAt": "2021-07-06T11:05:21.654Z"
}
]
}
Vote Data:
{
data: [
{
"user": "69881f8299a480965829ytr267",
"debate": "60e81f8299a4809658290d80"
}
]
}
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.
I have a problem, I need to return an array just from my flows relationship. How can I get an array with a list of the flows of all companies?
My model and migrations are correct, I just don't know how to make the query return only the flows.
Company Model
module.exports = (sequelize) => {
const company = sequelize.define('company', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER
},
uuid: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4
},
name: {
type: DataTypes.STRING,
allowNull: false
}
})
company.hasMany(sequelize.models.flow, {foreignKey: 'company_id', as: 'flows'})
}
Flow model
module.exports = (sequelize) => {
const flow = sequelize.define('flow', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER
},
company_id: {
allowNull: false,
type: DataTypes.INTEGER
},
uuid: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4
},
name: {
type: DataTypes.STRING,
allowNull: false
},
description: {
type: DataTypes.TEXT
}
})
flow.belongsTo(sequelize.models.company, {foreignKey: 'company_id', as: 'company'})
}
Query
const companies = await ORM.models.company
.findAll({
include: [{
model: ORM.models.flow,
as: 'flows'
}]
})
This query is returning like this:
[
{
"id": 1,
"uuid": "f0c1a5e1-c54c-4083-8284-5a9b272e8ba1",
"name": "Company 1",
"created_at": "2021-02-11T05:47:55.830Z",
"updated_at": "2021-02-11T05:47:55.830Z",
"flows": [
{
"id": 1,
"company_id": 1,
"uuid": "768262d2-88b7-4e0f-81e8-30d7253aae65",
"name": "Flow 1",
"description": null,
"created_at": "2021-02-11T05:48:10.211Z",
"updated_at": "2021-02-11T05:48:10.211Z",
"companyId": 1
}
]
},
{
"id": 2,
"uuid": "3dea2541-a505-4f0c-a356-f1a2d449d050",
"name": "Company 1",
"created_at": "2021-02-11T05:48:11.872Z",
"updated_at": "2021-02-11T05:48:11.872Z",
"flows": [
{
"id": 2,
"company_id": 2,
"uuid": "3e66e8e6-3754-41e5-93ca-6e8ed49e2025",
"name": "Flow 2",
"description": null,
"created_at": "2021-02-11T05:48:20.743Z",
"updated_at": "2021-02-11T05:48:20.743Z",
"companyId": 2
}
]
}
]
I need to return like this:
[
{
"id":1,
"company_id":1,
"uuid":"768262d2-88b7-4e0f-81e8-30d7253aae65",
"name":"Flow 1",
"description":null,
"created_at":"2021-02-11T05:48:10.211Z",
"updated_at":"2021-02-11T05:48:10.211Z",
"companyId":1
},
{
"id":2,
"company_id":2,
"uuid":"3e66e8e6-3754-41e5-93ca-6e8ed49e2025",
"name":"Flow 2",
"description":null,
"created_at":"2021-02-11T05:48:20.743Z",
"updated_at":"2021-02-11T05:48:20.743Z",
"companyId":2
}
]
If you just want the flows related data, why to fetch company related data with flows in it? Perhaps, you could only fetch flows data.
const flows = await ORM.models.flow
.findAll({
where: ....,
..........
});
If anyhow, you still want to show the flows for particular companies without showing any attributes of the company model, just do something like this:
const companies = await ORM.models.company
.findAll({
attributes: [], //empty
include: [{
model: ORM.models.flow,
as: 'flows'
}]
});
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').