ISODate in MongoDB query with double quotes - mongodb

I'm trying to make a MongoDB query, here's how I'm trying to do, part of my query:
db.admin_25c6b5.aggregate(
[
{ "$match" : { "attr" : "temperature", "ts" : {"$gte" : ISODate("2015-01-01"), "$lt" : ISODate("2025-01-01") } } },
{ "$sort" : { "ts" : 1 } },
{ "$project" : { "value" : 1, "_id" : 0 } }
])
When I tried this on Robo 3T it worked, but not on Grafana, it gave me the message Unexpected token I in JSON at position 63, the ISODate didn't work.
Then, I tried to add quotes:
db.admin_25c6b5.aggregate(
[
{ "$match" : { "attr" : "temperature", "ts" : {"$gte" : "ISODate("2015-01-01")", "$lt" : "ISODate("2025-01-01")" } } },
{ "$sort" : { "ts" : 1 } },
{ "$project" : { "value" : 1, "_id" : 0 } }
])
The new error message is: Unexpected number in JSON at position 73
I tried using this, but it didn't work:
db.admin_25c6b5.aggregate(
[
{ "$match" : { "attr" : "temperature", "ts" : {"$gte" : "ISODate(\"2015-01-01\")", "$lt" : "ISODate(\"2025-01-01\")" } } },
{ "$sort" : { "ts" : 1 } },
{ "$project" : { "value" : 1, "_id" : 0 } }
])
The new error message is Unexpected end of JSON input
I think the problem is that I am trying to use double quotes inside double quotes, do you have any idea to solve this?

Related

Mongo aggregation: Return count of distinct values from Key Value object

I'm really hoping someone can help me here, I'm going nuts with this problem :-d
So I have multiple documents (+100,000) which looks like this:
"_id" : ObjectId("60e5ae42fcc92f14c3a41208"),
"userId" : "xxxx",
"projectCreator" : {
"userId" : "xxx|xxxx"
},
"hashTags" : [
"Spring",
"Java"
],
"projectCategories" : {
"60d76ef0597444095b8ab4b2" : "Backend",
"60d76ef0597444095b8ab232" : "Infrastructure"
},
"createdDate" : ISODate("2021-07-07T13:38:10.655Z"),
"updatedAt" : ISODate("2021-07-08T11:48:36.200Z"),
"_class" : "xxxx.model.project.Project"
}
I would like to have a query which does the following:
Extract all the unique projectCategories value (the string value not the id) from all documents in a collection
Count the number of occurrences of each of the values
So the result would look like this:
Backend : NUMBER OF OCCURRENCES
FrontEnd : NUMBER OF OCCURRENCES
Infrastructure: NUMBER OF OCCURRENCES
I "think" I need to do a aggregation and the group the values and then do a count but to be very honest I cant understand this.
I've tried this query:
db.projects.aggregate([ { $match: { isDeleted : {$ne: true} }},{ $match: { projectCategories: { $exists:true, $ne: null }} },{ $project: { result: { $objectToArray: "$projectCategories" } } },{ $unwind : "$result"}])
which will return this:
{ "_id" : ObjectId("60c313e2905d344c7dd117f1"), "result" : { "k" : "60d76f295974444b818ab4bc", "v" : "Apps" } }
{ "_id" : ObjectId("60c313e2905d344c7dd117f1"), "result" : { "k" : "60d76f1759744461468ab4b8", "v" : "Development Tools" } }
{ "_id" : ObjectId("60c313e2905d344c7dd117f1"), "result" : { "k" : "60d76eeb597444b9da8ab4b1", "v" : "Frontend" } }
{ "_id" : ObjectId("60cfb59f30b2647610a6c931"), "result" : { "k" : "60d76eeb597444b9da8ab4b1", "v" : "Frontend" } }
{ "_id" : ObjectId("60cfb59f30b2647610a6c931"), "result" : { "k" : "60d76ef659744422d68ab4b3", "v" : "Fullstack" } }
{ "_id" : ObjectId("60cfb69730b2647610a6c932"), "result" : { "k" : "60d76f295974444b818ab4bc", "v" : "Apps" } }
{ "_id" : ObjectId("60df83e84d8b6341d49cff4e"), "result" : { "k" : "60d76ef0597444095b8ab4b2", "v" : "Backend" } }
{ "_id" : ObjectId("60df83e84d8b6341d49cff4e"), "result" : { "k" : "60d76eeb597444b9da8ab4b1", "v" : "Frontend" } }
{ "_id" : ObjectId("60df83e84d8b6341d49cff4e"), "result" : { "k" : "60d76ef659744422d68ab4b3", "v" : "Fullstack" } }
{ "_id" : ObjectId("60e5ae42fcc92f14c3a41208"), "result" : { "k" : "60d76ef0597444095b8ab4b2", "v" : "Backend" } }
{ "_id" : ObjectId("60f0abf9f5c82b27af712ad7"), "result" : { "k" : "60d76f2559744477168ab4bb", "v" : "Games" } }
{ "_id" : ObjectId("60f0abf9f5c82b27af712ad7"), "result" : { "k" : "60d76ef659744422d68ab4b3", "v" : "Fullstack" } }
{ "_id" : ObjectId("60f68d2df9710f58c1e9c872"), "result" : { "k" : "60d76f295974444b818ab4bc", "v" : "Apps" } }
{ "_id" : ObjectId("60f68d2df9710f58c1e9c872"), "result" : { "k" : "60d76f0e5974448f038ab4b7", "v" : "Open Source" } }
{ "_id" : ObjectId("60f68d2df9710f58c1e9c872"), "result" : { "k" : "60d76eeb597444b9da8ab4b1", "v" : "Frontend" } }
So where I'm stuck now is how do I unwind and get the output to be like:
Backend : NUMBER OF OCCURRENCES
FrontEnd : NUMBER OF OCCURRENCES
Infrastructure: NUMBER OF OCCURRENCES
Can anyone help me here please?
Thanks!
Update:
I've managed to get CLOSE with this query:
db.projects.aggregate([ { $match: { isDeleted : {$ne: true} }},{ $match: { projectCategories: { $exists:true, $ne: null }} },{ $project: { result: { $objectToArray: "$projectCategories" } } },{ $unwind : "$result"}, { $group: { _id: "$result.v", count: { $sum: 1 } } } ] )
However the output is like this now:
{ "_id" : "Development Tools", "count" : 1 }
{ "_id" : "Games", "count" : 1 }
{ "_id" : "Fullstack", "count" : 3 }
{ "_id" : "Open Source", "count" : 1 }
{ "_id" : "Frontend", "count" : 4 }
{ "_id" : "Apps", "count" : 3 }
{ "_id" : "Backend", "count" : 2 }
Is it possible to drop the _id?
You can group again to push the keys and values into an array, and then use $replaceRoot with $arrayToObject:
{$group:{
_id:null,
results:{$push: {k:"$_id", v:"$count"}}
}},
{$replaceRoot:{ newRoot: {$arrayToObject:"$results"}}}

