node.js 如何使用动态路由在我的 mongoose 数据库中查找人员

How use dynamic routes to find people in my mongoose database with node.js

    app.get('/admin/reservas/:param', function(req, res) {
        var param = req.param("param");
        console.log(param);
        mongoose.model('Something').findOne(
            {
            id: param
            }, function(err, obj) {
                res.send(obj);
                console.log(obj);
            }
        );
    });

我有这条路线,还有这个 EJS:

<% for(var i = 0; i < data.length; i++) { %>
  <td> <a href= <%="/admin/reservas/" + data[i].id  + ""%>><%= data[i].id   %></a></td>
  <td> <a href= <%="/admin/reservas/" + data[i].name    + ""%>><%= data[i].name     %></a></td>
<% } %>

很好,当我点击 ID 时,我在数据库中找到了我想要的 ID,但我也希望能够通过名称找到。

所以我试图改变路线:

    app.get('/names/:param', function(req, res) {
        var param = req.param("param");
        console.log(param);
        mongoose.model('Something').findOne(
            {
            id: param,
            name: param
            }, function(err, obj) {
                res.send(obj);
                console.log(obj);
            }
        );
    });

但正在返回任何内容,包括 ID 和名称

MongoDB 查询参数在默认情况下始终是逻辑条件 and。为了使用逻辑 $or 运算符:

    app.get('/admin/reservas/:param', function(req, res) {
        var param = req.param("param");
        console.log(param);
        mongoose.model('Something').findOne(
            {
                "$or": [
                    { id: param },
                    { name: param }
                ]
            }, function(err, obj) {
                res.send(obj);
                console.log(obj);
            }
        );
    });

$or 运算符采用查询文档数组来考虑条件。这是一个 "short circuit" 匹配,其中第一个评估为 true 的条件使语句为真。

如果不是这里的特定问题,至少那是正确的。请参阅 _id,它的 id 别名对于 MongoDB 和 Mongoose 都是一个特殊值。默认情况下,这将尝试 "cast" 到 ObjectID 类型,但如果提供的字符串无效,则它不能,例如 "fred"。

这将导致异常,因为提供了查询参数。所以底线规则是你不能 "mix types" 在 $or 条件下以这种方式使用无法从 String 转换的东西。您必须通过测试值以不同的方式 "logically" 它是什么:

    app.get('/admin/reservas/:param', function(req, res) {
        var param = req.param("param");
        console.log(param);

   var query = {};

       try {
           var id = mongoose.mongo.ObjectID(param);
           query = { "id": id };
       } catch {
           query = { "name": param };
       }

        mongoose.model('Something').findOne(
            query, function(err, obj) {
                res.send(obj);
                console.log(obj);
            }
        );
    });

这意味着查询现在的构建方式是 mongoose 将考虑要应用的模式 "types" 对其进行解析然后没有错误,因为查询哪个字段的决定是在别处做出的。

当然,您也可以 "bypass" mongoose 方法行为,只使用原始驱动程序:

    app.get('/admin/reservas/:param', function(req, res) {
        var param = req.param("param");
        console.log(param);

        var id ="";

        try {
            id = mongoose.mongo.ObjectID(param);
        }

        mongoose.model('Something').collection.findOne(
            {
                "$or": [
                    { id: id },
                    { name: param }
                ]
            }, function(err, obj) {
                res.send(obj);
                console.log(obj);
            }
        );
    });

但是当然你需要自己进行类型转换,而不仅仅是 "testing" 否则即使是代表 ObjectID 的正确 "String" 值也无法工作。