Mungo _id und Strings vergleichen


197

Ich habe eine node.js-Anwendung, die einige Daten abruft und in ein Objekt steckt, wie folgt:

var results = new Object();

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

Wenn ich ein Wenn / Dann basierend auf dieser gespeicherten ID mache, ist der Vergleich niemals wahr:

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

Wenn ich ein console.log der beiden IDs erstelle, stimmen sie genau überein:

User id: 4fc67871349bb7bf6a000002 AnotherMongoDocument id: 4fc67871349bb7bf6a000002

Ich gehe davon aus, dass dies eine Art Datentypproblem ist, bin mir jedoch nicht sicher, wie die Datei results.userId in einen Datentyp konvertiert werden soll, der dazu führt, dass der obige Vergleich zutrifft und mein ausgelagertes Gehirn (auch bekannt als Google) nicht helfen konnte.

Antworten:


359

Mongoose verwendet den mongodb-nativen Treiber, der den benutzerdefinierten ObjectID-Typ verwendet. Sie können ObjectIDs mit der .equals()Methode vergleichen. Mit Ihrem Beispiel results.userId.equals(AnotherMongoDocument._id). Der ObjectID-Typ verfügt auch über eine toString()Methode, wenn Sie eine stringifizierte Version der ObjectID im JSON-Format oder ein Cookie speichern möchten.

Wenn Sie verwenden ObjectID = require("mongodb").ObjectID(erfordert die mongodb-native Bibliothek), können Sie überprüfen, ob results.userIdes sich um eine gültige Kennung mit handelt results.userId instanceof ObjectID.

Etc.



4
Wenn Sie bereits verwenden mongoose, können Sie nur, require('mongoose').mongo.ObjectIDdamit Sie keine zusätzlichen Abhängigkeiten
auflisten müssen

62

ObjectIDs sind Objekte. Wenn Sie sie also nur mit vergleichen, vergleichen ==Sie ihre Referenzen. Wenn Sie ihre Werte vergleichen möchten, müssen Sie die folgende ObjectID.equalsMethode verwenden:

if (results.userId.equals(AnotherMongoDocument._id)) {
    ...
}

17

Das Konvertieren der Objekt-ID in einen String (mithilfe der toString () -Methode) erledigt den Job.


8

Die akzeptierten Antworten schränken wirklich ein, was Sie mit Ihrem Code tun können. Beispielsweise könnten Sie kein Array von durchsuchenObject Ids mit der Methode equals . Stattdessen wäre es sinnvoller, die Zeichen immer in Zeichenfolgen umzuwandeln und zu vergleichen.

Hier ist eine Beispielantwort für den Fall, dass Sie indexOf()in einem Array von Referenzen nach einer bestimmten ID suchen müssen. Angenommen, es queryhandelt sich um eine Abfrage, die Sie ausführen. Angenommen, es someModelhandelt sich um ein Mongo-Modell für die gesuchte ID. Schließlich wird angenommen, dass results.idListes sich um das Feld handelt, in dem Sie nach Ihrer Objekt-ID suchen.

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
oder ein Einzeiler:let exists = results.idList.filter(val => val.toString() === thisIsTheStringifiedIdWeAreLookingFor).length ? true : false
Zlatko

4
@Zlatko Ich bin kein großer Fan der neuen Syntax, sondern für jeden seine eigene.
r3wt

2
@ Zlatko const exists = results.idList.some(val => val.toString() === thisIsTheStringifiedIdWeAreLookingFor) oder const exists = results.idList.some(val => val.equals(someModel._id))
Axanpi

1
@ Zlatko all diese Jahre später, und wissen Sie was. Ich ziehe deine Version jetzt meiner vor. Stört es mich, wenn ich es meiner Antwort mit der richtigen Zuordnung hinzufüge?
r3wt

1
Der Preis des Fortschritts :) Natürlich können Sie die Antwort verwenden, es war der Zweck, eine Alternative bereitzustellen oder wenn möglich zu helfen.
Zlatko

6

Demnach habe ich drei Wege gefunden, um das Problem zu lösen.

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

0

Ich hatte genau das gleiche Problem und löste das Problem einfach mit Hilfe von JSON.stringify(): -

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

0

Die drei hier vorgeschlagenen möglichen Lösungen haben unterschiedliche Anwendungsfälle.

  1. Verwenden Sie .equals, wenn Sie ObjectID für zwei MongoDocuments wie dieses vergleichen

    results.userId.equals (AnotherMongoDocument._id)

  2. Verwenden Sie .toString (), wenn Sie eine Zeichenfolgendarstellung von ObjectID mit einer ObjectID eines mongoDocument vergleichen. so was

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


Was ist die dritte mögliche Lösung?
Chris Catignani
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.