2014-09-26 40 views
2

玉模板代碼比較對象ID在玉和MongoDB

each member in team.members 
     if member == user._id 
     - flag=true; 

這裏,球隊在蒙戈DB收集「團隊」文件和「會員」是具有數組作爲值的屬性。

這裏#{member}的值分別是53fecc27bace957811633dcc5412a08fa51c105017b9f1fe。兩者都是對象標識。

值#{user.id}是53fecc27bace957811633dcc

然而,這種比較會返回虛假和標誌是從來沒有設置爲true。 這是爲什麼?

回答

3

編輯清晰度:

mongodb本機驅動程序使用自定義ObjectID類型。即使ObjectIDs相同,memberuser._id仍然會引用兩個不同的對象,因此比較失敗。

下面是我正在談論的一個簡化示例。在下面的例子中,我有一個TestObject的構造函數(模擬mongo ObjectID)。我實例化兩個具有相同參數的對象(即x1x2)。雖然x1x2是相同對象的實例,並且都是使用相同的參數創建的,但它們實際上只是具有相同數據/有效內容的兩個不同對象。因此,第一次直接比較失敗了,因爲它們實際上並不相同。爲了進一步模擬,我添加了一個原型方法.equals(),它確保兩個對象都是TestObject的實例,並且有效載荷是相同的。

function TestObject(data) { 
    this.payload = data; 
} 
TestObject.prototype.equals = function(anotherObject) { 
    return (anotherObject instanceof TestObject) && (this.payload === anotherObject.payload); 
}; 

var x1 = new TestObject(1), x2 = new TestObject(1); 

console.log(x1 == x2); // <-- false 
console.log(x1.equals(x2)); // <-- true 

您可以通過將ObjectIDs轉換爲字符串來比較它們。

each member in team.members 
    if member.toString() == user._id.toString() 
    - flag=true; 

另一種可能的解決辦法是使用的ObjectId .equal()方法:如果我存儲對象ID在另一個對象例如x

each member in team.members 
    if member.equals(user._id) 
    - flag=true; 
+0

謝謝你解決了這個問題。 – 2014-10-03 07:38:25

+0

爲什麼早期的方案無法正常工作,請理解一個原因。 – 2014-10-03 07:39:12

+0

我假設你使用Mongoose,它使用mongodb本地驅動程序。 mongodb本地驅動程序使用自定義的ObjectID類型。即使ObjectIDs是相同的,「成員」和用戶。_id'指的是兩個不同的對象,因此比較失敗。 (1)'.equals()'方法(例如'member.equals(user._id)'),或者(2)使用'.toString()',我演示了這些自定義ObjectID在我上面的答案中。 – JME 2014-10-03 10:56:01

1

MongoDB的objectIds可能不是簡單的字符串。根據​​,它們是BSON類型。 成員和user._id可能是兩個不同的對象,這就是爲什麼「引用等於」比較失敗的原因,儘管它們的字符串表示方式是相同的。

在相關說明中,在您的應用程序中使用MongoDB生成的對象ID是一個壞主意。更健壯的設計是爲每種記錄類型設置自己的標識符。

+0

所以,你的意思是說X不再是OBJECTID? – 2014-10-03 07:41:15

+0

@Aniket Lawande試圖說的是,雖然兩個對象仍然是ObjectID,並且就Mongoose而言,它們表示相同的ObjectID,就JavaScript(因此Jade)而言,它們是兩個不同的對象,即使它們是具有相同的類型並且具有相同的有效負載(ObjectID引用)。我編輯了我的原始答案以用簡單的自定義對象來模擬問題。 – JME 2014-10-06 01:48:56