【问题标题】:How use dynamic routes to find people in my mongoose database with node.js如何使用动态路由在我的 mongoose 数据库中使用 node.js 查找人员
【发布时间】:2015-03-02 15:08:26
【问题描述】:
    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 时,我会在 db 中找到我想要的 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 和名称

【问题讨论】:

  • 不太确定您在这里追求什么,一些示例数据可能有助于解释更多信息。但是“id”和“name”属性不可能具有相同的值。也许您只是在寻找“名称”并复制您尚未理解的代码以从查询中删除“id”。否则没有真正看到这一点,因为“id”必须是唯一的。还是您的意思是“id”“name”,无论哪个匹配?
  • 对不起,我的英语不好...我希望能够在我的数据库中找到匹配的 id 或名称...

标签: express mongoose mongodb-query


【解决方案1】:

默认情况下,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 运算符采用查询文档数组来考虑条件。这是一个“短路”匹配,其中评估为true 的第一个条件使语句为真。

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

在提供查询参数时,这将导致异常。因此,底线规则是您不能以这种方式在 $or 条件中“混合类型”与无法从String 转换的内容。您必须通过测试值以不同的方式“逻辑地”执行此操作 它是什么:

    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 会考虑要应用的架构“类型”来解析它,然后没有错误,因为查询哪个字段的决定是在其他地方做出的。

当然,您也可以“绕过”猫鼬方法的行为,只使用原始驱动程序:

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

当然,您需要自己进行类型转换,而不仅仅是为了“测试”,否则即使是代表ObjectID 的正确“字符串”值也不起作用。

【讨论】:

  • 奇怪,同样的效果..我不能同时使用这两个,如果我去掉id,我只能通过名字找到..我正在处理你的代码..
  • @FátimaAlves 是的,有一个可能值得更好解释的原因。 ObjectId 类型的字段在这里是一种特殊情况,代码将无法尝试转换说“fred”,这不是有效的ObjectId 值。不过可以与任何其他“字符串”字段一起使用。
  • 你是对的,看 -> ErrorCastError: Cast to ObjectId failed for value "Fatima" at path "_id"
  • @FátimaAlves 我添加了代码来解释现在如何做。正如我所说,“类型转换”是这种情况下的问题,但在两个“字符串”字段上,$or 的标准应用程序是正常的。
  • 非常感谢@NeilLunn 的帮助和解释!! :)
猜你喜欢
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
  • 2021-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-15
  • 2023-03-08
相关资源
最近更新 更多