Cant group with aggregate in mongodb - mongodb

I try to aggregate and group objects in mongodb by month. I basically copy query from mongo docs.
db.users.aggregate(
{
$group : {
_id: {
month : { $month : "$registrationDate" }
},
count: { $sum: 1 }
}
}
);
Type of registrationDate is date.
Short version of object in users collection.
{
"_id" : ObjectId("50ab08399b57f2be03000000"),
...
"registrationDate" : ISODate("2012-11-20T05:34:01.000Z"),
...
}
Then I get an exception
exception: can't convert from BSON type NumberDouble to Date

The problem is that you have some documents in your collection where the type of registrationDate is not a date but a double-precision floating point number. You can find these documents with db.users.find( { registrationDate: { $type:1 } } ). Fix these documents and it should work. Alternatively you can add the following step to the front of your aggregation to exclude those documents where the registrationDate is not a Date: {$match: { registrationDate: { $type:9 } } }

Related

Get record having highest date inside nested group in Mongodb

I am having a record set like below :
I need to write a query where foreach datatype of every parent I show the data type with highest date i.e
So far I am able to create two groups one on parent id & other on data type but i am unable to understand how to get record with max date.
Below is my query :
db.getCollection('Maintenance').aggregate( [{ $group :
{ _id :{ parentName: "$ParentID" , maintainancename : "$DataType" }}},
{ $group : {
_id : "$_id.parentName",
maintainancename: {
$push: {
term:"$_id.DataType"
}
}
}
}] )
You don't have to $group twice, try below aggregation query :
db.collection.aggregate([
/** group on two fields `ParentID` & `Datatype`,
* which will leave docs with unique `ParentID + Datatype`
* & use `$max` to get max value on `Date` field in unique set of docs */
{
$group: {
_id: {
parentName: "$ParentID",
maintainancename: "$Datatype"
},
"Date": { $max: "$Date" }
}
}
])
Test : mongoplayground
Note : After group stage you can use $project or $addFieldsstages to transform fields the way you want.

How to update date field by removing time in mongoDB?

I have a collection of 100 records.Each record have date field like below
"created_date" : ISODate("2018-11-20T00:00:00.000Z")
I want to update each record by removing the time like below
"created_date" : "2018-11-20"
How to write a query for this kind of update
You can remove the timestamp from the date using Aggregate Query and update collection using forEach function. It may take time but it will update the collection data as per your requirement. Here is Mongo aggregation query:
db.getCollection('demo').aggregate([
{
$addFields: {
DateinString: {
$dateToString: {
format: "%Y-%m-%d",
date: "$created_date"
}
}
}
}
]).forEach(function(myDoc){
db.getCollection("demo").update({
_id: myDoc._id
}, {
$set: {
"created_date": myDoc.DateinString
}
})
})

Get all records with specified properties between a certain date range

I am passing in two dates formatted as MM-DD-YYYY which is a date range. I need to query all records within that range and include specified fields. I've had no luck.
Part of a record in Mongo:
{
"_id": "some ID",
"date": {
"$date": "2015-06-26T13:02:12.121Z"
},
Query:
var Start = '09-07-2015'
var End = '09-14-2015'
If I do:
var query = Order.find({
date : {
$lt : End,
$gt : Start
}
});
I get the full document within the week ranges as expected. However, I want to specify the fields to return rather than full document. So I've tried using grouping and project to specify those fields:
var query = Order.aggregate(
{
$match :
{
date: {
$gte: start,
$lt: end
}
},
$group:
{
cust_ID: '$request.headers.customer_id',
wholesaler_ID: '$request.headers.wholesalerID'
}
}
);
Likewise: I've also tried it using project to get the results I want. I thought maybe it won't match on a date string like 09-07-2015, so I included the ISO date directly. Still no luck... the query comes back undefined or empty:
var query = Order.aggregate(
{
$project:
{
date: 'date',
cust_ID: '$request.headers.custID',
wholesaler_ID: '$request.headers.wholesalerID'
}
},
{
$match :
{
date: {
$gte: "2014-12-09T21:02:56.872Z",
$lt: "2015-12-09T21:02:56.872Z"
}
}
}
);
var query = Order.find({
date : {
$lt : End,
$gt : Start
}}, {cust_ID:1, wholeseller_ID:1}
);
This will work.
I just tested this using Robomongo
db.getCollection('offerdb').find({time_posted:{$gt: '2015-10-21T21:40:04+05:30', $lte:'2015-12-14T05:53:14+05:30'}},{_id:1, merchant_id:1})
Works like a charm for me.
Try this command in mongo shell
use dbname
db.collection_name.find({date: {$gte: ISODate('2015-09-07 00:00:00'), $lte: ISODate('2015-09-14 23:59:59.999999')}},{'cust_ID':1,'_id':0,'wholeseller_ID':1})

PyMongo query field of documents

In my DynamoDB every document has several fields, one of the fields is a document called "engines" that holds several documents (all the engines) that hold several fields, as the picture shows below:
I would like to get all the couples of (engine,definitions) that their definition date is greater than a specific date.
I tried:
cursor=collection.find(
{'engines': { "$elemMatch" :
{ "definitions" :
{'$gt': startdate} } } }
,{'engines':{'$elemMatch':1}},{'engines':{'$elemMatch':{'definitions':1}}} )
but I get:
TypeError: skip must be an instance of int
Can someone help with the query?
You've mixed up the closing } and ended up passing {'engines':{'$elemMatch':{'definitions':1}}} as a skip argument value.
I think you meant:
cursor = collection.find(
{
'engines': {
"$elemMatch": {
"definitions": {
'$gt': startdate
}
}
}
},
{
'engines': {
'$elemMatch': {
'definitions': 1
}
}
}
)

How to count the number of documents on date field in MongoDB

Scenario: Consider, I have the following collection in the MongoDB:
{
"_id" : "CustomeID_3723",
"IsActive" : "Y",
"CreatedDateTime" : "2013-06-06T14:35:00Z"
}
Now I want to know the count of the created document on the particular day (say on 2013-03-04)
So, I am trying to find the solution using aggregation framework.
Information:
So far I have the following query built:
collection.aggregate([
{ $group: {
_id: '$CreatedDateTime'
}
},
{ $group: {
count: { _id: null, $sum: 1 }
}
},
{ $project: {
_id: 0,
"count" :"$count"
}
}
])
Issue: Now considering above query, its giving me the count. But not based on only date! Its taking time as well into consideration for unique count.
Question: Considering the field has ISO date, Can any one tell me how to count the documents based on only date (i.e excluding time)?
Replace your two groups with
{$project:{day:{$dayOfMonth:'$createdDateTime'},month:{$month:'$createdDateTime'},year:{$year:'$createdDateTime'}}},
{$group:{_id:{day:'$day',month:'$month',year:'$year'}, count: {$sum:1}}}
You can read more about the date operators here: http://docs.mongodb.org/manual/reference/aggregation/#date-operators