【问题标题】:Mysql 5.7.27: Searching JSON arrayMysql 5.7.27:搜索 JSON 数组
【发布时间】:2020-04-18 12:36:46
【问题描述】:

我试图弄清楚如何搜索表的 JSON 数组列。我找到了this Stackoverflow question,但我不清楚 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

如何在同一个查询中搜索特定标签?顺带一提:

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%'

这个方法有什么问题吗?

【问题讨论】:

    标签: mysql sql search


    【解决方案1】:

    如果你想检查任何个标签是否存在,你可以ORJSON_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']不会匹配['1', '2', '3'])等等。

    【讨论】:

    • 太棒了,感谢您的帮助。根本不知道如何使用 JSON_SEARCH!
    • @Eight 不用担心 - 我很高兴能帮上忙。
    【解决方案2】:

    这个方法的问题:

    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%' 匹配。

    当您想在列表中搜索单个值时,这是many reasons it's trouble to store a comma-separated list of values 之一。

    使用 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'
    

    而且您确定它不会匹配错误。它只会匹配一个值,而不是巧合包含您搜索的字符串的值。您还可以使用索引来帮助加快搜索速度。您可以添加无限数量的标签。还有许多其他好处。

    【讨论】:

    【解决方案3】:

    您所做的绝对没有问题,只需确保您的搜索词是干净的以防止(SQL 注入)。

    【讨论】:

      猜你喜欢
      • 2021-06-07
      • 1970-01-01
      • 1970-01-01
      • 2023-02-24
      • 2019-08-02
      • 2019-09-12
      • 2020-06-01
      • 1970-01-01
      相关资源
      最近更新 更多