remove duplicate documents in mongodb aggregate - node.js

I have offers collection that look like below, each document has offer id and place.
[
{
"_id": "p1-o1",
"place": "1"
},
{
"_id": "p1-o2",
"place": "1"
},
{
"_id": "p1-on",
"place": "1"
},
{
"_id": "p2-p1",
"place": "2"
},
{
"_id": "p2-o2",
"place": "2"
},
{
"_id": "p2-on",
"place": "2"
},
....
{
"_id": "pn-0n",
"place": "n"
}
]
I need to aggregate and result a stream of paginated documents like below, where each page has a single offer from a single place,
for first page:
[
{
"_id": "p1-o1",
"place": "1"
},
{
"_id": "p2-o1",
"place": "2"
},
.....
{
"_id": "pn-o1",
"place": "n"
}
]
for second page
[
{
"_id": "p1-o2",
"place": "1"
},
{
"_id": "p2-o2",
"place": "2"
},
.....
{
"_id": "pn-on",
"place": "n"
}
]
where "p1-o1" is the first offer in the first place and so on ...

Related

How to set up aggregation pipeline for specific use case in MongoDB

`I have two collections in MongoDB. One is users and the other is companies. I need to be able to populate the users.endpoints with the endpoints from companies that match ObjectID's which are in the user.endPoints property. It is a bit hard for me to wrap my head around considering there are two steps.
This is the companies collection.
{
"_id": {
"$oid": "63ed39162bfc2cf8065b76cf"
{
"_id": {
"$oid": "63ed39162bfc2cf8065b76cf"
},
"companyName": "Sowegatel",
"amount": 0,
"signalwireSid": "id",
"numbers": [
{
"number": "+12068133580",
"_id": {
"$oid": "63ed39c72bfc2cf8065b76f0"
},
"createdAt": {
"$date": {
"$numberLong": "1676491207931"
}
},
"updatedAt": {
"$date": {
"$numberLong": "1676491207931"
}
}
}
],
"endPoints": [
{
"userName": "4009",
"_id": "fb1d0ef9-c713-400e-a3c9-cbc6823aaf57"
},
{
"userName": "4019",
"_id": "506e710d-14a6-4345-bc89-8488af4cabe4"
},
{
"userName": "4020",
"_id": "c80bd1ab-ca8d-4649-9d35-56d64ef8fab5",
"type": "sip_endpoint"
}
],
"__v": 6
} },
"companyName": "Sowegatel",
"amount": 0,
"signalwireSid": "id",
"numbers": [
{
"number": "+12068133580",
"_id": {
"$oid": "63ed39c72bfc2cf8065b76f0"
},
"createdAt": {
"$date": {
"$numberLong": "1676491207931"
}
},
"updatedAt": {
"$date": {
"$numberLong": "1676491207931"
}
}
}
],
"endPoints": [
{
"userName": "4009",
"_id": "fb1d0ef9-c713-400e-a3c9-cbc6823aaf57"
},
{
"userName": "4019",
"_id": "506e710d-14a6-4345-bc89-8488af4cabe4"
},
{
"userName": "4020",
"_id": "c80bd1ab-ca8d-4649-9d35-56d64ef8fab5",
"type": "sip_endpoint"
}
],
"__v": 6
}
This is the users collection.
{
"_id": {
"$oid": "63ed39162bfc2cf8065b76d2"
},
"firstName": "mark",
"lastName": "thomas",
"email": "mt#st.com",
"password": "",
"companyId": {
"$oid": "63ed39162bfc2cf8065b76cf"
},
"active": true,
"role": "companyAdmin",
"tokens": [],
"__v": 2,
"endpoints": [
// I need to populate to endpoints here!!!! //
"c80bd1ab-ca8d-4649-9d35-56d64ef8fab5"
]
}
I can do a single step aggregation, but this is a little complicated for me.`

I need to push into nested array in node mongoose

