mongodb $addfields conditions is not working - node.js

i have used lookup for join 2 tables and i need to create 2 custom column so i have used the $addfields.
In $addfields, Member is not working but pqr is working.
I have a array of objects as a given below :
await mongoose.models.abc.aggregate([
{
$lookup:
{`enter code here`
from: 'xyz',
localField: 'id',
foreignField: '_id',
as: 'my'
}
},
{
$match: {
"my": { $ne: [] }
}
},
{
$addFields: {
pqr: { $cond: [{ $gte: ["$my.request", 1] }, { $sum: "$my.request" }, 0] },
Member: { $cond: [{ $eq: ["$myClub.request", 0] }, { $sum: "$myClub.request" }, 0] },
}
},
]);
[
{
"_id": "5ef05f650e26a40cb44a68d6",
"createdAt": "2020-06-22T07:36:05.640Z",
"updatedAt": "2020-06-22T07:36:05.640Z",
"__v": 0,
"my": [
{
"_id": "5eecc3c961767f21c8d694e0",
"request": 1,
"createdAt": "2020-06-19T13:55:21.573Z",
"updatedAt": "2020-06-19T13:55:21.573Z",
"__v": 0
},
{
"_id": "5ef1b8f2c3d54e21f4d6b332",
"request": 0,
"createdAt": "2020-06-23T08:10:26.036Z",
"updatedAt": "2020-06-23T08:10:26.036Z",
"__v": 0
}
]
}
]
i need a output like this:
[
{
"_id": "5ef05f650e26a40cb44a68d6",
"createdAt": "2020-06-22T07:36:05.640Z",
"updatedAt": "2020-06-22T07:36:05.640Z",
"__v": 0,
"my": [
{
"_id": "5eecc3c961767f21c8d694e0",
"request": 1,
"createdAt": "2020-06-19T13:55:21.573Z",
"updatedAt": "2020-06-19T13:55:21.573Z",
"__v": 0
},
{
"_id": "5ef1b8f2c3d54e21f4d6b332",
"request": 0,
"createdAt": "2020-06-23T08:10:26.036Z",
"updatedAt": "2020-06-23T08:10:26.036Z",
"__v": 0
}
],
"pqr":1, // for greater than eqaul to request=1
"Member":1 // // for eqaul to request=0
}
]

Related

How can I get total count of likes, dislikes and shares for each book Id from a table in mongodb using aggregate?

I have a table named histories. here is a sample of documents,
{
"_id": "6354e4210490e6f3dd109fb7",
"type": "like",
"bookId": "6329af1b1c67cc8eaf26fe42",
"userId": "635122ea40ef5d60e653fc9e",
"createdAt": "2022-10-23T06:50:09.166Z",
"updatedAt": "2022-10-23T06:50:09.166Z",
"__v": 0
},
{
"_id": "6354e4210490e6f3dd109fb9",
"type": "share",
"bookId": "6322db5464c70448ad0282d4",
"userId": "6301e9f243719de7e0637acf",
"createdAt": "2022-10-23T06:50:09.167Z",
"updatedAt": "2022-10-23T06:50:09.167Z",
"__v": 0
}
now i have to show a list of distinct bookId with its total likes, shares and dislikes count using aggregate in mongodb..
You can try with
db.histories.aggregate([
{
$group: {
_id: "$bookId" ,
likes: {
"$sum": { $cond: { if: { "$eq": ["$type", "like"]}, then: 1, else: 0 }}
},
dislikes: {
"$sum": { $cond: { if: { "$eq": ["$type", "dislike"]}, then: 1, else: 0 }}
},
shares: {
"$sum": { $cond: { if: { "$eq": ["$type", "share"]}, then: 1, else: 0 }}
},
}
},
])

compare date with mongoose timestamps using aggregate

