Mysql 5.7.27: поиск в массиве JSON - PullRequest
0 голосов
/ 18 апреля 2020

Я пытаюсь выяснить, как искать столбец массива JSON таблицы. Я нашел этот вопрос Stackoverflow , но мне неясно, как работает JSON_SEARCH.

В ответах люди, похоже, дают JSON_SEARCH прямые данные для поиска:

SELECT JSON_SEARCH('["1","2","3","4","5"]', 'one', "2")

Но так как я делаю поиск, у меня фактически нет массива ["1","2","3","4","5"]

Я создаю поисковый запрос примерно так:

SELECT * FROM `server_list` 
WHERE
    `server_version` LIKE '%%'
AND
    `server_name` LIKE '%%'
AND 
    `server_slots` > 1500
AND
    `server_slots` < 4000

Как я могу также искать определенные теги c в этом же запросе? Что-то вроде:

AND
    JSON_SEARCH(`server_tags`, ['1', '2', '3'])

Где server_tags - столбец, который я хочу найти, и ['1', '2', '3'] - это несколько тегов, которые я хочу найти.

Редактировать: Я только что понял JSON столбцы - это просто строки, что позволяет мне сделать это:

SELECT * FROM `lista_server` 
    `server_tags` LIKE '%value%'
    OR `server_tags` LIKE '%value2%'

Что-то не так с этим методом?

Ответы [ 3 ]

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

Если вы хотите проверить наличие любых тегов, вы можете OR собрать вместе результаты JSON_SEARCH для каждого из них:

AND (JSON_SEARCH(server_tags, 'one', '1') IS NOT NULL OR
     JSON_SEARCH(server_tags, 'one', '2') IS NOT NULL OR
     JSON_SEARCH(server_tags, 'one', '3') IS NOT NULL
    )

Чтобы проверить, что они все существуют, просто AND совместный поиск:

AND (JSON_SEARCH(server_tags, 'one', '1') IS NOT NULL AND
     JSON_SEARCH(server_tags, 'one', '2') IS NOT NULL AND
     JSON_SEARCH(server_tags, 'one', '3') IS NOT NULL
    )

Примечание: попытка поиска по тексту, скорее всего, не будет работать, возможно, значения в массив JSON не будет в том же порядке, что и в вашей тестовой строке (например, ['1', '2'] не будет соответствовать ['2', '1']), или длина массива JSON может отличаться (например, ['1', '2'] won ' t match ['1', '2', '3']) et c.

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

Проблема с этим методом:

SELECT * FROM `lista_server` 
WHERE `server_tags` LIKE '%value%'
OR `server_tags` LIKE '%value2%'

В том, что сопоставление по шаблону ничего не знает о границах значений.

Пример:

INSERT INTO lista_server SET server_tags = '112,456,789';

Затем найдите тэг '1', используя ваш метод:

SELECT * FROM lista_server WHERE server_tags LIKE '%1%'

Это соответствует! Поскольку значение 112 соответствует значению «% 1%».

Это одна из многих причин, по которым трудно хранить список значений, разделенных запятыми , когда вы хотите искать отдельные значения в список.

Использование JSON просто проблематично, если использовать список через запятую.

Вместо этого, если вы хотите искать отдельные значения, вам нужно нормализовать таблицу. Сохранение тегов по одному на строку в дочерней таблице:

INSERT INTO lista_server_tags (lista_server_id, tag) 
VALUES (1234, '112'), (1234, '456'), (1234, '789');

Затем вы можете искать их как отдельные значения:

SELECT l.* FROM lista_server AS l 
JOIN lista_server_tags AS t ON (l.id = t.lista_server_id)
WHERE t.tag = '112'

И вы уверены, что они не будут совпадать неправильно. Он будет соответствовать только одному значению, а не значениям, которые по совпадению содержат искомую строку. Вы также можете использовать индекс, чтобы ускорить поиск. Вы можете добавить неограниченное количество тегов. И много других преимуществ.

0 голосов
/ 18 апреля 2020

Абсолютно нет ничего плохого в том, что вы сделали, просто убедитесь, что ваш поисковый запрос чист, чтобы предотвратить (SQL Инъекция).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...