Comparaison de mangouste _id et de chaînes

197

J'ai une application node.js qui extrait des données et les colle dans un objet, comme ceci:

var results = new Object();

User.findOne(query, function(err, u) {
    results.userId = u._id;
}

Quand je fais un if / then basé sur cet ID stocké, la comparaison n'est jamais vraie:

if (results.userId == AnotherMongoDocument._id) {
    console.log('This is never true');
}

Quand je fais un console.log des deux identifiants, ils correspondent exactement:

User id: 4fc67871349bb7bf6a000002 AnotherMongoDocument id: 4fc67871349bb7bf6a000002

Je suppose que c'est une sorte de problème de type de données, mais je ne sais pas comment convertir results.userId en un type de données qui entraînera la comparaison ci-dessus et mon cerveau externalisé (alias Google) n'a pas pu aider.

tapoter
la source

Réponses:

360

Mongoose utilise le pilote natif mongodb, qui utilise le type ObjectID personnalisé. Vous pouvez comparer les ObjectID avec la .equals()méthode. Avec votre exemple results.userId.equals(AnotherMongoDocument._id),. Le type ObjectID possède également une toString()méthode, si vous souhaitez stocker une version chaîne de l'ObjectID au format JSON, ou un cookie.

Si vous utilisez ObjectID = require("mongodb").ObjectID(nécessite la bibliothèque native mongodb), vous pouvez vérifier s'il results.userIds'agit d'un identifiant valide avec results.userId instanceof ObjectID.

Etc.

cjohn
la source
13
Documents pour .equals(): mongodb.github.io/node-mongodb-native/api-bson-generated/…
Anthony Panozzo
4
Si vous utilisez déjà, mongoosevous pouvez simplement require('mongoose').mongo.ObjectIDne pas avoir à répertorier de dépendances supplémentaires
JoshuaDavid
63

ObjectIDs sont des objets, donc si vous les comparez avec ==vos références. Si vous souhaitez comparer leurs valeurs, vous devez utiliser la ObjectID.equalsméthode:

if (results.userId.equals(AnotherMongoDocument._id)) {
    ...
}
JohnnyHK
la source
17

la conversion de l'ID d'objet en chaîne (en utilisant la méthode toString ()) fera le travail.

Dila Gurung
la source
8

Les réponses acceptées limitent vraiment ce que vous pouvez faire avec votre code. Par exemple, vous ne pourrez pas rechercher un tableau deObject Ids à l'aide de la méthode equals. Au lieu de cela, il serait plus logique de toujours transtyper en chaîne et de comparer les clés.

Voici un exemple de réponse au cas où vous devriez utiliser indexOf()pour vérifier dans un tableau de références un identifiant spécifique. assumer queryest une requête que vous exécutez, assumer someModelest un modèle mongo pour l'id que vous recherchez, et enfin assumer results.idListest le champ dans lequel vous recherchez l'ID de votre objet.

query.exec(function(err,results){
   var array = results.idList.map(function(v){ return v.toString(); });
   var exists = array.indexOf(someModel._id.toString()) >= 0;
   console.log(exists);
});
r3wt
la source
1
ou un aller simple:let exists = results.idList.filter(val => val.toString() === thisIsTheStringifiedIdWeAreLookingFor).length ? true : false
Zlatko
4
@Zlatko je ne suis pas un grand fan de la nouvelle syntaxe mais chacun à son compte.
r3wt
2
@Zlatko const exists = results.idList.some(val => val.toString() === thisIsTheStringifiedIdWeAreLookingFor) or const exists = results.idList.some(val => val.equals(someModel._id))
axanpi
1
@Zlatko toutes ces années plus tard, et devinez quoi. Je préfère votre version à la mienne maintenant. l'esprit si je l'ajoute à ma réponse avec une attribution appropriée?
r3wt
1
Le prix du progrès :) Bien sûr, vous pouvez utiliser la réponse, son but était de fournir une alternative ou une aide si possible.
Zlatko
6

Selon ce qui précède, j'ai trouvé trois façons de résoudre le problème.

  1. AnotherMongoDocument._id.toString()
  2. JSON.stringify(AnotherMongoDocument._id)
  3. results.userId.equals(AnotherMongoDocument._id)
joie
la source
0

J'ai fait face exactement au même problème et j'ai simplement résolu le problème à l'aide de ce JSON.stringify()qui suit: -

if (JSON.stringify(results.userId) === JSON.stringify(AnotherMongoDocument._id)) {
        console.log('This is never true');
}
Jitendra
la source
0

Les trois solutions possibles suggérées ici ont des cas d'utilisation différents.

  1. Utilisez .equals lorsque vous comparez ObjectID sur deux mongoDocuments comme celui-ci

    results.userId.equals (AnotherMongoDocument._id)

  2. Utilisez .toString () lorsque vous comparez une représentation sous forme de chaîne de ObjectID à un ObjectID d'un mongoDocument. comme ça

    results.userId === AnotherMongoDocument._id.toString ()

Père-Empire
la source
Quelle est la troisième solution possible?
Chris Catignani