Comparando mangosta _id y cadenas

197

Tengo una aplicación node.js que extrae algunos datos y los pega en un objeto, como este:

var results = new Object();

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

Cuando hago un if / then basado en esa ID almacenada, la comparación nunca es cierta:

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

Cuando hago un console.log de los dos id, coinciden exactamente:

User id: 4fc67871349bb7bf6a000002 AnotherMongoDocument id: 4fc67871349bb7bf6a000002

Supongo que este es algún tipo de problema de tipo de datos, pero no estoy seguro de cómo convertir los resultados. ID de usuario a un tipo de datos que dará como resultado que la comparación anterior sea verdadera y mi cerebro tercerizado (también conocido como Google) no ha podido ayudar.

palmadita
fuente

Respuestas:

360

Mongoose usa el controlador mongodb-native, que usa el tipo de ObjectID personalizado. Puede comparar ObjectID con el .equals()método Con tu ejemplo results.userId.equals(AnotherMongoDocument._id),. El tipo ObjectID también tiene un toString()método, si desea almacenar una versión en cadena del ObjectID en formato JSON, o una cookie.

Si usa ObjectID = require("mongodb").ObjectID(requiere la biblioteca mongodb-native) puede verificar si results.userIdes un identificador válido con results.userId instanceof ObjectID.

Etc.

cjohn
fuente
13
Documentos para .equals(): mongodb.github.io/node-mongodb-native/api-bson-generated/…
Anthony Panozzo
44
Si ya lo está utilizando mongoose, puede require('mongoose').mongo.ObjectIDhacerlo para no tener que enumerar ninguna dependencia adicional
JoshuaDavid el
63

ObjectIDs son objetos, así que si solo los comparas con ellos ==, estás comparando sus referencias. Si desea comparar sus valores, debe utilizar el ObjectID.equalsmétodo:

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

convertir el ID del objeto a cadena (usando el método toString ()) hará el trabajo.

Dila Gurung
fuente
8

Las respuestas aceptadas realmente limitan lo que puede hacer con su código. Por ejemplo, no podría buscar una matriz Object Idsutilizando el método equals. En cambio, tendría más sentido lanzar siempre a cadena y comparar las claves.

Aquí hay una respuesta de ejemplo en caso de que necesite usar indexOf()para verificar dentro de una matriz de referencias para una identificación específica. asumir queryes una consulta que está ejecutando, asumir someModeles un modelo mongo para la identificación que está buscando, y finalmente asumir results.idListes el campo en el que está buscando su identificación de objeto.

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
fuente
1
o una frase:let exists = results.idList.filter(val => val.toString() === thisIsTheStringifiedIdWeAreLookingFor).length ? true : false
Zlatko
44
@Zlatko No soy un gran admirador de la nueva sintaxis sino de cada uno lo suyo.
r3wt
2
@Zlatko const exists = results.idList.some(val => val.toString() === thisIsTheStringifiedIdWeAreLookingFor) o const exists = results.idList.some(val => val.equals(someModel._id))
axanpi
1
@Zlatko todos estos años después, y adivina qué. Prefiero tu versión a la mía ahora. ¿te importa si lo agrego a mi respuesta con la atribución adecuada?
r3wt
1
El precio del progreso :) Por supuesto, puede usar la respuesta, su propósito era proporcionar una alternativa o ayuda si es posible.
Zlatko
6

De acuerdo con lo anterior, encontré tres formas de resolver el problema.

  1. AnotherMongoDocument._id.toString()
  2. JSON.stringify(AnotherMongoDocument._id)
  3. results.userId.equals(AnotherMongoDocument._id)
alegría
fuente
0

Me enfrenté exactamente al mismo problema y simplemente resolví el problema con la siguiente ayuda JSON.stringify():

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

Las tres posibles soluciones sugeridas aquí tienen diferentes casos de uso.

  1. Utilice .equals al comparar ObjectID en dos mongoDocuments como este

    results.userId.equals (AnotherMongoDocument._id)

  2. Utilice .toString () al comparar una representación de cadena de ObjectID con un ObjectID de un mongoDocument. Me gusta esto

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

Padre-imperio
fuente
¿Cuál es la tercera solución posible?
Chris Catignani