mySQL: выберите строки, если текстовый столбец содержит элемент в черном списке - PullRequest
0 голосов
/ 03 апреля 2020

Я пытаюсь создать запрос, который может выбрать все записи из моей базы данных, которые содержат тег из черного списка, если пост не содержит тег из белого списка. Теги хранятся в текстовом столбце (т. Е. " tag1 tag2 tag3 ").

Возьмем, к примеру, этот псевдокод:

let whitelist = ['tag1', 'tag3', 'tag5'];
let blacklist = ['tag2', 'tag4', 'tag6'];

connection.query('SELECT * FROM `posts` WHERE `tags` CONTAINS BLACKLIST TAG AND NOT WHITELIST TAG;', function (err, results) {
    // Returns all posts that have a blacklisted tag unless the post contains a tag on the whitelist
});

Можно ли сгенерировать запрос с использованием содержимого белого списка и черный список для выбора сообщений, содержащих черный список, если они не содержат белый список?

1 Ответ

1 голос
/ 03 апреля 2020

Лучшее, что можно сделать здесь, это правильно нормализовать tags и не иметь списка значений, разделенных пробелами. Однако если вы застряли в этом формате, вы можете использовать регулярное выражение для поиска одного из значений в каждом массиве в списке тегов. Вы можете сделать регулярные выражения из массивов whitelist и blacklist, используя:

whitelist_regex = ' ' + whitelist.join(' | ') + ' ';
blacklist_regex = ' ' + blacklist.join(' | ') + ' ';

Тогда ваш запрос станет

connection.query('SELECT * FROM `posts` WHERE `tags` RLIKE ? AND `tags` NOT RLIKE ?', 
                 [ blacklist_regex, whitelist_regex ],
                 function (err, results) {
                      // ...
                 });

Обновление

Если поле тегов выглядит как серия разделенных пробелами значений формы tagtype:tag, вы можете изменить два регулярных выражения в соответствии с этим форматом:

whitelist_regex = ':' + whitelist.join(' |:') + ' ';
blacklist_regex = ':' + blacklist.join(' |:') + ' ';
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...