【问题标题】:Find JSON object path by boolean value from MySQL通过 MySQL 中的布尔值查找 JSON 对象路径
【发布时间】:2020-03-22 19:55:03
【问题描述】:

如何找到属性为"is_true": true 的对象的路径?

数据列中的 JSON:

[
  {
    "myData": {},
    "is_true": true
  },
  {
    "myData": {},
    "is_true": false
  },
  {
    "myData": {},
    "is_true": false
  }
]

尝试失败:

SELECT JSON_SEARCH(data, "all", true) AS booleanObject FROM my_table

还有……

SELECT JSON_SEARCH(data, "all", "true") AS booleanObject
SELECT JSON_SEARCH(data, "all", "%true%") AS booleanObject
SELECT JSON_SEARCH(data, "all", true) AS booleanObject
SELECT JSON_SEARCH(data, "all", 1) AS booleanObject
SELECT JSON_SEARCH(data, "all", true, NULL, "$") AS booleanObject

等等

【问题讨论】:

  • 您对此的预期输出是什么。
  • 预期输出:如果搜索“真”$[0].is_true 否则路径包含“假”值$[1].is_true, $[2].is_true 等。

标签: mysql sql json


【解决方案1】:

不幸的是,JSON_SEARCH 似乎只搜索字符串值。你可以使用蛮力:

SELECT x.i, JSON_EXTRACT(data, CONCAT('$[', x.i, ']')) AS obj
FROM t
INNER JOIN (
    SELECT 0 AS i UNION ALL
    SELECT 1 UNION ALL
    SELECT 2 UNION ALL
    SELECT 3
) AS x ON x.i < JSON_LENGTH(t.data)
WHERE JSON_EXTRACT(data, CONCAT('$[', x.i, '].is_true')) = true

如果您使用的是 MySQL 8,那么更优雅的选择是使用JSON_TABLE:

SELECT x.i, x.obj
FROM t
CROSS JOIN JSON_TABLE(t.data, '$[*]' COLUMNS(
  i FOR ORDINALITY,
  is_true BOOLEAN PATH '$.is_true',
  obj JSON PATH '$'
)) AS x
WHERE x.is_true = true

Demo on db<>fiddle

【讨论】:

    【解决方案2】:

    这是一个不直观的选项,您应该小心性能问题:

    SELECT
      JSON_SEARCH(
        REPLACE(
          REPLACE(
            REPLACE(
              JSON_EXTRACT(@`json`, '$[*].is_true'),
              ', ',
              '", "'
            ),
            '[',
            '["'
          ),
          ']',
          '"]'
        ), 'all', 'true') `positions`;
    

    见dbfiddle。

    【讨论】:

      【解决方案3】:
      SELECT JSON_EXTRACT(is_true, "$[0].is_true") AS is_true
      FROM table
      WHERE JSON_EXTRACT(is_true, "$[0].is_true") = 1
      

      【讨论】:

      • 我尝试了相同的查询,但表中有超过 500k 行,我没有等待响应。看起来这个查询太慢了。搜索 1 行需要 0.007 秒,500.000 * 0.007 = 3500 秒...我也想以这种方式找到真实值:JSON_EXTRACT(is_true, "$[*].is_true") = true 但此查询在使用 * 符号时不允许查找数据。跨度>
      • 你试过 JSON_EXTRACT(is_true, "$.is_true") = true。并且不要返回所有数据使用限制和偏移量,以便您可以分页。
      • 如果我搜索JSON_EXTRACT(data, "$[*].is_true"),它会返回行“[true, false, false, false....]”,否则如果我搜索JSON_EXTRACT(data, "$[*].is_true") = true,它总是返回0。但是,如果我搜索某个字符串值 JSON_SEARCH(JSON_EXTRACT(data, "$[*].string_value"), "all", "myString") 一切都是正确的,并且我收到的结果包含指向属性的路径集合,例如:["$[1]", "$[2]", "$[3]", "$[4]", "$[5]", "$[6]"....] 如果我搜索 is_true 属性,我总是会收到 NULL 结果。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-10
      • 1970-01-01
      • 1970-01-01
      • 2017-06-04
      • 1970-01-01
      • 2013-06-22
      相关资源
      最近更新 更多