Как выполнить поиск в базе данных MySQL с помощью массива строк?

#mysql #node.js

#mysql #node.js

Вопрос:

Это для бота Discord с NodeJS. Итак, у меня есть массив с именем args, который содержит аргументы, переданные пользователем при вызове команды. Что я хочу сделать, это выполнить поиск в базе данных по столбцу «Симптомы» и вернуть эти строки обратно. Но мне нужны только те, которые содержат слова в массиве. Например, если я отправлю команду «Боль, ангина», бот затем превратит это в массив. Затем я хочу, чтобы он выполнял поиск в базе данных по всему, что содержит эти слова, но это не обязательно должно быть в таком порядке, например, строка может содержать «Боль в горле, головная боль, болевой синдром», и он все равно выберет это, потому что оно, по крайней мере, содержит эти два аргумента.

Я пробовал следующие решения:

SELECT * FROM diagnose WHERE Symptoms IN (${args})

Но это возвращает строку, только если в ней есть только одно слово (это слово — cough и ничего больше, если бы было другое слово, оно бы не отображалось).

SELECT * FROM diagnose WHERE Symptoms LIKE '%${args}%'

Тот же результат, что и выше.

Мой код:

 if (!message.content.startsWith(prefix) || message.author.bot) return;
    const args = message.content.slice(prefix.length).split(' ');
    const command = args.shift().toLowerCase();

if(command === `symptoms`){
        if(!args.length){
            return message.channel.send("You didn't provide me any symptoms.");
        }
        var query = connection.query(`SELECT * FROM diagnose WHERE Symptoms LIKE '${args}'`);
        console.log(args1);
        query.on('error', function(err) {
            throw err;
        });
        query.on('fields', function(fields) {
            //console.log(fields);
        });
        query.on('result', function(row) {
            //console.log(row);
            message.channel.send(row.Outcome);
        });
    }
  

Ответ №1:

Самый простой способ, но не самый эффективный, для достижения этого:

 SELECT *
FROM diagnose
WHERE 'pain' IN Symptoms
  AND 'sore' IN Symptoms
  AND 'throath' IN Symptoms
  

Эффективным способом было бы создать другую таблицу со словами в столбце Симптомы, указывающими на диагноз. Допустим, мы уже создали и заполнили другую таблицу, например diagnoseWords, тогда вы могли бы сделать:

 SELECT DISTINCT *  
FROM diagnose d
INNER JOIN diagnoseWords w1 ON d.id=w1.id AND w1.word='pain' 
INNER JOIN diagnoseWords w2 ON d.id=w2.id AND w2.word='sore' 
INNER JOIN diagnoseWords w3 ON d.id=w3.id AND w3.word='throat' 
  

Конечно, для этого потребовались бы индексы, и это обмен пространства на время. Другие базы данных, в которых реализован оператор INTERSECT, такие как postgres и oracle, позволили бы вам сделать:

 SELECT * FROM diagnose d 
 INNER JOIN  diagnoseWords w ON d.id=w.id AND w.word='sore'
INTERSECT
SELECT * FROM diagnose d 
 INNER JOIN  diagnoseWords w ON d.id=w.id AND w.word='throat'
  

Другим подходом, который, как представляется, был бы полезен в вашем случае, был бы поиск на естественном языке mysql или просто поиск по логическому тексту.
Для работы обоих подходов требуется ПОЛНОТЕКСТОВЫЙ индекс.

Вы могли бы предоставить функцию «больше результатов», используя полнотекстовый поиск с расширением запроса

Комментарии:

1. Спасибо за ответ. Проблема в том, что это не будут одни и те же значения каждый раз, пользователи будут все время вводить разные значения.

2. Это тривиально: создайте инструкцию sql, динамически заменяющую значения переменных. Я сохранил значения для простоты.