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.

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.



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)) {
    ...
}

17

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


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

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)

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');
}

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 ()


Qual é a terceira solução possível?
Chris Catignani
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.