Многопараметрический поиск с mysql и node.js - PullRequest
0 голосов
/ 05 марта 2020

Позвольте мне предисловие, сказав, что я очень новичок в SQL (и дизайне бэкэнда) в целом. Так что для тех, кто раздражен вопросами noob, пожалуйста, будьте осторожны.

ПРЕДПОСЫЛКИ:

Я пытаюсь создать базу данных тестов продуктов (сохраняя тестовые данные для всех наших продуктов), где я хочу, чтобы пользователь чтобы иметь возможность уточнить поиск, чтобы найти тестовые данные, которые они действительно хотят. Например, они могут начать с поиска всех продуктов определенного бренда, а затем уточнить его с типом продукта и / или уточнить с диапазоном дат, когда тест был выполнен.

ПРОБЛЕМА:

Мне трудно найти информацию о том, как реализовать многопараметрический поиск с 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 процедур, но передавал динамические c данные в "ОТ" пункт не представляется возможным. Пример: если у меня была процедура фирменного наименования и процедура типа продукта, я не знаю, как / если я могу передать результаты одной процедуры в предложение "FROM" другой, чтобы фактически уточнить поиск.

Одна идея состояла в том, чтобы создать таблицы с результатами в каждой из этих процедур и передать эти новые имена таблиц последующим процедурам, но это кажется мне неэффективным способом сделать это (Я ошибаюсь? полностью git способ сделать это?).

Я также изучаю создание строки запроса на стороне узла, которая бы разумно решала, какие критерии поиска были заданы внешним интерфейсом, и выяснила где поставить SQL И, а также СОЕДИНЕНИЕ и что-нибудь. Приведенный ниже пример на самом деле работает, но кажется, что он может быть ужасно быстрым, поскольку я добавляю больше критериев поиска вместе с 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, чтобы я мог Можно выбрать процедуры, применимые к критериям поиска?
    • Является ли создание таблиц результатов в процедуре и передача этих новых имен таблиц другим процедурам разумным способом сделать это?
  • Построение запроса с нуля в узле работает, но кажется раздутым. Есть ли лучший способ сделать это?
  • Поиск в Google "многопараметрического поиска mysql nodejs" не дает полезных результатов для моего вопроса, т.е. Я не задаю правильный вопрос. Какой правильный вопрос? Что мне нужно исследовать?

1 Ответ

1 голос
/ 05 марта 2020

Один из вариантов - использовать 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);
...