Je reçois un problème pour exécuter la requête globale suivante:
db.snippets.aggregate([ { '$project': { month: { '$month': '$created_at' }} } ])
Le message d'erreur pour le même est:
assert: command failed: {
"errmsg" : "exception: can't convert from BSON type EOO to Date",
"code" : 16006,
"ok" : 0 } : aggregate failed
Comment puis-je contourner ce problème. J'ai trouvé une question connexe
Question relative au dépassement de capacité de la pile
Mais il ne dit pas comment faire avancer les choses.
Vous avez probablement un ou plusieurs documents avec une valeur created_at
qui n'est pas une BSON Date
et vous devrez résoudre ce problème en convertissant ces valeurs en Date
ou en les supprimant.
Vous pouvez trouver ces documents avec une requête $not
qui utilise l'opérateur $type
comme:
db.snippets.find({created_at: {$not: {$type: 9}}})
Si les valeurs created_at
sont des chaînes de date, vous pouvez rechercher les documents à mettre à jour, puis les mettre à jour dans le shell à l'aide du code suivant:
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);
})
Dans certains cas, certains documents sont supposés contenir des champs de date vides. Dans ces cas, vous pouvez essayer ceci (en utilisant votre exemple):
db.snippets.aggregate([ { '$project': { month:
{ $cond: [{ $ifNull: ['$created_at', 0] }, { $month: '$created_at' }, -1] }} } ])
Dans cet exemple, nous obtenons -1 dans les cas où aucun champ '$ created_at' n'est trouvé. Pour tous les autres cas, nous aurions le mois de date.
J'avais un problème connexe, mais dans mon cas, les champs Date étaient les membres d'un tableau. L'erreur était donc "impossible de convertir l'objet de type BSON en date".
Je devais obtenir le jour de la semaine à partir des dates du tableau possibleTripDateTimes.
Exemple de document:
{
"possibleTripDateTimes" : [
{
"tripDateTime" : ISODate("2015-08-01T06:00:00.000-0700")
}
]
}
Le correctif consistait simplement à utiliser la notation par points pour adresser les champs des membres du tableau.
db.trips.aggregate([
{
$project: {
departTime: {
$map: {
input: "$possibleTripDateTimes.tripDateTime",
as: "dateTime",
in: { $dayOfWeek: "$$dateTime" }
}
}
}
}
]
);
J'espère que cela aidera quelqu'un qui n'a également aucun résultat de recherche sur la recherche "Objet de type BSON"
essayez celui-ci, son aide pour moi ci-dessus problème.
db.snippets.aggregate([{
'$project': {
month: { $substr: ["$created_at", 5, 2] }
}
}]);
le code ci-dessus devient mensuel
les données sont entrées dans la base de données au format ISO avec lequel on peut facilement travailler.
J'ai eu un problème similaire et je l'ai résolu en vérifiant si la date existait.
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}}
])
Mon champ de date est bd
et avec ce match, je reçois tous les utilisateurs qui ont leur anniversaire le 15 janvier.
Cette erreur peut également apparaître si vous avez incorrectement nommé vos propriétés dans votre agrégation par rapport à ce qu'elles sont dans votre base de données.
Par exemple, mon code était
$group: {
_id: {$week: "$projects.timeStamp"},
total: { $sum: "$projects.hours" }
}
Mais je n'avais pas de timestamp camelcased dans ma base de données, donc la simple modification en projects.timestamp
l'a corrigé.
J'ai eu le même problème, je me suis dit qu'il manquait le champ de date pour certains documents, ce qui entraînait l'échec de la conversion. Je viens d'ajouter une clause de correspondance pour les filtrer. Mais bien sûr, je suis en train d’examiner du côté de mon application pourquoi ils ne sont pas peuplés.
db.snippets.aggregate([
{
'$match': {
'created_at': {
"$exists": true
}
}
},
{
'$project': {
month: {
'$month': '$created_at'
}
}
}
])
Tout d'abord, vous devez vérifier si le type de données est dans ISODate. SI vous ne pouvez pas changer le type de données comme dans l'exemple suivant.
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);})
Maintenant, vous pouvez le trouver de deux manières
db.collectionName.find({ $expr: {$eq: [{ $year: "$your_date_field" }, 2017]}});
Ou par agrégation
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}}])