Mongoose - 查询$或slug / id

时间:2012-12-11 17:07:33

标签: mongoose

我正在尝试创建一个可以通过slug或id查询的mongoose查询,但问题在于我不知道我将要处理哪一个,因为我将它作为Express路由:

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) {
             // ...
             });
         }
         // ....
     });
});

还有其他方法我还没考虑过吗?我知道我可以将我的slug变成ObjectId,但如果可能的话我宁愿避免这种情况。

2 个答案:

答案 0 :(得分:5)

测试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);
        }
        // ....
    });
});

答案 1 :(得分:4)

我绝对更喜欢以下语法(对ObjectId使用Mongoose验证器):

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