I have this documents of movie showing time and date:
`{
"_id": ObjectId("5628668c3e82c49245b7acdc"),
"ticketID": ObjectId("5606d36b5fbd7d76028b4b08"),
"uid": "50000",
"day": "Friday",
"date": "2015-10-23 21:05:00",
"adult": NumberLong(550),
"student": NumberLong(550),
"children": NumberLong(250),
"limit": NumberLong(20),
"sold": NumberLong(0)
},{
"_id": ObjectId("562866013e82c49045b7acdc"),
"ticketID": ObjectId("5606d36b5fbd7d76028b4b08"),
"uid": "50000",
"day": "Friday",
"date": "2015-10-23 19:30:00",
"adult": NumberLong(1050),
"student": NumberLong(800),
"children": NumberLong(550),
"limit": NumberLong(20),
"sold": NumberLong(0)
},{
"_id": ObjectId("562865013e82c49845b7acda"),
"ticketID": ObjectId("5606d36b5fbd7d76028b4b08"),
"uid": "50000",
"day": "Friday",
"date": "2015-10-23 18:45:00",
"adult": NumberLong(1500),
"student": NumberLong(750),
"children": NumberLong(750),
"limit": NumberLong(20),
"sold": NumberLong(0)
}
`
I want to group the final result by "day" where "ticketID" matches, "date" as an object and adding "adult","student","children","limit" to an array
-- UPDATE --
I would like the returned structure to follow:
{
"_id": "ticketID",
"day": "Friday",
"items": [
{
"date": date,
"time": time"adult": price,
"children": price,
"student": price,
"limit": value
},
{
"date": date,
"time": time"adult": price,
"children": price,
"student": price,
"limit": value
},
{
"date": date,
"time": time"adult": price,
"children": price,
"student": price,
"limit": value
}
]
}
Run the following aggregation pipeline which uses the $group operator to group your documents by the specified fields, add the items array by using the accumulator operator $push that returns an array of expression values for each group. The $project pipeline operator then reshapes the documents by amending the fields to get the final desired structure:
var pipeline = [
{
"$group": {
"_id": {
"ticketID": "$ticketID",
"day": "$day"
},
"items": {
"$push": {
"date": "$date",
"time": "$time",
"adult": "$adult",
"children": "$children",
"student": "$student",
"limit": "$limit"
}
}
}
},
{
"$project": {
"_id": "$_id.ticketID",
"day": "$_id.day",
"items": 1
}
}
];
db.collection.aggregate(pipeline);
Related
I'm trying to learn the advanced mongodb+mongoose function, so this is the result of my orders, and what I'm trying to do here is to compute the total amounts related to the sellerId
So in this one, I have two documents, the document 1 have an amount of 99 and and the other one is 11
so I need to get the sum of two. I've been searching and found the aggregate, but I can't figure out how I can combine the two documents.
[
{
"_id": "6360d1d0bd860240e2589564",
"userId": "6360cf687e186ebe29ab2a29",
"products": [
{
"productId": "6360cdd166480badb8c1e05b",
"quantity": 1,
"sellerId": "6360c6ed05e1e99034b5f7eb",
"_id": "6360d1d0bd860240e2589565"
}
],
"amount": 99,
"location": "asdsad",
"time": "asdsad",
"status": "pending",
"tax": 0.99,
},
{
"_id": "6360d7978044f3048e59bf34",
"userId": "6360d50dbd860240e258c585",
"products": [
{
"productId": "6360d7528044f3048e59bb6c",
"quantity": 1,
"sellerId": "6360d4d5bd860240e258c582",
"_id": "6360d7978044f3048e59bf35"
},
{
"productId": "6360d7868044f3048e59bd8c",
"quantity": 1,
"sellerId": "6360d4d5bd860240e258c582",
"_id": "6360d7978044f3048e59bf36"
}
],
"amount": 11,
"location": "Gym",
"time": "8:00 AM",
"status": "pending",
"tax": 0.11,
}
]
This might helps.
db.collection.aggregate([
{
$group: {
_id: null,
count: {
$sum: "$amount"
}
}
}
])
I would like to group my data by different conditions but I do not understand how I could do it.
My data:
[
{"Id": "1", "Info": "X" "Date": 10/1},
{"Id": "2", "Info": "X" "Date": 13/2},
{"Id": "3", "Info": "Y" "Date": 13/2},
{"Id": "4", "Info": "X" "Date": 10/1},
{"Id": "5", "Info": "X" "Date": 10/1},
{"Id": "6", "Info": "X" "Date": 13/2},
]
And I would like to group them by Info and by Date, a result similar to this one:
[
{"Id": ["1","4","5"], "Info": "X" "Date": 10/1},
]
[
{"Id": ["2", "6"], "Info": "X" "Date": 13/2},
]
[
{"Id": ["3"], "Info": "Y" "Date": 13/2},
]
I am using aggregate and I just know how to use aggregate to group them just by one condition, I donĀ“t know how to continue and how to use date in $group, this is what I have and how I group it by info:
.aggregate([
{ "$match" : { "$or": [{"status": "downloading"}, {"status": "calculating"}]}},
{ "$project": {"Id": 1, "Date": 1, "info": 1}},
{ "$group" : { "_id" : "$Info", "Id" : { "$addToSet" : "$Id"}}},
{ "$project": {"_id": 0, "Info": "$_id", "Id": 1 }}
You can give the _id in the $group stage multiple fields, like so:
db.collection.aggregate([
{
"$project": {
"Id": 1,
"Date": 1,
"info": 1
}
},
{
"$group": {
"_id": {
date: "$Date",
info: "$info"
},
"Id": {
"$addToSet": "$Id"
}
}
},
{
"$project": {
"_id": 0,
"Info": "$_id.info",
"Date": "$_id.date",
"Id": 1
}
}
])
Mongo Playground
I have a collection as follow,
[
{
"_id": "movie:1",
"title": "Vertigo",
"year": 1958,
"genre": "drama",
"country": "DE"
},
{
"_id": "movie:2",
"title": "Alien",
"year": 1979,
"genre": "Science-fiction",
"country": "USA"
},
{
"_id": "movie:3",
"title": "Sacrifice",
"year": 1986,
"genre": "drama",
"summary": null,
"country": "FR"
}
]
I have the following query,
db.moviesEmbedded.aggregate([
{"$group" : {_id:{country:"$country", genre: "$genre", movie: "$title"}, movies:{$sum:1} } } ]
But it doesn't give me the correct output. Can someone please help me with this?
You have to $match first to filter the desired values. So you need this query:
db.collection.aggregate({
"$match": {
"genre": "drama"
}
},
{
"$group": {
"_id": "$country",
"total": {
"$sum": 1
}
}
})
Example here.
Note that you can output the total or multiple values in this way if you prefer:
db.collection.aggregate({
"$match": {
"genre": "drama"
}
},
{
"$group": {
"_id": "$country",
"movie": {
"$push": {
"title": "$title",
"year": "$year"
}
}
}
})
Example here
I would like to independently group the results of an or clause, including overlap. The data set is rather large so running 2 queries sequentially will result in an undesirable wait time. I am hoping I can somehow project which clause returned the corresponding data. Given this data set:
[
{
"_id": 1,
"item": "abc",
"name": "Michael",
"price": NumberDecimal("10"),
"quantity": NumberInt("2"),
"date": ISODate("2014-03-01T08:00:00Z")
},
{
"_id": 2,
"item": "jkl",
"name": "Toby",
"price": NumberDecimal("20"),
"quantity": NumberInt("1"),
"date": ISODate("2014-03-01T09:00:00Z")
},
{
"_id": 3,
"item": "xyz",
"name": "Keith",
"price": NumberDecimal("5"),
"quantity": NumberInt("10"),
"date": ISODate("2014-03-15T09:00:00Z")
},
{
"_id": 4,
"item": "abc",
"name": "Dwight",
"price": NumberDecimal("5"),
"quantity": NumberInt("20"),
"date": ISODate("2014-04-04T11:21:39.736Z")
},
{
"_id": 5,
"item": "abc",
"name": "Ryan",
"price": NumberDecimal("10"),
"quantity": NumberInt("10"),
"date": ISODate("2014-04-04T21:23:13.331Z")
},
{
"_id": 6,
"item": "def",
"name": "Jim",
"price": NumberDecimal("7.5"),
"quantity": NumberInt("5"),
"date": ISODate("2015-06-04T05:08:13Z")
},
{
"_id": 7,
"item": "abc",
"name": "Keith",
"price": NumberDecimal("7.5"),
"quantity": NumberInt("10"),
"date": ISODate("2015-09-10T08:43:00Z")
},
{
"_id": 8,
"item": "abc",
"name": "Michael",
"price": NumberDecimal("10"),
"quantity": NumberInt("5"),
"date": ISODate("2016-02-06T20:20:13Z")
},
]
I would like to receive this result:
[{
"_id": {
"name": "Keith"
},
"count": 2
},
{
"_id": {
"item": "abc",
},
"count": 5
}]
Here is what I have tried so far:
db.collection.aggregate([
{
$match: {
$or: [
{
item: "abc"
},
{
name: "Keith"
}
]
}
},
{
$group: {
_id: {
item: "$item",
name: "$name"
},
count: {
$sum: 1
}
}
}
])
You can use $facet to get multiple aggregation pipelines into the same stage in this way:
Using $facet there are two "outputs" one group by name and other by item.
In each one there are multiple stages:
First $match to process only documents you want.
Then $group with _id name or item, and $count to get the total.
db.collection.aggregate([
{
"$facet": {
"groupByName": [
{
"$match": {"name": "Keith"}
},
{
"$group": {"_id": "$name","count": {"$sum": 1}}
}
],
"groupByItem": [
{
"$match": {"item": "abc"}
},
{
"$group": {"_id": "$item","count": {"$sum": 1}}
}
]
}
}
])
Example here
The output is:
{
"groupByItem": [
{
"_id": "abc",
"count": 5
}
],
"groupByName": [
{
"_id": "Keith",
"count": 2
}
]
}
Here it is:
mongos> db.n.aggregate([ { $facet:{ names:[ {$match:{name:"Keith"}} , {$group:{_id:{name:"$name"}, count:{$sum:1}}} ] , items:[ {$match:{item:"abc"}},{ $group:{_id:{item:"$item"}, count:{$sum:1}} } ] } } , {$project:{ "namesANDitems":{$concatArrays:[ "$names","$items" ]} }} ,{$unwind:"$namesANDitems"} ,{$replaceRoot:{newRoot:"$namesANDitems"} } ]).pretty()
{ "_id" : { "name" : "Keith" }, "count" : 2 }
{ "_id" : { "item" : "abc" }, "count" : 5 }
mongos>
explained:
You create two pipes via $facet
Match in every facet pipe what you need to group pipe1=names , pipe2=items
Join the arrays from the two pipes in single array named "namesANDitems"
Convert the array to object with $unwind
Remove the temporary object name namesANDitems so you have only the two objects as requested
I am trying to delete an object within an array. But that array is nested within two objects. How do I do this?
For example: let's say I want to delete the transaction with
_id: 58c3154a19f82c0ddc53f0de
How would I do this??
{
"_id": {
"$oid": "58bad6cf93ab9703da331e25"
},
"username": "david.lam#transfast.com",
"password": "sha1$fc05ad7d$1$1cc86a287642516f947fda520ae8ddd42e983e23",
"firstName": "David",
"lastName": "David",
"transactions": {
"2017": {
"3": [
{
"where": "Duane Reade",
"what": "asdf",
"category": 6,
"amount": "34",
"_id": {
"$oid": "58c300ef1602f90c7166cbfb"
},
"date": {
"day": 10,
"month": 3,
"year": 2017
}
},
{
"where": "Amazon",
"what": "asdf",
"category": 2,
"amount": "100",
"_id": {
"$oid": "58c3154a19f82c0ddc53f0de"
},
"date": {
"day": 10,
"month": 3,
"year": 2017
}
}
]
}
}
}
To do so you need to use the $pull operator. Address array elements with the dot notation. The following query does the job:
db.user1.update({},
{$pull: {'transactions.2017.3': {_id: ObjectId("58c3154a19f82c0ddc53f0de")}}
});