I want to keep only that data in counts which will be matched with it's parent id for each individual document.
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 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 }
);
My Query
const data = await StudentSchema.aggregate([
{ $match: { classID: mongoose.Types.ObjectId(`${req.params.id}`) } },
{
$lookup: {
from: "attendances",
pipeline: [
{
$match: {
subjectID: mongoose.Types.ObjectId(`${req.params.Sid}`),
},
},
{ $group: { _id: "$studentID", count: { $sum: 1 } } },
],
as: "counts",
},
},
]);
This is the data I'm getting from this query:
{
"data": [
{
"_id": "63677d2960fa65e95aef5e95",
"name": "Lavannya Urkande",
"email": "lavannya#gmail.com",
"number": "9130354519",
"rollNumber": 201,
"departmentID": "6365531fdc02a121ffeed944",
"classID": "636554e8dc02a121ffeed982",
"position": "Student",
"password": "$2a$10$mqysVgtIGrYbvMGtHE2vbu0z5g05BlwJizcc.CfWMld78VPrnvcrO",
"createdAt": "2022-11-06T09:23:53.803Z",
"updatedAt": "2022-11-06T09:23:53.803Z",
"__v": 0,
"counts": [
{
"_id": "6367819d60fa65e95aef5ea7",
"count": 2,
},
{
"_id": "63677d2960fa65e95aef5e95",
"count": 3,
}
]
},
{
"_id": "6367819d60fa65e95aef5ea7",
"name": "Sohan Shinde",
"email": "soham#gmail.com",
"number": "9130354510",
"rollNumber": 202,
"departmentID": "6365531fdc02a121ffeed944",
"classID": "636554e8dc02a121ffeed982",
"position": "Student",
"password": "$2a$10$DuXjtayCPgGwkNnpog5IYeEEkY56igtlA/m6vobT44wmlSLcXp1eK",
"createdAt": "2022-11-06T09:42:53.861Z",
"updatedAt": "2022-11-06T09:42:53.861Z",
"__v": 0,
"counts": [
{
"_id": "6367819d60fa65e95aef5ea7",
"count": 2,
},
{
"_id": "63677d2960fa65e95aef5e95",
"count": 3,
}
]
}
]
}
But I want this type of data from my query(counts)
The only data which matched with it's parent _id. Notice the _id and counts._id then you can understand my request.
{
"data": [
{
"_id": "63677d2960fa65e95aef5e95",
"name": "Lavannya Urkande",
"email": "lavannya#gmail.com",
"number": "9130354519",
"rollNumber": 201,
"departmentID": "6365531fdc02a121ffeed944",
"classID": "636554e8dc02a121ffeed982",
"position": "Student",
"password": "$2a$10$mqysVgtIGrYbvMGtHE2vbu0z5g05BlwJizcc.CfWMld78VPrnvcrO",
"createdAt": "2022-11-06T09:23:53.803Z",
"updatedAt": "2022-11-06T09:23:53.803Z",
"__v": 0,
"counts": [
{
"_id": "63677d2960fa65e95aef5e95",
"count": 3,
}
]
},
{
"_id": "6367819d60fa65e95aef5ea7",
"name": "Sohan Shinde",
"email": "soham#gmail.com",
"number": "9130354510",
"rollNumber": 202,
"departmentID": "6365531fdc02a121ffeed944",
"classID": "636554e8dc02a121ffeed982",
"position": "Student",
"password": "$2a$10$DuXjtayCPgGwkNnpog5IYeEEkY56igtlA/m6vobT44wmlSLcXp1eK",
"createdAt": "2022-11-06T09:42:53.861Z",
"updatedAt": "2022-11-06T09:42:53.861Z",
"__v": 0,
"counts": [
{
"_id": "6367819d60fa65e95aef5ea7",
"count": 2,
}
]
}
]
}
You can use filter method in your $project
const data = await StudentSchema.aggregate([
{ $match: { classID: mongoose.Types.ObjectId(`${req.params.id}`) } },
{
$lookup: {
from: "attendances",
pipeline: [
{
$match: {
subjectID: mongoose.Types.ObjectId(`${req.params.Sid}`),
},
},
{ $group: { _id: "$studentID", count: { $sum: 1 } } },
],
as: "counts",
},
},
{
$project: {
classID: 1,
departmentID: 1,
email: 1,
name: 1,
number: 1,
position: 1,
rollNumber: 1,
counts: {
$filter: {
input: "$counts",
cond: {
$eq: ["$$this._id", "$_id"],
},
},
},
},
},
]);
Related
I have two mongoose schema one for keywords :
const keywordSchema = new Schema<keywordI>(
{
sentence: { type: String, required: true },
example: { type: String, required: true },
translate: { type: String, required: true },
imageUrl: { type: String, required: true },
audioUrl: { type: String, required: true },
deletedAt: { type: Date, select: false },
},
{ timestamps: true }
);
and one for keywordsUser :
const keywordUserSchema = new Schema<keywordUserI>(
{
keywordId: {
type: mongoose.Types.ObjectId,
ref: "Keyword",
required: true,
},
userId: {
type: mongoose.Types.ObjectId,
ref: "User",
required: true,
},
isBookMarked: { type: Boolean, default: false },
correctAnswer: { type: Number, default: 0 },
wrongAnswer: { type: Number, default: 0 },
},
{ timestamps: true }
);
I want to get keywords by user grouped by type which I calculate from wrongAnswer and correctAnswer
I try to do this using aggregate
return KeyWordUser.aggregate([
{
$match: { userId },
},
{
$addFields: {
type: {
$function: {
body: getType,
args: ["$correctAnswer", "$wrongAnswer"],
lang: "js",
},
},
},
},
{
$group: {
_id: "$type",
words: {
$push: "$keywordId",
},
isBookMarked: {
$push: { isBookMarked: "$isBookMarked", keywordId: "$keywordId" },
},
},
},
{
$lookup: {
localField: "words",
from: "keywords",
foreignField: "_id",
as: "props",
},
},
{
$addFields: { type: "$_id" },
},
{
$project: {
_id: 0,
words: 0,
},
},
]);
I have this result from aggregate
returned data from. postman
I want to add new aggregate stage to get this result
previous result
[
{
"isBookMarked": [
{
"keywordId": "62e2a0ad3113b8234511cd72"
},
{
"isBookMarked": false,
"keywordId": "62e2a0ba3113b8234511cd74"
}
],
"props": [
{
"_id": "62e2a0ad3113b8234511cd72",
"sentence": "hello",
"example": "Hello , what's your name",
"translate": "مرحبا ما اسمك",
"imageUrl": "src/img/keywords/keyword-A7H_M-1659019437698.png",
"audioUrl": "src/audio/keywords/keyword-YyhUp-1659019437700.mpeg",
"createdAt": "2022-07-28T14:43:57.708Z",
"updatedAt": "2022-07-28T14:43:57.708Z",
"__v": 0
},
{
"_id": "62e2a0ba3113b8234511cd74",
"sentence": "hello 2 ",
"example": "Hello , what's your name 2 ",
"translate": "مرحبا ما اسمك 2",
"imageUrl": "src/img/keywords/keyword-2JO7D-1659019450396.png",
"audioUrl": "src/audio/keywords/keyword-kt5Tc-1659019450397.mpeg",
"createdAt": "2022-07-28T14:44:10.400Z",
"updatedAt": "2022-07-28T14:44:10.400Z",
"__v": 0
}
],
"type": "strong"
}
]
and i want this result :
[
{
"props": [
{
"_id": "62e2a0ad3113b8234511cd72",
"sentence": "hello",
"example": "Hello , what's your name",
"translate": "مرحبا ما اسمك",
"imageUrl": "src/img/keywords/keyword-A7H_M-1659019437698.png",
"audioUrl": "src/audio/keywords/keyword-YyhUp-1659019437700.mpeg",
"createdAt": "2022-07-28T14:43:57.708Z",
"updatedAt": "2022-07-28T14:43:57.708Z",
"__v": 0
},
{
"_id": "62e2a0ba3113b8234511cd74",
"isBookMarked" : false
"sentence": "hello 2 ",
"example": "Hello , what's your name 2 ",
"translate": "مرحبا ما اسمك 2",
"imageUrl": "src/img/keywords/keyword-2JO7D-1659019450396.png",
"audioUrl": "src/audio/keywords/keyword-kt5Tc-1659019450397.mpeg",
"createdAt": "2022-07-28T14:44:10.400Z",
"updatedAt": "2022-07-28T14:44:10.400Z",
"__v": 0
}
],
"type": "strong"
}
]
You can just populate with the keywordId not with aggregate
if its free_preview is true means, the video data must preview to all and when the free_preview is false means its not might expose the video data.
But in this scenario if free_preview is false then also the video data is expose.
i want to make this to preview the videos wheather the free_preview is true otherwise the videos doesn't expose.
how can i solve this?
-----------------API CODE--------------------
export const courses = async (req, res) => {
const all = await Course.find({ published: true})
.populate("instructor", "_id name")
.exec();
res.json(all)
};
import { json } from "express";
import mongoose from "mongoose";
const { ObjectId } = mongoose.Schema;
const lessonSchema = new mongoose.Schema(
{
title: {
type: String,
trim: true,
minlength: 3,
maxlength: 320,
required: true,
},
slug: {
type: String,
lowercase: true,
},
content: {
type: String,
minlength: 200,
},
video: {},
time:{
type: Number,
required: true,
trim: true,
min: 1,
max: 5
},
free_preview: {
type: Boolean,
default: false,
},
},
{ timestamps: true }
);
const courseSchema = new mongoose.Schema(
{
name: {
type: String,
trim: true,
minlength: 3,
maxlength: 320,
required: true,
},
slug: {
type: String,
lowercase: true,
},
description: {
type: {},
minlength: 200,
required: true,
},
price: {
type: Number,
default: 500,
},
image: {},
category: String,
published: {
type: Boolean,
default: false,
},
paid: {
type: Boolean,
default: true,
},
instructor: {
type: ObjectId,
ref: "User",
required: true,
},
Category:{
type : String,
trim: true,
min: 4,
max: 200
},
lessons: [lessonSchema],
},
{ timestamps: true }
);
export default mongoose.model("Course", courseSchema);
----------------------------api response ----------------------------------
[
{
"price": 400,
"published": true,
"paid": true,
"_id": "61d73468f0ef1c2df856d580",
"slug": "nmap-for-ethical-hacking",
"instructor": {
"_id": "61d73336f0ef1c2df856d57f",
"name": "lenin royal"
},
"name": "Nmap for ethical hacking",
"description": "sfdsfdf",
"lessons": [
{
"free_preview": false,
"_id": "61d73721da89b03378321bc3",
"title": "intro",
"content": "sdfdfdff",
"video": {
"Location": "https://berrys01.s3.ap-south-1.amazonaws.com/_k8b_Khyz9GgTZkomm7WS.mp4",
"Bucket": "berrys01",
"Key": "_k8b_Khyz9GgTZkomm7WS.mp4",
"ETag": "\"00bf0fea24f997ac205c16de2ca3f7fa-2\""
},
"slug": "intro",
"updatedAt": "2022-01-06T18:38:25.674Z",
"createdAt": "2022-01-06T18:38:25.674Z"
},
{
"free_preview": true,
"_id": "61d737b8da89b03378321bc4",
"title": "hgdsfhgsdf",
"content": "dfsdfdf",
"video": {
"Location": "https://berrys01.s3.ap-south-1.amazonaws.com/Nqc6YL5LG1r3kWZIPigc1.mp4",
"Bucket": "berrys01",
"Key": "Nqc6YL5LG1r3kWZIPigc1.mp4",
"ETag": "\"4fbfb64ae636171fa7a7020ecc3b6a9e-16\""
},
"slug": "hgdsfhgsdf",
"updatedAt": "2022-01-06T18:40:56.963Z",
"createdAt": "2022-01-06T18:40:56.963Z"
},
{
"free_preview": true,
"_id": "61d737cada89b03378321bc5",
"title": "hello",
"content": "dfgdfg",
"video": {
"Location": "https://berrys01.s3.ap-south-1.amazonaws.com/fv5jEXzphsJ9al9DMKAr3.mp4",
"Bucket": "berrys01",
"Key": "fv5jEXzphsJ9al9DMKAr3.mp4",
"ETag": "\"72e0076dec633d7f3630628e92ba1891-3\""
},
"slug": "hello",
"updatedAt": "2022-01-06T18:41:14.132Z",
"createdAt": "2022-01-06T18:41:14.132Z"
},
{
"free_preview": true,
"_id": "61d737d6da89b03378321bc6",
"title": "rgrg",
"content": "dgdf",
"video": {
"Location": "https://berrys01.s3.ap-south-1.amazonaws.com/gmYnDGSrspH4jgfhC8ybr.mp4",
"Bucket": "berrys01",
"Key": "gmYnDGSrspH4jgfhC8ybr.mp4",
"ETag": "\"72e0076dec633d7f3630628e92ba1891-3\""
},
"slug": "rgrg",
"updatedAt": "2022-01-06T18:41:26.610Z",
"createdAt": "2022-01-06T18:41:26.610Z"
},
{
"free_preview": true,
"_id": "61d737e2da89b03378321bc7",
"title": "rgdgry56t5",
"content": "5yr",
"video": {
"Location": "https://berrys01.s3.ap-south-1.amazonaws.com/hzRW7TJn9ichITOk-3A-w.mp4",
"Bucket": "berrys01",
"Key": "hzRW7TJn9ichITOk-3A-w.mp4",
"ETag": "\"72e0076dec633d7f3630628e92ba1891-3\""
},
"slug": "rgdgry56t5",
"updatedAt": "2022-01-06T18:41:38.985Z",
"createdAt": "2022-01-06T18:41:38.985Z"
}
],
From what I see, a solution would be to do something like this
const courses = await Course
.find({ published: true })
.populate({
path: 'lessons',
match: { free_preview: true },
select: 'name -_id'
})
.exec();
I have two fields for a vote poll like vote1 and vote2 which hold a candidateId. What I was trying to do is, calculate the number of vote counts for each candidate in my VotePoll collection.
My VotePollSchema looks like the following:
VotePollSchema = mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
required: true,
},
vote1: {
desc: "First Voted Candidate",
type: mongoose.Schema.Types.ObjectId,
ref: "Candidate",
type: String,
},
vote2: {
desc: "Second Voted Candidate",
type: mongoose.Schema.Types.ObjectId,
ref: "Candidate",
type: String,
},
isActive: {
desc: "is Active.",
type: Boolean,
default: true,
required: true,
},
});
What I want to achieve here is that count the number of votes for a candidate which might be in vote1 or vote2. Since each User is able to vote for one or two candidates at the same time.
So, how should I group this collection by the candidate? Which could be either in vote1 or in vote2. I've tried something like this but I don't think it's the appropriate way of doing it.
const votePolls = await VotePoll.aggregate([
{ $match: { isActive: true } },
{
$group: {
_id: {
$or: [{ firstVotedCandidate: "$firstVotedCandidate" }],
},
voteCount: { $sum: 1 },
},
},
]);
My expected result:
{
candidateOne: {
candidateName: "Joshua Solomon"
voteCount: 140
}
candidateTwo: {
candidateName: "Jenny Doe"
voteCount: 25
}
...
}
Sample input data:
[
{
"isActive": true,
"user": {
"fullName": "Joshua Solomon",
"createdAt": "2021-08-02T13:33:14.584Z",
"updatedAt": "2021-08-02T13:36:35.041Z",
"registeredBy": "61026c5e4fd8a53c98b8c579",
"id": "6107f4182e21a42bd8b2b9cb"
},
"vote1": {
"isActive": true,
"fullName": "Candidate 1",
"title": "Available Candidate",
"createdAt": "2021-07-28T12:35:27.868Z",
"updatedAt": "2021-07-28T12:35:27.868Z",
"id": "61014f0f8d0ad041c0cf493a"
},
"vote2": {
"isActive": true,
"fullName": "Candidate 4",
"title": "Fourth Candidate",
"createdAt": "2021-07-28T12:36:13.229Z",
"updatedAt": "2021-07-28T12:36:13.229Z",
"id": "61014f3d8d0ad041c0cf4940"
},
"createdAt": "2021-08-02T13:36:34.859Z",
"updatedAt": "2021-08-02T13:36:34.859Z",
"id": "6107f4e22e21a42bd8b2dae2"
},
{
"isActive": true,
"user": {
"fullName": "Jenny Doe",
"createdAt": "2021-08-02T13:33:15.351Z",
"updatedAt": "2021-08-03T06:10:53.632Z",
"registeredBy": "61026c5e4fd8a53c98b8c579",
"id": "6107f4192e21a42bd8b2d136"
},
"vote1": {
"isActive": true,
"fullName": "Candidate 4",
"title": "Fourth Candidate",
"createdAt": "2021-07-28T12:36:13.229Z",
"updatedAt": "2021-07-28T12:36:13.229Z",
"id": "61014f3d8d0ad041c0cf4940"
},
"vote2": {
"isActive": true,
"fullName": "Candidate 2",
"title": "Second Candidate",
"createdAt": "2021-07-28T12:35:56.425Z",
"updatedAt": "2021-07-28T12:35:56.425Z",
"id": "61014f2c8d0ad041c0cf493c"
},
"createdAt": "2021-08-03T06:10:53.389Z",
"updatedAt": "2021-08-03T06:10:53.389Z",
"id": "6108ddedcc1c4f2a505b4028"
}
]
This aggregate will return results in a sorted array:
[
{
'$addFields': {
'votes': [
'$vote1', '$vote2'
]
}
}, {
'$unwind': {
'path': '$votes'
}
}, {
'$group': {
'_id': {
'name': '$votes.fullName'
},
'voteCount': {
'$sum': 1
}
}
}, {
'$project': {
'candidateName': '$_id.name',
'voteCount': 1,
'_id': 0
}
}, {
'$sort': {
'voteCount': -1
}
}
]
The $addfields the vote fields into an array,
The $unwind separates the documents based on the votes,
The $group gets the voteCount, it will get the total votes regardless of whether they were the first or second vote
The $project is just to clean things up
And the $sort is to sort the array from most votes to least.
I think you'd be best suited by changing your schema, vote1 and vote2 store practically the same information so you could simplify by having a schema where you store votes as an array of objects:
VotePollSchema = mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
required: true,
},
votes: [{
desc: String,
type: mongoose.Schema.Types.ObjectId,
ref: "Candidate",
type: String,
}],
isActive: {
desc: "is Active.",
type: Boolean,
default: true,
required: true,
},
});
Then you could avoid the $addFields at the start
I have 2 schemas:
const SiteSchema = new mongoose.Schema(
{
placement: Number,
groupId: mongoose.SchemaTypes.ObjectId,
title: {
type: String,
required: true,
trim: true,
},
url: {
type: String,
required: true,
},
},
{ timestamps: true }
)
and
const GroupSchema = new mongoose.Schema(
{
placement: Number,
header: {
type: String,
required: true,
trim: true,
},
items: [Site.schema],
},
{ timestamps: true }
)
I'm trying to get all groups with up to 5 of their corresponding sites based on the sites placement value like this:
roup.find({ 'items.placement': { $lte: 5 } })
.skip(offset)
.limit(maxNumberOfResults)
.sort('placement')
.lean()
.then(groups => {res.send({ sites: groups}))
however the result i get is all the sites in the group, regardless of their placement value.
for example:
I'm expecting to get:
[
{
"_id": "60dd2c314d98940d90fe8861",
"placement": 0,
"createdAt": "some date",
"updatedAt": "some date",
"header": "group",
"items": [
{
"_id": "60dd2cb54d98940d90fefb2a",
"groupId": "60dd2c314d98940d90fe8861",
"placement": 1,
"title": "something",
"url": "some url",
"createdAt": "some date",
"updatedAt": "some date"
},
{
"_id": "60dd2cb54d98940d90fefb2d",
"groupId": "60dd2c314d98940d90fe8861",
"placement": 2,
},
{
"_id": "60dd2cb54d98940d90fefb2f",
"groupId": "60dd2c314d98940d90fe8861",
"placement": 3,
},
{
"_id": "60dd2cb54d98940d90fefb30",
"groupId": "60dd2c314d98940d90fe8861",
"placement": 4,
},{
"_id": "60dd2cb54d98940d90fefb30",
"groupId": "60dd2c314d98940d90fe8861",
"placement": 5,
},
]
but getting placements 6 and onwards as well
***If someone could also tell me how to sort the subdocument array according to the placement value, would be greatly appreciated.
Try changing items: [Site.schema] to items: [SiteSchema],
I have an aggregation pipeline which supposed to return an ordered array. However. Every time I make an API cal, it returns a different order each time. Here is my code
exports.getResultToCompetition = asyncHandler(async (req, res, next) => {
const data = await Result.aggregate([
{
$match: { competition: mongoose.Types.ObjectId(req.params.competitionId) },
},
{
$project: {
points: 1,
kilogramms: 1,
sector: 1,
user: 1,
competition: 1,
place: 1,
},
},
{
$sort: {
kilogramms: -1,
},
},
{
$lookup: {
from: "users", // must be the PHYSICAL name of the collection
localField: "user",
foreignField: "_id",
as: "user",
},
},
{
$addFields: {
user: {
$arrayElemAt: ["$user", 0],
},
},
},
{
$group: {
_id: "$sector",
res: {
$push: "$$ROOT",
},
},
},
]);
res.status(200).json({ success: true, data });
});
And the Schema:
const mongoose = require('mongoose');
const ResultSchema = new mongoose.Schema({
competitionSeries: {
type: String,
default: 0,
},
points: {
type: Number,
default: 0,
},
sector: {
type: String,
},
kilogramms: {
type: Number,
default: 0,
},
place: {
type: Number,
default: 0,
},
isCompetitionRunning: {
type: Boolean,
default: true,
},
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: true,
},
team: {
name: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
},
partner: {
type: String,
},
teamName: {
type: String,
},
},
competition: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Competition',
required: true,
},
});
module.exports = Result = mongoose.model('Result', ResultSchema);
The kilograms field is saved as a Double in the MongoDB database
I set the value in the frontend in React as a number.
I am not sure if its causing the problem.
The kilograms value supposed to be a float number like 14.5
This is the result which is correct:
{
"success": true,
"data": [
{
"_id": "B",
"res": [
{
"_id": "5eca12e2607c2c0017c16904",
"points": 1,
"kilogramms": 90.52,
"place": 59,
"sector": "B",
"competition": "5eb90caa7b45620017a4d919",
"user": {
"_id": "5eb82c89e5d6cc0017e71a2a",
"avatar": "placeholder.jpg",
"role": "user"
}
},
{
"_id": "5eca1406607c2c0017c16918",
"points": 2,
"kilogramms": 39.45,
"place": 10,
"sector": "B",
"competition": "5eb90caa7b45620017a4d919",
"user": {
"_id": "5eb83175e5d6cc0017e71a42",
"avatar": "653571a228226499806e8a717cf2d6e1",
"role": "user"
}
},
{
"_id": "5eca11fc607c2c0017c168f5",
"points": 3,
"kilogramms": 29.62,
"place": 8,
"sector": "B",
"competition": "5eb90caa7b45620017a4d919",
"user": {
"_id": "5eb83970e5d6cc0017e71a64",
"avatar": "1589316331809-feederuser",
"role": "user"
}
},
{
"_id": "5eca1250607c2c0017c168fa",
"points": 4,
"kilogramms": 24.25,
"place": 56,
"sector": "B",
"competition": "5eb90caa7b45620017a4d919",
"user": {
"_id": "5eb83a00e5d6cc0017e71a67",
"avatar": "placeholder.jpg",
"role": "user"
}
}
]
},
{
"_id": "C",
"res": [
{
"_id": "5eca12cc607c2c0017c16903",
"points": 1,
"kilogramms": 72.43,
"place": 52,
"sector": "C",
"competition": "5eb90caa7b45620017a4d919",
"user": {
"_id": "5eb83c2ee5d6cc0017e71a70",
"avatar": "56065850e67a64878e5034d06cecc0ea",
"role": "user"
}
},
{
"_id": "5eca1307607c2c0017c16907",
"points": 2,
"kilogramms": 43.35,
"place": 12,
"sector": "C",
"competition": "5eb90caa7b45620017a4d919",
"user": {
"_id": "5eb998864d62090017231ce6",
"avatar": "placeholder.jpg",
"role": "user",
"name": "Halász Tibor"
}
},
{
"_id": "5eca1325607c2c0017c16909",
"points": 3,
"kilogramms": 39.43,
"place": 15,
"sector": "C",
"competition": "5eb90caa7b45620017a4d919",
"user": {
"_id": "5eb9b46c4d62090017231cf8",
"avatar": "placeholder.jpg",
"role": "user"
}
},
{
"_id": "5eca14c1607c2c0017c16927",
"points": 4,
"kilogramms": 36.99,
"place": 11,
"sector": "C",
"competition": "5eb90caa7b45620017a4d919",
"user": {
"_id": "5eb82fdbe5d6cc0017e71a3d",
"avatar": "placeholder.jpg",
"role": "user"
}
}
]
}
]
}
After I call again the endpoint it shows a different order. Meaning, Sector C is coming first which is not correct because in Sector B there is a higher kilograms result.
You can add a maxKilogramm field to your documents, and sort by that field by adding the following stages to the end of your aggregation.
{
$addFields: {
"maxKilogramm": {
$max: "$res.kilogramms"
}
}
},
{
$sort: {
maxKilogramm: -1,
},
},
{
$project: {
maxKilogramm: 0
}
}
Playground