I used node mongoose.
I need to update this array push new item into Breackfast(mealList.foodList.breackfast || any),
I want to add new foodlist by time can you please give me suggestion for how to do,
{
"_id": "5fe43eb44cd6820963c98c32",
"name": "Monday Diet",
"userID": "5f225d7458b48d0fe897662e",
"day": "Monday",
"type": "private",
"mealList": [
{
"_id": "5fe43eb44cd6820963c98c33",
"time": "Breakfast",
"foodList": [
{
"_id": "5fe43eb44cd6820963c98c34",
"foodName": "Eggs",
"Qty": "2",
"calories": "calories",
"category": "category"
}
]
},
{
"_id": "5fe43eb44cd6820963c98c36",
"time": "Lunch",
"foodList": [
{
"_id": "5fe43eb44cd6820963c98c37",
"foodName": "food1",
"Qty": "100g"
},
]
}
],
"createdAt": "2020-12-24T07:09:40.141Z",
"updatedAt": "2020-12-24T07:09:40.141Z",
"__v": 0
}
I tried:
Diet.updateOne(
{ "Diet.mealList._id": req.body.mealId },
// { $push: { "Diet.0.mealList.$.foodList": req.body.foodList } },
{ $push: { foodList: req.body.foodList } }
)
Few Fixes:
convert your string _id to object type using mongoose.Types.ObjectId
remove Diet from first and push object in foodList
Diet.updateOne({
"mealList._id": mongoose.Types.ObjectId(req.body.mealId)
},
{
$push: {
"mealList.$.foodList": req.body.foodList
}
})
Playground

Multiple groups and project using mongoose

I'm trying display aggregated data by a time range in Mongoose. My Data is like:
{company: "1" createdTime:"2017-01-01"}
{company: "1" createdTime:"2017-01-01"}
{company: "1" createdTime:"2017-01-02"}
{company: "2" createdTime:"2017-01-02"}
{company: "2" createdTime:"2017-01-03"}
{company: "3" createdTime:"2017-01-03"}
{company: "3" createdTime:"2017-01-03"}
I have created a query like:
{
"aggregate": [{
"$project": {
"frequency": {
"$dateToString": {
"format": "%Y-%m-%d",
"date": "$createdTime"
}
}
}
}, {
"$group": {
"_id": {
"date": "$frequency"
},
"count": {
"$sum": 1
}
}
}
]
}
and returns:
[
{
"_id": {
"date": "2017-01-01"
},
"count": 2
},
{
"_id": {
"date": "2017-01-02"
},
"count": 2
},
{
"_id": {
"date": "2017-01-03"
},
"count": 3
}
]
Which gives me the count for the overall occurrences for that particular date, which is fine.
I'm wanting to further break that down to give me the sum of occurrences per company for that date which should look something like this:
[
{
"_id": {
"date": "2017-01-01",
"companies": [{
"company": 1,
"count": 2
}]
},
"count": 2
},
{
"_id": {
"date": "2017-01-02",
"companies": [{
"company": 1,
"count": 1
},{
"company": 2,
"count": 1
}]
},
"count": 2
},
{
"_id": {
"date": "2017-01-03",
,
"companies": [{
"company": 2,
"count": 1
},{
"company": 3,
"count": 2
}]]
},
"count": 3
}
]
I've tried all sort of combinations but always get errors when i put in a second group and i can't work out how to do it?
EDIT
I wasn't able to use examples from the comments or they didn't work for my use case however, combining this information i came up with this:
{
"aggregate": [{
"$group": {
"_id": {
"company": "$company",
"date": {
"$dayOfMonth": "$createdTime"
},
"month": {
"$month": "$createdTime"
},
"year": {
"$year": "$createdTime"
}
},
"count": {
"$sum": 1
}
}
}, {
"$group": {
"_id": "$_id.company",
"events": {
"$push": {
"date": "$_id.date",
"month": "$_id.month",
"year": "$_id.year",
"count": "$count"
}
},
"totalEvents": {
"$sum": "$count"
}
}
}
]
}
which renders some results like:
[
{
"_id": "1",
"dateCount": [
{
"date": 3,
"month": 12,
"year": 2017,
"count": 40
},
{
"date": 10,
"month": 12,
"year": 2017,
"count": 8
}
]
}
]
Ideally the date would be yyyy-mm-dd but using the full date in the query would include the time also resulting in an entry for each time not date. I guess this will do for now, i can easily create a date from this albeit it's a little more cumbersome but it'll do until anything better comes along.
Edit 2
[{
"_id": ObjectId("5a38a03b33ccd28fb87f6dc9"),
"createdBy": ObjectId("5a2e203fa567425b2cb411fc"),
"appId": ObjectId("5a2e203fa567425b2cb411fb"),
"eventName": "event",
"userName": "person",
"userEmail": "company__29",
"organisation": "company",
"module": "module",
"createdTime": ISODate("2017-12-02T17:07:25.000Z")
"__v": 0
}
]
Query:
{
"aggregate": [{
"$project": {
"frequency": {
"$dateToString": {
"format": "%U",
"date": "$createdTime"
}
}
}
}, {
"$group": {
"_id": {
"frequency": "$frequency",
"organisation": "$organisation"
},
"count": {
"$sum": 1
}
}
}, {
"$group": {
"_id": {
"date": "$_id.frequency"
},
"count": {
"$sum": 1
},
"companies": {
"$push": {
"organisation": "$organisation",
"count": "$count"
}
}
}
}
]
}