Mongodb If then else, unwinding

I have documnet structure like below.
{
"_id" : ObjectId("5852c49ba35fe"),
"date" : "20100101",
"p9" : "PWR_FSA",
"p10" : "00278",
"p11" : "002",
"gs" : [
{
"tis" : [
{
"rr" : "00",
"ul" : [
{
"amnt" : 1.0,
"su" : "N"
}
]
}
],
"type" : "PQR"
}
],
"trig_id" : "255"
}
{
"_id" : ObjectId("59fdc49ba35fe"),
"date" : "20100101",
"p9" : "PWR_FSA",
"p10" : "00278",
"p11" : "002",
"gs" : [
{
"mis" : [
{
"rr" : "00",
"tl" : [
{
"amnt" : -1.5,
"su" : "N"
}
]
}
],
"type" : "ABC"
}
],
"trig_id" : "255"
}
Now i want to aggregare the amount on the basis of p9 so i have written below query.
I am gettiing an error at then : {{$unwind : "$gs.tis"},{$unwind : "$gs.tis.ul"}},
Where i am going wrong? Also Can i do unwinding in Then clause ?
db.TB.aggregate({$match :{$and :[{"trig_id" : "255"}]}},
{ $unwind : "$gs" },
{$project: {_id :1,
"amnt" :{
$concat : [ {
$cond : { if : {"gs.type" : {$eq : "PQR"}} ,
then : {{$unwind : "$gs.tis"},{$unwind : "$gs.tis.ul"}},
$cond : { if : {$match : {"gs.tis.ul.su": "N"}} , then : {$gs.tis.ul.amnt} , else: {""}}
else : "" }
}]}},
"total" : { $sum : 1 }
}},
{$group :{"_id": "$p9",
"amnt": {"$sum": "$amnt"}
}
})

Mongodb pull data from subarray