This is the schema:
const mongoose = require("mongoose");
const OrderSchema = mongoose.Schema({
order_status: {
type: "String",
enum: ['Pending', 'Declined', 'Approved','Paid', 'Complete'],
default: "Pending",
},
},{ timestamps: true });
module.exports = mongoose.model("order", OrderSchema);
Stored data in db:
[
{
"_id": "61ceb03b76ed7e3b809bb15b",
"order_status": "Declined",
"createdAt": "2021-12-31T07:24:43.129Z",
"updatedAt": "2021-12-31T07:24:43.129Z",
"__v": 0
},
{
"_id": "61ceb04676ed7e3b809bb15e",
"order_status": "Paid",
"createdAt": "2021-12-31T00:00:00.000Z",
"updatedAt": "2021-12-31T07:24:54.951Z",
"__v": 0
},
{
"_id": "61ceb04f76ed7e3b809bb161",
"order_status": "Approved",
"createdAt": "2022-01-01T00:00:00.000Z",
"updatedAt": "2021-12-31T07:25:03.860Z",
"__v": 0
},
{
"_id": "61ceb05276ed7e3b809bb164",
"order_status": "Complete",
"createdAt": "2021-12-31T07:25:06.580Z",
"updatedAt": "2021-12-31T07:25:06.580Z",
"__v": 0
},
{
"_id": "61ceb05576ed7e3b809bb167",
"order_status": "Complete",
"createdAt": "2021-12-31T07:25:09.686Z",
"updatedAt": "2021-12-31T07:25:09.686Z",
"__v": 0
},
{
"_id": "61ceb06976ed7e3b809bb16d",
"order_status": "Complete",
"createdAt": "2021-12-31T07:25:29.569Z",
"updatedAt": "2021-12-31T07:25:29.569Z",
"__v": 0
},
{
"_id": "61ceb06d76ed7e3b809bb170",
"order_status": "Complete",
"createdAt": "2021-12-31T07:25:33.858Z",
"updatedAt": "2021-12-31T07:25:33.858Z",
"__v": 0
},
{
"_id": "61ceb07376ed7e3b809bb173",
"order_status": "Pending",
"createdAt": "2021-12-31T07:25:39.270Z",
"updatedAt": "2021-12-31T07:25:39.270Z",
"__v": 0
},
{
"_id": "61ceb07776ed7e3b809bb176",
"order_status": "Complete",
"createdAt": "2021-12-31T07:25:43.672Z",
"updatedAt": "2021-12-31T07:25:43.672Z",
"__v": 0
},
{
"_id": "61ceb07e76ed7e3b809bb179",
"order_status": "Complete",
"createdAt": "2021-12-31T07:25:50.963Z",
"updatedAt": "2021-12-31T07:25:50.963Z",
"__v": 0
},
{
"_id": "61ceb08276ed7e3b809bb17c",
"order_status": "Pending",
"createdAt": "2021-12-31T07:25:54.675Z",
"updatedAt": "2021-12-31T07:25:54.675Z",
"__v": 0
},
{
"_id": "61ceb08776ed7e3b809bb17f",
"order_status": "Complete",
"createdAt": "2021-12-31T07:25:59.616Z",
"updatedAt": "2021-12-31T07:25:59.616Z",
"__v": 0
},
{
"_id": "61ceb08d76ed7e3b809bb182",
"order_status": "Complete",
"createdAt": "2021-12-31T07:26:05.141Z",
"updatedAt": "2021-12-31T07:26:05.141Z",
"__v": 0
}
]
Query: the value of from = 2021-01-01T00:00:00.000Z and to = 2021-12-31T00:00:00.000Z
let from = new Date("2021-01-01")
let to = new Date("2021-12-31")
return await OrderSchema.aggregate([
{$match : { createdAt: {
$gte: from, $lte: to
} }
}
])
Using the above query I'm getting no record. when I change the time from createdAt: "2021-12-31T07:26:05.141Z" to createdAt: "2021-12-31T00:00:00.000Z" in DB then it work fine.
How can I get records of 1 month or 1 week from the current date and resolve the time issue?
I think this work for you may be or click here and check results
2022-01-01 --> $lte higher date so set less then
2021-12-31 --> $gte lower date so set grater then
db.collection.aggregate([
{
$match: {
$and: [
{
createdAt: {
$gte: "2021-12-31T00:00:00.000Z"
}
},
{
createdAt: {
$lte: "2022-01-01T00:00:00.000Z"
}
}
]
}
}
])
I believe you need the $and operator:
OrderSchema.aggregate([{
$match : {
$and: {
createdAt: { $gte: from },
createdAt: { $lte: to }
}
}
])

Mongoose aggregate by date and values

I cannot solve a problem I am having on a project.
First of all, I have a Schema called Emotions, shown below:
import mongoose from 'mongoose';
const EmotionSchema = new mongoose.Schema({
classification: {
type: String,
required: true,
},
probability: {
type: Number,
required: true,
},
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
}
}, {
timestamps: true,
});
export default mongoose.model('Emotion', EmotionSchema);
And some data like this:
[
{
"_id": "61144a393c532f066725bd24",
"classification": "Feliz",
"probability": 0.98,
"user": "60eecfeba0810013e750cdbc",
"createdAt": "2021-08-11T22:07:53.331Z",
"updatedAt": "2021-08-11T22:07:53.331Z",
"__v": 0
},
{
"_id": "61144a46d30bd006fa2be702",
"classification": "Feliz",
"probability": 0.98,
"user": "60eecfeba0810013e750cdbc",
"createdAt": "2021-08-11T22:08:06.618Z",
"updatedAt": "2021-08-11T22:08:06.618Z",
"__v": 0
},
{
"_id": "611541dd62a7f214afab3ceb",
"classification": "Triste",
"probability": 0.9,
"user": "60eecfeba0810013e750cdbc",
"createdAt": "2021-08-12T15:44:29.150Z",
"updatedAt": "2021-08-12T15:44:29.150Z",
"__v": 0
},
{
"_id": "611541f762a7f214afab3cf5",
"classification": "Raiva",
"probability": 0.86,
"user": "60eecfeba0810013e750cdbc",
"createdAt": "2021-08-12T15:44:55.909Z",
"updatedAt": "2021-08-12T15:44:55.909Z",
"__v": 0
},
{
"_id": "6115420362a7f214afab3cf7",
"classification": "Neutro",
"probability": 0.99,
"user": "60eecfeba0810013e750cdbc",
"createdAt": "2021-08-12T15:45:07.297Z",
"updatedAt": "2021-08-12T15:45:07.297Z",
"__v": 0
},
{
"_id": "6115420462a7f214afab3cf9",
"classification": "Neutro",
"probability": 0.99,
"user": "60eecfeba0810013e750cdbc",
"createdAt": "2021-08-12T15:45:08.002Z",
"updatedAt": "2021-08-12T15:45:08.002Z",
"__v": 0
},
{
"_id": "611543d252be9a187c380e5d",
"classification": "Feliz",
"probability": 0.91,
"user": "60eecfeba0810013e750cdbc",
"createdAt": "2021-08-12T15:52:50.599Z",
"updatedAt": "2021-08-12T15:52:50.599Z",
"__v": 0
}
]
What I want is:
First group each of these records by day.
Afterwards, count the values ​​by classification, but separating these classifications.
Something like that:
[
{
"_id": "12/08/2021",
"feliz": 1,
"triste": 1,
"raiva": 1,
"neutro": 2,
"surpreso": 0,
},
{
"_id": "11/08/2021",
"feliz": 2,
"triste": 0,
"raiva": 0,
"neutro": 0,
"surpreso": 0,
}
]
I did something like that, but it's only working for a value, eg "Feliz".
In code:
Emotion.aggregate([
{ $match:
{
user: user._id,
classification: "Feliz"
}
},
{ $group: {
_id : { $dateToString: { format: "%d/%m/%Y", date: "$createdAt" } },
feliz: { $sum: 1 }
}},
], function(err, results) {
if (err) throw err;
return res.json(results);
})
And it returns:
[
{
"_id": "12/08/2021",
"feliz": 1
},
{
"_id": "11/08/2021",
"feliz": 4
}
]
One more question:
From the Client-side, I always get values ​​for "classification" like:
"Feliz", "Triste", "Surpreso", "Raiva", "Neutro".
So is it better to add an enum to my schema "Emotion"?
(Sorry for my English, i hope you understand).
$group by createdAt date and classification, count sum
$group by createdAt only and construct the array of classification and count in key-value pair
$arrayToObject to convert above key-value pair array of object to an object format
Emotion.aggregate([
{
$match: {
user: user._id,
classification: "Feliz"
}
},
{
$group: {
_id: {
createdAt: {
$dateToString: {
format: "%d/%m/%Y",
date: "$createdAt"
}
},
classification: "$classification"
},
count: { $sum: 1 }
}
},
{
$group: {
_id: "$_id.createdAt",
classifications: {
$push: {
k: "$_id.classification",
v: "$count"
}
}
}
},
{
$addFields: {
classifications: {
$arrayToObject: "$classifications"
}
}
}
],
function(err, results) {
if (err) throw err;
return res.json(results);
})
Playground
Note: this will not return classification when count is 0! You need to do this after query in js.
One more question: From the Client-side, I always get values ​​for "classification" like: "Feliz", "Triste", "Surpreso", "Raiva", "Neutro". So is it better to add an enum to my schema "Emotion"?
It is up to your project requirement, you can set these values in enum to restrict the input.

