【问题标题】:Multi-parameter search with mysql and node.js使用 mysql 和 node.js 进行多参数搜索
【发布时间】:2020-03-05 17:29:30
【问题描述】:

首先让我先说我对 SQL(和后端设计)非常陌生。所以对于那些对菜鸟问题感到恼火的人,请温柔一点。

背景:

我正在尝试构建一个产品测试数据库(存储我们所有产品的测试数据),我希望用户能够在其中优化搜索以找到他们真正想要的测试数据。例如,他们可能首先搜索某个品牌的所有产品,然后使用产品类型对其进行优化,和/或使用测试完成的日期范围对其进行优化。

问题:

我很难找到有关如何使用 mysql 和 node.js 实现多参数搜索的信息。我知道您可以在纯 SQL 语法中进行嵌套查询和连接等,但我不太清楚如何从 node.js 执行此操作,尤其是在不能保证使用某些搜索条件时。

例如:

CREATE PROCEDURE `procedureName`(
    IN brandname VARCHAR(20),
       producttype VARCHAR(30))
BEGIN
    SELECT * FROM products
    WHERE brand = brandname
    AND product_type = producttype;
END

我知道如何将数据从 node.js 传递到这个过程,但是如果用户没有指定产品类型怎么办?有没有办法取消这部分查询?就像是: AND product_type = ALL;

我的尝试:

我还研究了嵌套多个 SQL 过程,但将动态数据传递给“FROM”子句似乎是不可能的。例如:如果我有一个品牌程序和一个产品类型程序,我不知道如何/是否可以将结果从一个程序传递到另一个程序的“FROM”子句以实际优化搜索。

一个想法是在每个过程中创建带有结果的表,并将这些新表名称传递给后续过程,但这让我觉得这样做的效率很低(我错了吗?这是一种完全合法的方式这样做?)。

我还在考虑在节点端构建一个查询字符串,该字符串可以智能地决定前端指定了哪些搜索条件,并找出将 SQL AND 和 JOIN 以及什么不放在哪里。下面的示例确实有效,但是当我向其他表添加更多搜索条件以及 JOINS 时,这似乎会很快变得难看。

// Build a SQL query based on the parameters in a request URL
// Example request URL: http://localhost:3000/search?brand=brandName&type=productType
function qParams(req) {
    let q = "SELECT * FROM products WHERE ";
    let insert = [];
    if(req.query.brand) {
        brandname = req.query.brand; // get brandname from url request
        q = q + `brand = ?`, // Build brandname part of WHERE clause
        insert.push(brandname); // Add brandname to insert array to be used with query.
    };
    if(req.query.type) {
        productType = req.query.type; // get product type from url request
        insert.length > 0 ? q = q + ' AND ' : q = q; // Decide if this is the first search criteria, add AND if not.
        q = q + 'product_type = ?'; // Add product_type to WHERE clause
        insert.push(productType); // Add product_type variable to insert array.
    }
    // Return query string and variable insert array
    return {
        q: q, 
        insert: insert
    };
};

// Send Query
async function qSend(req, res) {
    const results = await qParams(req); // Call above function, wait for results

    // Send query string and variables to MySQL, send response to browser.
    con.query(results.q, results.insert, (err, rows) => {
        if(err) throw err;
        res.send(rows);
        res.end;
    })
};

// Handle GET request
router.use('/search', qSend);

简洁的问题:

  • 我是否可以构建 1 个 SQL 过程,将所有搜索条件作为变量,如果不使用某些条件,则从 node.js 中取消这些变量?
  • 有没有办法嵌套多个 MySQL 过程,以便我可以选择适用于搜索条件的过程?
    • 在一个过程中创建结果表并将这些新表名称传递给其他过程是一种合理的方法吗?
  • 在节点中从头开始构建查询是有效的,但它似乎臃肿。有没有更好的方法来做到这一点?
  • 谷歌搜索“多参数搜索 mysql nodejs”对我的问题没有产生有用的结果,即 我没有问正确的问题。什么是正确的问题? 我需要研究什么?

【问题讨论】:

    标签: mysql sql node.js search where-clause


    【解决方案1】:

    一种选择是使用coalesce()

    SELECT p.* 
    FROM products p
    WHERE 
        p.brand = COALESCE(:brandname, p.brand)
        AND p.product_type = COALESCE(:producttype, p.producttype);
    

    对参数进行显式null 检查可能更有效:

        SELECT p.* 
    FROM products p
    WHERE 
        (:brandname IS NULL OR p.brand = :brandname)
        AND (:producttype IS NULL OR p.product_type = :producttype);
    

    【讨论】:

    • 这完美地回答了我的第一个问题。我可以有 1 个 SQL 过程,它处理空值。在 node.js 中,我的查询函数现在看起来像:function qSend(req,res){ const brand = req.query.brand ? req.query.brand : null; const type = req.query.type ? req.query.type : null ; const q = "CALL procedureName(?,?)"; console.log(brand); con.query(q, [brand,type], (err,rows) => { res.send(rows); }); res.end };
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多