2012-02-27 64 views
5

我正在嘗試爲用戶創建一個路由,以便能夠檢查其他用戶的配置文件。但是,我希望通過兩個不同的網址/profile/nickname/profile/id加入這些配置文件,以便可以通過使用用戶的暱稱或用戶標識來接受配置文件。我嘗試下面的代碼:

app.get("/profile/:id", function(req, res) { 

User.findOne({ $or : [{ "nickname": req.params.id },{ "_id": req.params.id }] }, function(err, user) { 
    if(user) 
    { 
     res.render('users/profile.jade', { 
     locals: { 
      currentUser: user, 
      title: user.nickname +"'s Profile", 
      jsf:[], 
     } 
     }); 
    } 
    else 
    { 
     res.render('404.jade', { 
      status: 404, 
      title: 'Page Not Found', 
       jsf: [] 
     }); 
    } 
}); 
}); 

的問題是,現在看來似乎是隻與ID而不是與暱稱的工作,也就是說,如果我存取權限/profile/4f4ae474546708b219000005工作上的事情,但如果我訪問/profile/mmellad這是給那個用戶的暱稱,我得到了404頁面。

還有一件事我要指出的是暱稱工作得很好,這是改變從

User.findOne({ $or : [{ "nickname": req.params.id },{ "_id": req.params.id }] } 

查詢到

User.findOne({ "nickname": req.params.id } } 

在這種情況下/profile/mmellado工作正常,但使用用戶ID顯然不是。

什麼是正確的方法來做到這一點?我在想我可能會用錯方法。

另一件事一提的是,如果我嘗試在蒙戈控制檯下面的代碼,它工作正常,以及:

x = db.users.findOne({ $or: [ {nickname:"mmellado"}, {_id:ObjectId("4f4ae474546708b219000005")} ]}) 

我插入正確的暱稱和一個錯誤的_id測試的代碼,然後測試用一個錯誤的暱稱和正確的_id。在這兩種情況下,x最終都包含了我需要的記錄的對象。

我想我可以用一條額外的路徑修復它,但我是新來的Node.js和所有一起表達,所以我不知道propop方法會是什麼。

謝謝!

+0

你在用什麼版本的mongo? – 2012-02-27 08:17:03

+0

蒙戈的版本是這樣的: 馬科斯Mellados的iMac-2:〜馬科斯$ mongod的--version 分貝版本V2.0.2,pdfile 4.5版 週一02月27日2點48分十一秒Git版本:514b122d308928517f5841888ceaa4246a7f18e3 – 2012-02-27 08:48:45

回答

4

你在控制檯中試過這個:x = db.users.findOne({ $or: [ {nickname:"mmellado"}, {_id:ObjectId("mmellado")} ]})。即使暱稱匹配,您也會看到一個錯誤,因爲它首先嚐試將「mmellado」轉換爲ObjectId並失敗。這可能是您的網頁在使用暱稱時失敗的原因。

我不知道node.js mongodb驅動程序的內部,但它可能會嘗試將內部轉換爲ObjectId在查詢「_id」字段(如果無效,則失敗)。我沒有檢查這個,所以試試看。還可以嘗試檢查回調中的err對象。如果這是問題,解決此問題的一種方法是在查詢之前檢查參數是否爲有效的ObjectId,例如自己創建ObjectId並在失敗時捕獲異常。事情是這樣的(未測試):

try { 
    var objectId = createObjectId(req.params.id); // Create this function yourself 
    User.findOne({ "_id": objectId }, callbackFunction); 
} catch (err) { 
    // Fall back to using nickname 
    User.findOne({ "nickname": req.params.id }, callbackFunction); 
} 
+0

我試着在查詢時間打印錯誤代碼。這是我得到: [錯誤:無效ObjectId], 我的假設是,當我嘗試使用Finch作爲參數,並且條件通過_id部分,由於給定的字符串不是有效的ObjectId,查詢中斷,返回一個錯誤......因此,即使部分查詢確實有效,也不會給出結果......關於如何解決此問題的任何想法? – 2012-02-27 19:14:17

+0

@MarcosMellado這似乎支持我的想法。我在我的文章中提出瞭解決方案,我修改了它以添加一些示例代碼,以使其更清晰。 – Lycha 2012-02-27 19:32:23

+0

我其實到了一個非常類似的解決方案,我會做適當的修改它與嘗試捕捉工作,讓你知道它的工作:) – 2012-02-27 20:50:32

0

默認_id值是12字節的二進制哈希值,所以你首先需要將字符串轉換成二進制您使用ObjectID.createFromHexString這樣發送查詢之前:

var id = ObjectID.createFromHexString(idHex); 

然後在您的查詢中使用id。

您的代碼應該是這個樣子:

User.findOne({ $or : [{ "nickname": req.params.id },{ "_id": ObjectID.createFromHexString(req.params.id) }] }, function(err, user) { ........ 

問候芬奇!

+0

你會如何定義ObjectId?現在我有mongoose = require('mongoose'), \t \t ObjectID = mongoose.Schema.ObjectId, – 2012-02-28 17:33:38

+0

忽略最後一條評論,他的方法的問題是,在發送暱稱作爲參數並將其傳遞給它的時候通過createFromHexString功能,它引發下一個錯誤:錯誤:參數傳遞的必須是12個字節的單個字符串或在十六進制格式24個進制字符的字符串(假定暱稱是雀例如) – 2012-02-28 17:38:43

+0

真實姿態,儘量第一轉換你的字符串(Finch)轉換爲Hex字符串:var hexString = nickname.toHexString(); - 然後傳遞它作爲參數來創建你的objectID – user313551 2012-02-28 20:46:02