web-dev-qa-db-fra.com

exception: impossible de convertir le type EOO BSON en Date

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.

25
jsbisht

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);
})
56
JohnnyHK

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.

4
FRocha

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"

2
Skipwave

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. 

1
Anurag Pandey

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.

1
facumedica

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é. 

0
Enda Molloy

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'
      }
    }
  }
])
0
Wolf7176

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}}])
0
ABDUL JAMAL