【问题标题】:How to search JSON data in MySQL?如何在 MySQL 中搜索 JSON 数据?
【发布时间】:2015-08-05 07:59:39
【问题描述】:

我已经在 mysql DB 中插入了 json encoded 数据类型的记录,现在我必须在 json encoded 数据中进行搜索,但我无法使用以下 MySql 查询获取正确的数据。

SELECT  `id` ,  `attribs_json` 
FROM  `products` 
WHERE  `attribs_json` REGEXP  '"1":{"value":[^"3"$]'

查询结果键等于“1”,值是除“3”以外的任何值

我的数据是:

{"feature":{"1":{"value":"["2","3"]"},
            "2":{"value":["1"]},
            "5":{"value":""},
            "3":{"value":["1"]},
            "9":{"value":""},
            "4":{"value":"\u0633\u0627\u062a\u0646"},
            "6":{"value":""},
            "7":{"value":""},
            "8":{"value":""}
           },
"show_counter":"0",
"show_counter_discount":""
}}

【问题讨论】:

  • 我想向我展示所有记录,键是“1”,“3”是值之一
  • 解释“不能”!你得到什么输出?
  • 我想显示特征 id 为 1 且特征值之一为 3 的所有产品特征是这样的数组:feature = array( 1=>array(1,2,3),2= >array(1,4,7) ) 我正在使用 jsonencode 将其保存到数据库中
  • 这听起来是个糟糕的主意。将要过滤的数据拆分为它们自己的列,然后仅使用 JSON 内容获取您不会过滤的其他信息,您会受益。
  • 为什么想法很糟糕。这样做有什么缺点?

标签: mysql json mysql-json


【解决方案1】:

如果你有 MySQL 版本 >= 5.7,那么你可以试试这个:

SELECT JSON_EXTRACT(name, "$.id") AS name
FROM table
WHERE JSON_EXTRACT(name, "$.id") > 3

输出:

+-------------------------------+
| name                          | 
+-------------------------------+
| {"id": "4", "name": "Betty"}  | 
+-------------------------------+


详情请查看 MySQL 参考手册:
https://dev.mysql.com/doc/refman/5.7/en/json-search-functions.html

【讨论】:

  • 重要提示:json_encode 将整数保存为双引号值(因此 - string 类型)。如果搜索相等,则必须使用JSON_EXTRACT(name, "$.id") = "4" 而不是JSON_EXTRACT(name, "$.id") = 4
  • > 在 MySQL 5.7.9 及更高版本中, -> 运算符在与两个参数一起使用时用作 JSON_EXTRACT() 函数的别名然后您的示例变为:SELECT name->"$.id" as name FROM table WHERE name->"$.id" > 3 就个人而言,我发现这更容易跟随。
  • 我猜 MySQL 4.8.5 版不可能?那么我将不得不研究一个 PHP 解决方案。
【解决方案2】:

如果您使用的是 MySQL 最新版本,以下可能有助于满足您的要求。

select * from products where attribs_json->"$.feature.value[*]" in (1,3)

【讨论】:

  • 最新版本的mysql是什么意思?支持哪个版本?
  • 什么版本的IN算子支持?
  • MySQL 5.5 及以上版本@Sérgio
  • mysql --version mysql Ver 14.14 Distrib 5.7.18,适用于 Linux (x86_64) 警告:(1235,“此版本的 MySQL 尚不支持‘IN 运算符中 JSON 的比较’” )
【解决方案3】:
  1. 在数据库中存储 JSON 违反了第一范式。

    您能做的最好的事情是规范化特征并将其存储在另一个表中。然后,您将能够使用具有更好外观和性能的连接查询。 您的 JSON 甚至类似于表格。

  2. Mysql 5.7 具有内置 JSON 功能:
    http://mysqlserverteam.com/mysql-5-7-lab-release-json-functions-part-2-querying-json-data/

  3. 正确的模式是:

    WHERE  `attribs_json` REGEXP '"1":{"value":[^}]*"3"[^}]*}'
    

    [^}] 将匹配除} 之外的任何字符

