在mongo中按ID或用户名查找

Jak*_*ake 2 mongoose mongodb node.js

我正在尝试按用户名或_id这样查找

exports.getUser = function (req, res){
    User.find({ $or: [ {username:req.params.id}, {_id:req.params.id} ] })
        .exec(function (err, collections) {
    res.send(collections);
    });
};
Run Code Online (Sandbox Code Playgroud)

当我通过_id搜索但是用户名失败时它会起作用,因为它无法返回有效的OjectID.我试着像这样做两个单独的查询

exports.getUser = function (req, res){
    User.findOne({username:req.params.id}).exec(function (err, user) {
        if (user)
            res.send(user);
    });

    User.findById({_id:req.params.id}).exec(function (err, user) {
        if (user)
            res.send(user);
    });
};
Run Code Online (Sandbox Code Playgroud)

但如果用户不存在,则会挂起,因为它从不发送响应.由于节点是异步的,我得到,Error: Can't set headers after they are sent.如果我添加

else
    res.sendStatus(400);
Run Code Online (Sandbox Code Playgroud)

到findById查询.我想不出任何其他方法来解决这个问题.我在MongoDB Node中检查了正则表达式,检查objectid是否有效

exports.getUser = function (req, res){
    var checkForHexRegExp = new RegExp("^[0-9a-fA-F]{24}$");
    if(checkForHexRegExp.test(req.params.id)){
        User.findById({_id:req.params.id}).exec(function (err, user) {
            if (user)
                res.send(user);
        });
    }
    User.findOne({username:req.params.id}).exec(function (err, user) {
            res.send(user);
    });

};
Run Code Online (Sandbox Code Playgroud)

而且我得到了同样的错误,因为它是异步的.必须有一个比这更好的方法

rob*_*lep 5

很可能你的第一个查询不起作用,因为MongoDB期望它_id是一个ObjectId,而不是一个字符串(req.params.id可能是):

var ObjectId = require('mongoose').Types.ObjectId;

exports.getUser = function (req, res) {
  var id  = req.params.id;
  var $or = [ { username : id } ];

  // Does it look like an ObjectId? If so, convert it to one and
  // add it to the list of OR operands.
  if (ObjectId.isValid(id)) {
    $or.push({ _id : ObjectId(id) });
  }

  User.find({ $or : $or }).exec(function (err, collections) {
    // TODO: check for errors
    res.send(collections);
  });
};
Run Code Online (Sandbox Code Playgroud)