Hi I have below mongodb collection
{
"_id" : ObjectId("53ce993639203f573671d3f5"),
"user_id" : NumberLong(51),
"buses" : [
{
"slot_id" : NumberLong(50),
"status" : NumberLong(3),
"bus_id" : NumberLong(8)
},
{
"slot_id" : NumberLong(67),
"status" : NumberLong(3),
"bus_id" : NumberLong(12)
}
]
}
i want to pull sub array where bus_id=8.
Final result i want to be like this
{
"_id" : ObjectId("53ce993639203f573671d3f5"),
"user_id" : NumberLong(51),
"buses" : [
{
"slot_id" : NumberLong(67),
"status" : NumberLong(3),
"bus_id" : NumberLong(12)
}
]
}
When i tried with below query
db.collectionname.update({},{$pull: {buses: {bus_id:8}}},{multi: true})
I got below error in console,
Cannot apply $pull/$pullAll modifier to non-array
Can any one please suggest me how to achieve this,and also need php mongodb query also.
Thanks in Advance
Worked fine for me for your sample document:
> db.bus.findOne()
{
"_id" : ObjectId("53ce993639203f573671d3f5"),
"user_id" : NumberLong(51),
"buses" : [
{
"slot_id" : NumberLong(50),
"status" : NumberLong(3),
"bus_id" : NumberLong(8)
},
{
"slot_id" : NumberLong(67),
"status" : NumberLong(3),
"bus_id" : NumberLong(12)
}
]
}
> db.bus.update({}, { "$pull" : { "buses" : { "bus_id" : 8 } } }, { "multi" : true })
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.bus.findOne()
{
"_id" : ObjectId("53ce993639203f573671d3f5"),
"user_id" : NumberLong(51),
"buses" : [
{
"slot_id" : NumberLong(67),
"status" : NumberLong(3),
"bus_id" : NumberLong(12)
}
]
}
The cause of the problem is that some buses element is not an array. What does the query
> db.bus.find({ "buses.0" : { "$exists" : 0}, "buses" : { "$ne" : [] } })
return? This query finds documents where there is no 0th element of the array and the array is not empty, so it should return documents where buses is not an array.

Need to add a "generated value" to the results in MongoDB

I have a query
[ { "$match" : { "vm_id" : "218276"}},{ "$group" : { "_id" : { "$dayOfMonth" : "$ts"} , "public_tx_total" : { "$sum" : "$interface_public_tx_bytes"} , "public_rx_total" : { "$sum" : "$interface_public_rx_bytes"} , "private_tx_total" : { "$sum" : "$interface_private_tx_bytes"} , "private_rx_total" : { "$sum" : "$interface_private_rx_bytes"} , "count" : { "$sum" : 1}}},{ "$sort" : { "_id" : 1}} ]
where I want to add a key that takes $ts and pulls the year out of and add it to the results
year: {$year: "$ts"}
I 'm not sure where to place the snippet without causing an error.
You can do it by adding the following command into the group query.
"year" : {$first : { $year:"$ts"}}
Your query will look like :
[
{"$match":{"vm_id":"218276"}},
{"$group":{"_id":{"$dayOfMonth":"$ts"},
"year":{$first:{$year:"$ts"}},
"public_tx_total":{"$sum":"$interface_public_tx_bytes"},
"public_rx_total":{"$sum":"$interface_public_rx_bytes"},
"private_tx_total":{"$sum":"$interface_private_tx_bytes"},
"private_rx_total":{"$sum":"$interface_private_rx_bytes"},
"count":{"$sum":1}}},
{"$sort":{"_id":1}}
]

Do $sort works for sub array document

I have a collection which has a field of array kind. I want to sort on the basis of a field of sub-array but Mongo is not sorting the data.
My collection is:
{
"_id" : ObjectId("51f1fcc08188d3117c6da351"),
"cust_id" : "abc123",
"ord_date" : ISODate("2012-10-03T18:30:00Z"),
"status" : "A",
"price" : 25,
"items" : [{
"sku" : "ggg",
"qty" : 7,
"price" : 2.5
}, {
"sku" : "ppp",
"qty" : 5,
"price" : 2.5
}]
}
My Query is:
db.orders.aggregate([
{ "$unwind" : "$items"} ,
{ "$match" : { }} ,
{ "$group" : { "items" : { "$addToSet" : { "sku" : "$items.sku"}} , "_id" : { }}} ,
{ "$sort" : { "items.sku" : 1}} ,
{ "$project" : { "_id" : 0 , "items" : 1}}
])
Result is:
"result" : [
{
"items" : [
{
"sku" : "ppp"
},
{
"sku" : "ggg"
}
]
}
],
"ok" : 1
}
Whereas "sku":"ggg" should come first when it is ascending.
You weant to do the sort BEFORE you regroup:
db.orders.aggregate([
{ "$unwind" : "$items"} ,
{ "$sort" : { "items.sku" : 1}},
{ "$match" : { }} ,
{ "$group" : { "items" : { "$push" : { "sku" : "$items.sku"}} , "_id" : null}} ,
{ "$project" : { "_id" : 0 , "items" : 1}}
])