2012-06-16 37 views
26

我有一個直接的工具來構建文檔集合,然後自動格式化它們以用於在ExpressJS上編寫的EPUB或LaTeX呈現。我使用Coffeescript,如果重要的話(我懷疑它)。Mongoose:ObjectId比較失敗並不一致

使用貓鼬,我有以下幾點:

DocumentSchema = new Schema 
    title:  String 

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

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

Offrefs沒有指定什麼它指的是因爲,因爲我希望能夠遏制一些粘合劑其他粘合劑,創建邏輯集合:「這些是爲打印機「,」這些是爲EPUB,「」這些只是網絡,「等(我已經剝離了所有雜項的東西了。)

不幸的是,我已經跑進查詢,其中,檢索物體

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

而且兩個確實看起來一樣。但是:

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

而且兩個引用的最後兩個視覺對比,他們相同的ID號,但ObjectId對象不正確地比較。

我不想要做的字符串轉換不斷,這是當我將這些複雜的對象爲數據樹木強烈方法可行。樹木關係是任何數據庫中的熊;他們在MongoDB中不應該很難。

你如何在MongoDB中進行ObjectId比較?

回答

76

的直==(或===)比較將通過引用,而不是值的兩個對象進行比較。所以如果它們都引用同一個實例,那麼它只會評估爲真。

相反,你應該使用的ObjectIDequals方法來比較它們的值:

story._id.equals(offref.ref) 

正如評論@bendytree筆記,如果任一值可以是空(和你想的空值比較平等),那麼你可以改用以下內容:

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

耶,無證的功能。 – peterjwest

+0

所以這和mongoose.Schema.Types.ObjectID不一樣? 他們的文檔暗示它只有'auto'方法: http://mongoosejs.com/docs/api.html#schema-objectid-js – peterjwest

+1

@peterjwest右鍵,'mongoose.Schema.Types.ObjectId'真的只是用作模式定義中的字段型元數據。 – JohnnyHK

1

這又有點超越了原來問的問題,但我發現,對象ID年代.equals方法在某些情況下返回false其中字符串比較將返回即使值不爲空也是如此。例如:

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

輸出:

compare1: true; compare2: false; compare3: true 

時invitationOwningUser(一個對象ID)從集合來使用貓鼬架構創建和linkedOwningUser(也是一個對象ID)使用未創建的集合來發生這種情況Mongoose(只是常規的MongoDB方法)。

這裏是含有invitationOwningUser(該owningUser字段)該文件:

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

這裏是含有linkedOwningUser(該owningUser字段)該文件:

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

所以,作爲對我來說是底線,我將使用字符串比較技術來比較ObjectID,而不是.equals方法。

+0

這似乎是一個關鍵問題。你知道爲什麼貓鼬看起來不一樣嗎?我在'MongooseBuffer.mixin.equals'中猜測它是'if(!Buffer.isBuffer(other))'這看起來是一種優化來保存掃描內容。我現在很擔心!我只是將我的.toString轉換爲.equals。 (但我只使用貓鼬==貓鼬,所以我想這不是一個風險)。 – scipilot