Comparando mangusto _id e strings

197

Eu tenho um aplicativo node.js que extrai alguns dados e os cola em um objeto, como este:

var results = new Object();

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

Quando eu faço um if / then com base nesse ID armazenado, a comparação nunca é verdadeira:

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

Quando eu faço um console.log dos dois IDs, eles correspondem exatamente:

User id: 4fc67871349bb7bf6a000002 AnotherMongoDocument id: 4fc67871349bb7bf6a000002

Estou assumindo que este é algum tipo de problema de tipo de dados, mas não tenho certeza de como converter results.userId para um tipo de dados que resultará na verdade na comparação acima e meu cérebro terceirizado (aka Google) não conseguiu ajudar.

tapinha
fonte

Respostas:

360

O Mongoose usa o driver nativo do mongodb, que usa o tipo de ObjectID personalizado. Você pode comparar ObjectIDs com o .equals()método Com o seu exemplo results.userId.equals(AnotherMongoDocument._id),. O tipo ObjectID também possui um toString()método, se você deseja armazenar uma versão stringified do ObjectID no formato JSON ou um cookie.

Se você usar ObjectID = require("mongodb").ObjectID(requer a biblioteca nativa do mongodb), poderá verificar se results.userIdé um identificador válido results.userId instanceof ObjectID.

Etc.

cojo
fonte
13
Documentos para .equals(): mongodb.github.io/node-mongodb-native/api-bson-generated/…
Anthony Panozzo 6/15
4
Se você já está usando mongoosevocê pode apenas require('mongoose').mongo.ObjectIDpara que você não tem que listar todas as dependências adicionais
JoshuaDavid
63

ObjectIDs são objetos; portanto, se você apenas os comparar, ==você comparará as referências deles. Se você quiser comparar seus valores, precisará usar o ObjectID.equalsmétodo:

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

a conversão do ID do objeto em string (usando o método toString ()) fará o trabalho.

Dila Gurung
fonte
8

As respostas aceitas realmente limitam o que você pode fazer com seu código. Por exemplo, você não seria capaz de pesquisar uma matriz Object Idsusando o método equals. Em vez disso, faria mais sentido sempre converter para string e comparar as chaves.

Aqui está um exemplo de resposta, caso você precise usar indexOf() para verificar em uma matriz de referências um ID específico. assume que queryé uma consulta que você está executando, assume que someModelé um modelo mongo para o ID que você está procurando e, finalmente, assume que results.idListé o campo em que você está procurando seu ID 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
fonte
1
ou um one-liner:let exists = results.idList.filter(val => val.toString() === thisIsTheStringifiedIdWeAreLookingFor).length ? true : false
Zlatko 7/16
4
@Zlatko, eu não sou um grande fã da nova sintaxe, mas cada um na sua.
r3wt
2
@Zlatko const exists = results.idList.some(val => val.toString() === thisIsTheStringifiedIdWeAreLookingFor) ou const exists = results.idList.some(val => val.equals(someModel._id))
axanpi
1
@ Zlatko todos esses anos depois, e adivinhem. Eu prefiro sua versão à minha agora. importa se eu adicioná-lo à minha resposta com a atribuição adequada?
R3wt
1
O preço do progresso :) É claro que você pode usar a resposta, seu objetivo era fornecer uma alternativa ou ajudar, se possível.
Zlatko
6

De acordo com o exposto, encontrei três maneiras de resolver o problema.

  1. AnotherMongoDocument._id.toString()
  2. JSON.stringify(AnotherMongoDocument._id)
  3. results.userId.equals(AnotherMongoDocument._id)
alegria
fonte
0

Enfrentei exatamente o mesmo problema e simplesmente resolvi o problema com a ajuda da JSON.stringify()seguinte forma: -

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

As três soluções possíveis sugeridas aqui têm diferentes casos de uso.

  1. Use .equals ao comparar ObjectID em dois mongoDocuments como este

    results.userId.equals (AnotherMongoDocument._id)

  2. Use .toString () ao comparar uma representação de string de ObjectID a um ObjectID de um mongoDocument. como isso

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

Pai-Império
fonte
Qual é a terceira solução possível?
Chris Catignani