【讨论】:

  • 同意上面的#1,但有时您会遇到在设计时表上的几个字段名称是未知的情况。在这种情况下,您可以通过在表上使用 JSON 数据类型来混合关系和 nosql 数据存储。
  • 至第 1 点,问题不在于架构设计,而在于将数据存储提取为 json。第 2 点是答案的链接,第 3 点很脆弱,如果 json 发生变化,它可能会失败。
  • 我可以建议 JSON_EXTRACT(attribs_json, '$.feature."1".value') 将在键“1”处获得特征的值
【解决方案4】:

我使用这个查询

SELECT id FROM table_name WHERE field_name REGEXP '"key_name":"([^"])key_word([^"])"';
or
SELECT id FROM table_name WHERE field_name RLIKE '"key_name":"[[:<:]]key_word[[:>:]]"';

我用它来搜索部分值的第一个查询。第二个查询我用它来搜索确切的单词。

【讨论】:

  • MySQL 5.7 终于有了 JSON 支持。然而,该更新成为主流需要一段时间,但作为快速参考,这是提取一些信息的简单方法。谢谢!
  • 它对我不起作用。我的结构类似于{"images":"-"}SELECT id FROM parsed_redfin WHERE data` RLIKE '"images":"[[:<:>:]]"';` 没有返回任何东西
【解决方案5】:

对于Mysql8->

查询:

SELECT properties, properties->"$.price" FROM book where isbn='978-9730228236' and  JSON_EXTRACT(properties, "$.price") > 400;

数据:

mysql> select * from book\G;
*************************** 1. row ***************************
id: 1
isbn: 978-9730228236
properties: {"price": 44.99, "title": "High-Performance Java Persistence", "author": "Vlad Mihalcea", "publisher": "Amazon"}
1 row in set (0.00 sec)

【讨论】:

    【解决方案6】:

    请照做。

    SELECT * FROM `products` 
        WHERE JSON_UNQUOTE(JSON_EXTRACT(`attribs_json`, '$.value')) LIKE '%X%'
    

    【讨论】:

      【解决方案7】:

      如果 MySQL 版本

      SELECT fields
      FROM table
      WHERE field_json LIKE '%"key":"70"%';
      

      // 70 = 价值

      【讨论】:

        【解决方案8】:
        SELECT
            country.NAME AS 'country_name',
            city.NAME AS 'city_name',
            city.district,
            city.info,
            JSON_EXTRACT( city.info, "$.Population" ) AS 'formated_population' 
        FROM
            city
            INNER JOIN country ON city.CountryCode = country.
            CODE INNER JOIN countrylanguage ON country.CODE = countrylanguage.CountryCode 
        GROUP BY
            city.NAME,
            city.district,
            country.NAME;
        
        ORDER BY
            country.NAME ASC;
        

        【讨论】:

          【解决方案9】:

          我觉得……

          搜索部分值:

          SELECT id FROM table_name WHERE field_name REGEXP '"key_name":"([^"])*key_word([^"])*"';
          

          搜索确切的单词:

          SELECT id FROM table_name WHERE field_name RLIKE '"key_name":"[[:<:]]key_word[[:>:]]"';
          

          【讨论】:

          • 这与已经存在的答案之一完全相同。瓦伦蒂诺说的话没必要重复 :)
          【解决方案10】:

          适用于所有 MySQL(和 5.7)

          SELECT LOWER(TRIM(BOTH 0x22 FROM TRIM(BOTH 0x20 FROM SUBSTRING(SUBSTRING(json_filed,LOCATE('\"ArrayItem\"',json_filed)+LENGTH('\"ArrayItem\"'),LOCATE(0x2C,SUBSTRING(json_filed,LOCATE('\"ArrayItem\"',json_filed)+LENGTH('\"ArrayItem\"')+1,LENGTH(json_filed)))),LOCATE(0x22,SUBSTRING(json_filed,LOCATE('\"ArrayItem\"',json_filed)+LENGTH('\"ArrayItem\"'),LOCATE(0x2C,SUBSTRING(json_filed,LOCATE('\"ArrayItem\"',json_filed)+LENGTH('\"ArrayItem\"')+1,LENGTH(json_filed))))),LENGTH(json_filed))))) AS result FROM `table`;
          

          【讨论】:

            猜你喜欢
            • 2018-09-17
            • 1970-01-01
            • 1970-01-01
            • 2021-04-04
            • 1970-01-01
            • 2019-08-02
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多