Multiple group using Mongoose

I'm wanting to get the sum of all events for each company. Here is my data:
{company: "1" event:"a"}
{company: "1" event:"b"}
{company: "1" event:"c"}
{company: "2" event:"b"}
{company: "2" event:"b"}
{company: "3" event:"c"}
{company: "3" event:"c"}
I currently have this to aggregate the date for events but I'm struggling to further group them by company:
{
"aggregate": [
{
"$group": {
"_id": "$event",
"count": {"$sum": 1}
}
},
{"$sort": {"_id": 1}}
]
}
Which renders these results:
[
{
"_id": "a",
"count": 1
},
{
"_id": "b",
"count": 3
},
{
"_id": "c",
"count": 2
}]
How can I further group the event counts by company to produce something along the lines of:
[{
"_id": {
"company" :"1",
"events": [
{
"event": "a",
"count": 1
},
{
"event": "b",
"count": 1
},
{
"event": "c",
"count": 1
},
]
}
},
{
"_id": {
"company" :"2",
"events": [
{
"event": "b",
"count": 2
}
]
}
},
{
"_id": {
"company" :"3",
"events": [
{
"event": "c",
"count": 2
}
]
}
}
]
I've tried all sorts of further groups in the query but can't produce the data I'm after. There is also one caveat: I'm unable to process anything server side or change the schema, so therefore I am only enable to pass in a query which I hope can be done.
db.collection.aggregate([
{
$group:{
_id:{company:"$company",event:"$event"},
count:{$sum:1}
}
},
{
$group:{
_id:"$_id.company",
events:{$push:{event:"$_id.event",count:"$count"}}
}
}
])
And if u need exact same output you mentioned then add $project stage like
$project:{_id:{company:"$_id",events:"$events"}}

Aggregation with Mongodb using mongoose

Hey im trying some aggregation on mongodb using moongose:
I got this data:
[
{
"school": "1",
"preferences": [
{
"person": "X",
"color": "A"
},
{
"person": "X",
"color": "B"
},
{
"person": "Y",
"color": "A"
}
]
},
{
"school": "2",
"preferences": [
{
"person": "Z",
"color": "A"
},
{
"person": "Y",
"color": "C"
}
]
}
]
I think the data explaisn it self, What i want to get as result is,
when i query for the school that matches '1'. i would like to get this result:
[
{
"_id": "X",
"colors": [
"A",
"B"
]
},
{
"_id": "Y",
"colors": ["A"]
}
]
I used aggregation before, but i cant figure to get this result.
Check this aggregation query :
db.collectionName.aggregate({
"$match": {
"school": "1"
}
}, {
"$unwind": "$preferences"
}, {
"$group": {
"_id": "$preferences.person",
"colors": {
"$addToSet": "$preferences.color" // $addToSet used here only to add distinct color
}
}
})
Edit If you want count the number of color then used group with sum as below :
db.collectionName.aggregate({
"$match": {
"school": "1"
}
}, {
"$unwind": "$preferences"
}, {
"$group": {
"_id": "$preferences.color",
"appears": {
"$sum": 1
}
}
})
EDIT
As per your new requirement you should do following aggregation:
db.collectionName.aggregate({
"$unwind": "$preferences"
},
{
"$group": {
"_id": {
"person": "$preferences.person",
"color": "$preferences.color"
},
"count": {
"$sum": 1
}
}
},
{
"$group": {
"_id": "$_id.person",
"colors": {
"$push": {
"color": "$_id.color",
"count": "$count"
}
}
}
},
{
"$project": {
"_id": 0,
"person": "$_id",
"colors": 1
}
}).pretty()

Resources