2012-12-11 101 views
3

我想創建一個貓鼬查詢,可以通過slu or或編號查詢,但問題來了,我不知道哪一個我將要處理我有這個作爲一個快速途徑:

app.get('/animals/dogs/:id', function (req, res, next) { 
    Dogs.find({$or: [{slug: id}, {_id: id}]}, function (err, docs) { 
     if (err) { 
      return next(err); 
     } 
     // .... 
    }); 
}); 

我想一張由搜索能力,但上面這個方法拋出了一個Invalid ObjectId錯誤。

另一種方法是嵌套查詢,但這種感覺有點麻煩:

app.get('/animals/dogs/:id', function (req, res, next) { 
    Dogs.find({slug: id}, function (err, docs) { 
     if (err) { 
      return next(err); 
     } 
     if (!docs) { 
      Dogs.findById(id, function (err, docs) { 
      // ... 
      }); 
     } 
     // .... 
    }); 
}); 

是否有任何其他的方法,我還沒有考慮過?我知道我可以將我的slu子變成ObjectId,但我寧願儘可能避免這種情況。

回答

4

測試是否id是一個有效的ObjectId,然後只在查詢這個詞,如果它是有效的:

app.get('/animals/dogs/:id', function (req, res, next) { 
    var query = {$or: [{slug: id}]}; 
    if (id.match(/^[0-9a-fA-F]{24}$/)) { 
     query.$or.push({_id: id}); 
    } 
    Dogs.find(query, function (err, docs) { 
     if (err) { 
      return next(err); 
     } 
     // .... 
    }); 
}); 
+0

啊,好東西,我想知道是否有一個匹配ObjectId的正則表達式 - 我會給它一個。 – leepowell

+0

完美地工作 - 謝謝! – leepowell

3

我肯定更喜歡下面的語法(使用貓鼬驗證爲ObjectId):

const mongoose = require('mongoose'); 
const isObjectId = mongoose.ObjectId.isValid; 

app.get('/animals/dogs/:id', function (req, res, next) { 
    const id = req.params.id; 
    const promise = isObjectId(id) ? Dogs.find(id) : Dogs.findOne({ slug: id }); 

    promise.then(dog => res.send(dog)).catch(next) 
});