首页 > 解决方案 > 在快速路由中使用 find() 时向我的 mongodb 添加过滤可能吗?如何?

问题描述

您好,我有这个使用异步的 GET 函数,它找到用户刚刚单击的特定“类别”猫鼬模式和另一个“工具”猫鼬模式(它只是在我的数据库中找到所有工具)并将它们都传输到渲染页面。

如果有一种方法可以向我的 Tool.find 添加某种过滤,我正在徘徊,因此它只会找到与用户刚刚单击的类别(Category.name)具有相同类别属性(Tool.category)的工具?

获取函数:

router.get("/catalog/:id", function (req, res, next) {
    let output = {
            category: [],
            tools: []
    };
    async.parallel([
            function (cb) {
                    Category.findById(req.params.id).exec(function (err, foundCategory) {
                            if (err || !foundCategory) {
                                    req.flash("error", "No category found.");
                                    return res.redirect("back");
                            } else {
                                    output.category = foundCategory;
                                    cb(null, foundCategory);
                            }
                    });
            },
            function (cb) {
                    Tool.find({}, function (err, foundTools) {
                            if (err || !foundTools) {
                                    req.flash("error", "No tools were found.");
                                    return res.redirect("back");
                            } else {
                                    output.tools = foundTools;
                                    cb(null, foundTools);
                            }
                    });
            }
    ], function done(err, results) {
            if (err) {
                    res.json(err.message);
            } else {
                    res.render("tools/catalog-items", {
                            category: output.category,
                            tools: output.tools
                    });
            }
    });

});

标签: javascriptmongodbexpressmongoosemongoose-schema

解决方案


你绝对可以做到这一点。您想要实现的是使第二个查询依赖于第一个查询的结果。

在这种情况下,async.parallel将无法正常工作,因为您需要先获得结果Category.findById

如果您有多个(超过 2 个)后续查询,我会建议您使用该async.waterfall方法。您可以在此处查看文档。

但是对于这种特殊情况,您可以像这样简单:

Category.findById(req.params.id, function (err, foundCategory) {
    if (err || !foundCategory) {
        req.flash("error", "No category found.");
        return res.redirect("back");
    }

    Tools.find({
        // As described in the question we filter by a `name` field
        // although in future you might consider creating an ObjectId reference
        category: foundCategory.name
    }, function (err, foundTools) {

        // As we applied filtering we might return an empty array of tools
        // instead of throwing an error
        if (err || !foundTools) {
            req.flash("error", "No tools were found.");
            return res.redirect("back");
        }

        res.render("tools/catalog-items", {
            category: foundCategory,
            tools: foundTools
        });
    });
});

您当然也可以进行排序。您只需要添加.sort({someProperty: 1}).exec(...). 请参阅此处的示例。


推荐阅读