Use Mongoose aggregate to fetch object inside of an array

Here is my MongoDB schema:
{
"_id": "603f23ff6c1d862e5ced9e35",
"reviews": [
{
"like": 0,
"dislike": 0,
"_id": "603f23ff6c1d862e5ced9e34",
"userID": "5fd864abb53d452e0cbb5ef0",
"comment": "Not so good",
},
{
"like": 0,
"dislike": 0,
"_id": "603f242a6c1d862e5ced9e36",
"userID": "5fd864abb53d452e0cbb5ef0",
"comment": "Not so good",
}
]
productID:"hdy6nch99dndn"
}
I want to use aggregate to get the review object of a particular id. I tried but not with any success.
Here is my code:
ProductReview.aggregate([
{ $match: { productID: productID } }
])
$match
$unwind
db.collection.aggregate([
{
$match: {
productID: 1
}
},
{
$unwind: "$reviews"
},
{
$match: {
"reviews._id": 2
}
}
])
Output:
[
{
"_id": ObjectId("5a934e000102030405000000"),
"productID": 1,
"reviews": {
"_id": 2,
"comment": "second comment",
"dislikes": [
{
"userID": 3
},
{
"userID": 4
}
],
"likes": [
{
"userID": 1
},
{
"userID": 2
}
]
}
}
]
Mongo Playground: https://mongoplayground.net/p/qfWS1rCuMfc

