Porównanie mangusty _id i ciągów

197

Mam aplikację node.js, która pobiera niektóre dane i umieszcza je w obiekcie, na przykład:

var results = new Object();

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

Kiedy wykonuję if / then na podstawie tego przechowywanego identyfikatora, porównanie nigdy nie jest prawdziwe:

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

Kiedy robię plik console.log dwóch identyfikatorów, pasują one dokładnie:

User id: 4fc67871349bb7bf6a000002 AnotherMongoDocument id: 4fc67871349bb7bf6a000002

Zakładam, że jest to jakiś problem z typem danych, ale nie jestem pewien, jak przekonwertować results.userId na typ danych, który spowoduje, że powyższe porównanie będzie prawdziwe, a mój outsourcing mózgu (alias Google) nie był w stanie pomóc.

poklepać
źródło

Odpowiedzi:

360

Mongoose używa natywnego sterownika mongodb, który używa niestandardowego typu ObjectID. Możesz porównać ObjectID z tą .equals()metodą. Ze swoim przykładzie results.userId.equals(AnotherMongoDocument._id). Typ ObjectID ma również toString()metodę, jeśli chcesz przechowywać strunkową wersję ObjectID w formacie JSON lub plik cookie.

Jeśli używasz ObjectID = require("mongodb").ObjectID(wymaga biblioteki natywnej mongodb), możesz sprawdzić, czy results.userIdjest to poprawny identyfikator za pomocą results.userId instanceof ObjectID.

Itp.

cjohn
źródło
13
Dokumenty dla .equals(): mongodb.github.io/node-mongodb-native/api-bson-generated/…
Anthony Panozzo
4
Jeśli już używasz mongoose, możesz po prostu require('mongoose').mongo.ObjectIDnie wymieniać żadnych dodatkowych zależności
JoshuaDavid
63

ObjectIDs są obiektami, więc po prostu porównując je ==, porównujesz ich odwołania. Jeśli chcesz porównać ich wartości, musisz użyć ObjectID.equalsmetody:

if (results.userId.equals(AnotherMongoDocument._id)) {
    ...
}
JohnnyHK
źródło
17

konwersja id obiektu na ciąg (przy użyciu metody toString ()) wykona zadanie.

Dila Gurung
źródło
8

Akceptowane odpowiedzi naprawdę ograniczają możliwości kodu. Na przykład nie można przeszukiwać tablicy Object Idsza pomocą metody równości. Zamiast tego bardziej sensowne byłoby zawsze rzutowanie na łańcuch i porównywanie kluczy.

Oto przykładowa odpowiedź na wypadek, gdybyś musiał użyć, indexOf()aby sprawdzić w tablicy referencji określonego identyfikatora. załóżmy, że querywykonujesz zapytanie, załóżmy, że someModeljest to model mongo dla identyfikatora, którego szukasz, i na koniec załóż, że results.idListjest to pole, w którym szukasz identyfikatora obiektu.

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
źródło
1
lub jednowierszowy:let exists = results.idList.filter(val => val.toString() === thisIsTheStringifiedIdWeAreLookingFor).length ? true : false
Zlatko
4
@Zlatko nie jestem wielkim fanem nowej składni, ale do każdego własnego.
r3wt
2
@Zlatko const exists = results.idList.some(val => val.toString() === thisIsTheStringifiedIdWeAreLookingFor) lub const exists = results.idList.some(val => val.equals(someModel._id))
axanpi
1
@Zlatko przez te wszystkie lata później i zgadnij co. Wolę teraz twoją wersję od mojej. czy mogę dodać to do mojej odpowiedzi z odpowiednim przypisaniem?
r3wt
1
Cena postępu :) Oczywiście możesz skorzystać z odpowiedzi, jej celem było zapewnienie alternatywy lub pomocy, jeśli to możliwe.
Zlatko,
6

Zgodnie z powyższym znalazłem trzy sposoby rozwiązania problemu.

  1. AnotherMongoDocument._id.toString()
  2. JSON.stringify(AnotherMongoDocument._id)
  3. results.userId.equals(AnotherMongoDocument._id)
radość
źródło
0

Napotkałem dokładnie ten sam problem i po prostu go rozwiązałem za pomocą JSON.stringify():

if (JSON.stringify(results.userId) === JSON.stringify(AnotherMongoDocument._id)) {
        console.log('This is never true');
}
Jitendra
źródło
0

Trzy sugerowane tutaj możliwe rozwiązania mają różne przypadki użycia.

  1. Użyj .equals podczas porównywania ObjectID na dwóch takich dokumentach mongoDocuments

    results.userId.equals (AnotherMongoDocument._id)

  2. Użyj .toString () podczas porównywania reprezentacji ciągu ObjectID z ObjectID obiektu mongoDocument. lubię to

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

Ojcze Imperium
źródło
Jakie jest trzecie możliwe rozwiązanie?
Chris Catignani