2012-06-16 40 views
26

Ich habe ein unkompliziertes Werkzeug zum Erstellen von Dokumentensammlungen und zum automatischen Formatieren für EPUB- oder LaTeX-Rendering, das auf ExpressJS geschrieben wurde. Ich benutze Coffeescript, wenn das wichtig ist (ich bezweifle es).Mungo: ObjectId-Vergleiche schlagen inkonsistent fehl

Mit Mongoose, ich habe folgendes:

DocumentSchema = new Schema 
    title:  String 

Offrefs = new Schema 
    ref:  { type: ObjectId } 
    isa:  String 

BinderSchema = new Schema 
    title:  String 
    contains: [Offrefs] 

Offrefs ist nicht festgelegt, was es bedeutet, weil, weil ich einige Bindemittel in der Lage sein wollen, in anderen Bindemittel enthalten, logische Sammlungen zu erstellen: „Diese sind für den Drucker, "" Diese sind für epub, "" Das sind nur Web, "etc. (Ich habe alle Verschiedenes ausgezogen.)

Leider habe ich in Abfragen wo, für abgerufen Objekte

(story._id == offref.ref) -> True 

Und die beiden sehen tatsächlich gleich aus. Aber:

(binder._id == offref.ref) -> False 
(String(binder._id) == String(offref.ref)) -> True 

Und ein visueller Vergleich der beiden Referenzen in den letzten zwei, sie sind die gleiche ID-Nummer, aber die ObjectId Objekte nicht korrekt vergleichen.

Ich möchte nicht ständig Zeichenfolgenkonvertierungen durchführen müssen, was eine starke Möglichkeit ist, wenn ich diese komplexen Objekte in Datenstrukturen umwandle. Baumbeziehungen sind in jedem DB ein Bär; Sie sollten in MongoDB nicht schwierig sein.

Wie machen Sie ObjectId Vergleiche in MongoDB?

Antwort

76

Ein gerader == (oder ===) Vergleich vergleicht die beiden Objekte als Referenz, nicht als Wert. Das wird also nur dann als wahr gewertet, wenn beide auf dieselbe Instanz verweisen.

Stattdessen sollten Sie die equals Methode von ObjectID werden mit ihren Werten vergleichen:

story._id.equals(offref.ref) 

Wie @bendytree Hinweise in den Kommentaren, wenn entweder Wert null sein könnte (und Sie wollen nulls wie gleich vergleichen), dann können Sie die folgenden statt:

String(story._id) === String(offref.ref) 
+8

Yay, undokumentierte Funktionen. – peterjwest

+0

Also das ist nicht dasselbe wie mongoose.Schema.Types.ObjectID? Ihre Dokumentation impliziert, dass es nur die Methode 'auto' hat: http://mongoosejs.com/docs/api.html#schema-objectid-js – peterjwest

+1

@peterjwest Richtig, 'mongoose.Schema.Types.ObjectId' ist wirklich nur für die Verwendung als Feldtyp-Metadaten in Schemadefinitionen. – JohnnyHK

1

Diese etwas über die ursprüngliche gestellte Frage geht, aber ich habe, dass ein String-Vergleich in einigen Fällen falsch die .equals Methode der ObjectID des gefundenen zurück, wo zurückkehren true, auch wenn die Werte nicht null sind. Beispiel:

var compare1 = invitationOwningUser.toString() === linkedOwningUser.toString(); 
var compare2 = invitationOwningUser.equals(linkedOwningUser); 
var compare3 = String(invitationOwningUser) === String(linkedOwningUser); 
logger.debug("compare1: " + compare1 + "; " + "compare2: " + compare2 + "; " + "compare3: " + compare3); 

Ausgang:

compare1: true; compare2: false; compare3: true 

Dies passierte, wenn invitationOwningUser (ObjectID) aus einer Sammlung kam schuf ein Mungo-Schema verwenden und linkedOwningUser (auch ein ObjectID) stammte aus einer Sammlung nicht erstellt Mungo (nur normale MongoDB-Methoden).

Hier ist das Dokument invitationOwningUser (das owningUser Feld) enthält:

{ 
    "_id" : ObjectId("5782faec1f3b568d58d09518"), 
    "owningUser" : ObjectId("5781a5685a06e69b158763ea"), 
    "capabilities" : [ 
     "Read", 
     "Update" 
    ], 
    "redeemed" : true, 
    "expiry" : ISODate("2016-07-12T01:45:18.017Z"), 
    "__v" : 0 
} 

Hier ist das Dokument mit linkedOwningUser (das owningUser Feld):

{ 
    "_id" : ObjectId("05fb8257c95d538d58be7a89"), 
    "linked" : [ 
     { 
      "owningUser" : ObjectId("5781a5685a06e69b158763ea"), 
      "capabilities" : [ 
       "Read", 
       "Update" 
      ] 
     } 
    ] 
} 

So, als Endergebnis für mich , Verwende ich die String-Vergleichstechnik, um ObjectIDs, nicht die .equals-Methode zu vergleichen.

+0

Dies scheint ein kritisches Problem zu sein. Weißt du, warum Mongoose sie nicht als gleich sieht? Ich vermute, es ist 'if (! Buffer.isBuffer (other))' in der 'MongooseBuffer.mixin.equals', die eine Optimierung scheint, um das Scannen der Inhalte zu speichern. Ich mache mir jetzt Sorgen! Ich habe gerade meine .toStrings in .equals umgewandelt. (aber ich benutze nur Mungo == Mungo, also denke ich, es ist kein Risiko). – scipilot

Verwandte Themen