Issue with to get data from MongoDB aggregate

I want data from places where userid is equal to the body.user._id
PLACE DATA
{
"_id": "5e8ddd0f7f5b174290bbefc8",
"type": 0,
"location": [
24.8757396,
67.3464698
],
"title": "E 22, Steel Town Karachi, Karachi City, Sindh, Pakistan",
"googlePlaceId": "ChIJlbvA8BIzsz4Rlh7w_fKfwus",
"createdDate": "2020-04-08T14:17:51.869Z",
"__v": 0,
},
{
"_id": "5e8de4204396310017564a2b",
"type": 0,
"location": [
24.910688,
67.0310973
],
"title": "Nazimabad, Karachi, Pakistan",
"googlePlaceId": "ChIJzZudRr0_sz4R81KZ48Ylk3Q",
"createdDate": "2020-04-08T14:48:00.557Z",
"__v": 0,
},
{
"_id": "5e8de4364396310017564a2d",
"type": 0,
"location": [
24.9180271,
67.0970916
],
"title": "Gulshan-e-Iqbal, Karachi, Pakistan",
"googlePlaceId": "ChIJsda_CLg4sz4RIghXwgIae5k",
"createdDate": "2020-04-08T14:48:22.979Z",
"__v": 0,
},
{
"_id": "5e8dea79894854524cc554e0",
"type": 0,
"location": [
24.9343322,
67.177173
],
"title": "Malir Cantt Check Post No 6, Malir Link to Super Highway, Karachi, Pakistan",
"googlePlaceId": "ChIJJ7BbsyQ4sz4RvpkV9Ig_aU4",
"createdDate": "2020-04-08T15:15:05.360Z",
"__v": 0,
}**
Visited Places DATA
{
"_id":"5e90998f8bc84d0017a6d2f3",
"visitingNo":"0",
"_userId":"5e8f3ef5434f5800170c7169"
"_placeId":"5e908fdb8bc84d0017a6d2e8"
"createdDate":"2020-04-10T16:06:39.231+00:00"
"__v":"0"
},
{
"_id":"5e90998f8bc84d0017a6d2f3",
"visitingNo":"0",
"_userId":"5e8f3ef5434f5800170c7169"
"_placeId":"5e908fdb8bc84d0017a6d2e8"
"createdDate":"2020-04-10T16:06:39.231+00:00"
"__v":"0"
},
{
"_id":"5e90998f8bc84d0017a6d2f3",
"visitingNo":"0",
"_userId":"5e8f3ef5434f5800170c7169"
"_placeId":"5e908fdb8bc84d0017a6d2e8"
"createdDate":"2020-04-10T16:06:39.231+00:00"
"__v":"0"
},
MY CODE
const palace = placeData.aggregate([
{
$lookup:{
from: `${visitplaceData}`,
// localField: "_id",
// foreignField: "_placeId",
let : {
"placeId" : "$_id"
},
pipeline : [
{ $sort: { visitingNo : -1 } },
{
$match : {
$expr : {
$and : [
{$eq: [ "$_placeId", "$$placeId" ]},
{"_userId": body.user._id}
]
}
}
},
],
as: "places"
}
}
])

Resources