Reputation: 9679
I am getting an issue for running the following aggregate query:
db.snippets.aggregate([ { '$project': { month: { '$month': '$created_at' }} } ])
The error message for the same is:
assert: command failed: {
"errmsg" : "exception: can't convert from BSON type EOO to Date",
"code" : 16006,
"ok" : 0 } : aggregate failed
How do I get around this issue? I found a related question: MongoDB: can't convert from BSON type EOO to Date.
But it doesn't tell me how to get things done.
Upvotes: 36
Views: 44498
Reputation: 230
In my case I had to use "$toDate" and it worked:
db.snippets.aggregate([ { '$project': { month: { '$month': {$toDate: '$created_at'} }} } ])
Upvotes: 0
Reputation: 1
First, you can identify the particular field which is causing an issue as follows:
db.collectionName.find( { 'dateField' : { $type : 2 } } )
The above line checks and finds all the documents with field name 'dateField' having type as String(referred as $type - 2).
Once it is identified and verified, we can modify those records as follows:
db.collectionName.find( { 'dateField' : { $type : 2 } } ).forEach( function (x) {
x.dateField = new ISODate(x.dateField);
db.collectionName.save(x);
});
Upvotes: 0
Reputation: 452
First, you need to check whether the data type is in ISODate. IF not you can change the data type as the following example.
db.collectionName.find().forEach(function(each_object_from_collection){each_object_from_collection.your_date_field=new ISODate(each_object_from_collection.your_date_field);db.collectionName.save(each_object_from_collection);})
Now you can find it in two ways
db.collectionName.find({ $expr: {$eq: [{ $year: "$your_date_field" }, 2017]}});
Or by aggregation
db.collectionName.aggregate([{$project: {field1_you_need_in_result: 1,field12_you_need_in_result: 1,your_year_variable: {$year: '$your_date_field'}, your_month_variable: {$month: '$your_date_field'}}},{$match: {your_year_variable:2017, your_month_variable: 3}}])
Upvotes: 0
Reputation: 658
I had a similar problem, and solved it checking if the date existed.
db.users.aggregate([
{$project:{day: { $cond: ["$bd", { $dayOfMonth: "$bd" }, -1] },
month: { $cond: ["$bd", { $month: "$bd" }, -1] },
year: { $cond: ["$bd", { $year: "$bd" }, -1] }
}},
{$match:{"month":1, "day":15}}
])
My date field is bd
and with that match I'm getting all users that have their birthday on January 15th.
Upvotes: 2
Reputation: 984
This error can also appear if you have incorrectly named your properties in your aggregation relative to what they are in your database.
For example my code was
$group: {
_id: {$week: "$projects.timeStamp"},
total: { $sum: "$projects.hours" }
}
But I hadn't camelcased timestamp in my database so simply modifying to projects.timestamp
fixed it.
Upvotes: 0
Reputation: 317
I had the same problem, I figured that the date field is missing for some of the documents causing the conversion to fail. I just added a match clause to filter these out. But ofcourse i am investigating on my app side why they are not being populated.
db.snippets.aggregate([
{
'$match': {
'created_at': {
"$exists": true
}
}
},
{
'$project': {
month: {
'$month': '$created_at'
}
}
}
])
Upvotes: 2
Reputation: 693
I had a related issue, but in my case the Date fields were the members of an array, so the error was "can't convert BSON type Object to Date".
I needed to get the day of week from the dates in the possibleTripDateTimes array.
Sample document:
{
"possibleTripDateTimes" : [
{
"tripDateTime" : ISODate("2015-08-01T06:00:00.000-0700")
}
]
}
The fix was simply to use dot notation to address the array member fields.
db.trips.aggregate([
{
$project: {
departTime: {
$map: {
input: "$possibleTripDateTimes.tripDateTime",
as: "dateTime",
in: { $dayOfWeek: "$$dateTime" }
}
}
}
}
]
);
I hope this helps someone who also gets zero search results on the "BSON type Object" search
Upvotes: 3
Reputation: 744
try this one, its help for me above problem.
db.snippets.aggregate([{
'$project': {
month: { $substr: ["$created_at", 5, 2] }
}
}]);
above code get month wise
data is entered into the database in ISO format which can then be easily worked with.
Upvotes: 6
Reputation: 960
In some situations, some documents are supposed to have empty Date fields. In those cases, you could try this (using your example):
db.snippets.aggregate([ { '$project': { month:
{ $cond: [{ $ifNull: ['$created_at', 0] }, { $month: '$created_at' }, -1] }} } ])
In this example, we would get -1 in the cases whenever no field '$created_at' is found. For all the other cases, we would get the Date month.
Upvotes: 4
Reputation: 312115
You likely have one or more docs with a created_at
value that's not a BSON Date
and you'll need to fix that by converting those values to Date
or removing them.
You can find those docs with a $not
query that uses the $type
operator like:
db.snippets.find({created_at: {$not: {$type: 9}}})
If the created_at
values are date strings, you can find the docs that need updating and then update them in the shell using code like:
db.snippets.find({created_at: {$not: {$type: 9}}}).forEach(function(doc) {
// Convert created_at to a Date
doc.created_at = new Date(doc.created_at);
db.snippets.save(doc);
})
Upvotes: 69