结合 JSON_SEARCH 和 JSON_EXTRACT 得到我:“无效的 JSON 路径表达式。”

Posted

技术标签:

【中文标题】结合 JSON_SEARCH 和 JSON_EXTRACT 得到我:“无效的 JSON 路径表达式。”【英文标题】:Combining JSON_SEARCH and JSON_EXTRACT get me: "Invalid JSON path expression." 【发布时间】:2017-03-25 06:08:00 【问题描述】:

我有一个名为“campaigns”的表。其中一列名为“filter_apps”,他的类型是 JSON

我有文件行,它们只包含这样的标记数组:

["be3beb1fe916ee653ab825fd8fe022", "c130b917983c719495042e31306ffb"]
["4fef3f1999c78cf987960492da4d2a"]
["106c274e319bdeae8bcf8daf515b1f"]
["2521f0df6cffb7487d527319674cf3"]
["c130b917983c719495042e31306ffb"]

例子:

SELECT JSON_SEARCH(filter_apps, 'one', 'c130b917983c719495042e31306ffb') FROM campaigns;

结果:

"$[1]"
null
null
null
"$[0]"

现在一切都正确,匹配的列又回来了。如果我做一个测试,我可以证明它:

SELECT JSON_EXTRACT(filter_apps, '$[1]') FROM campaigns;

结果

"c130b917983c719495042e31306ffb"
null
null
null
null

所以此时我认为我可以使用 JSON_EXTRACT 提取值,我的查询:

SELECT JSON_EXTRACT(filter_apps, JSON_SEARCH(filter_apps, 'one', 'c130b917983c719495042e31306ffb')) FROM campaigns;

这导致我出错:

"[42000][3143] JSON 路径表达式无效。错误在字符位置 1 附近。"

【问题讨论】:

在挖掘了更多找到解决方案之后,我只是将 JSON_SEARCH 包装在 JSON_UNQUOTE 方法中! 【参考方案1】:

解决方案

就这么简单:

SELECT JSON_EXTRACT(filter_apps, JSON_UNQUOTE(JSON_SEARCH(filter_apps, 'one', 'c130b917983c719495042e31306ffb'))) FROM campaigns;

问题已解决!我将 JSON_SEARCH 包装在 JSON_UNQUOTE 方法中!

一点提示,我在这里找到了解决方案:https://dev.mysql.com/doc/refman/5.7/en/json-function-reference.html

【讨论】:

好问题。我在这里做了同样的事情,并且像一个魅力一样工作。不幸的是,我是在自己在这里解决之后才发现这个问题的。另外,在我的情况下,我必须一起使用REPLACE 函数来更改从JSON_SEARCH 返回的“路径”的最后一部分。 非常感谢您的回复。我已经为此苦苦挣扎了几个月和几个月,但没有找到解决方案。我什至在多个地方读到不允许使用变量作为路径表达式。这是一个巨大的发现,有助于在 MySQL(特别是 MySQL 8 以下的版本)中使用 JSON。再次感谢! 只是好奇当使用all 搜索模式而不是one 时,可以采取什么技巧将结果从JSON_SEARCH 传递到JSON_EXTRACT。 谢谢!有点反直觉(在 MySQL 方面);在放弃并来到这里之前,我刚刚尝试过 JSON_QUOTE。 即使我很想知道如果我们使用 all 而不是 one 的解决方法是什么。示例:从广告系列中选择 JSON_EXTRACT(filter_apps, JSON_UNQUOTE(JSON_SEARCH(filter_apps, 'all', 'c130b917983c719495042e31306ffb')));【参考方案2】:

我花了几个小时,因为我的 JSON 对象要复杂得多,但我找到了“全部”选项的解决方案。

SELECT *,
    REPLACE(REPLACE(LTRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(filter_apps, ',', n), ',', -1)), '[', ''), ']', '') AS all_json
FROM (
    SELECT *, JSON_EXTRACT(filter_apps, JSON_UNQUOTE(JSON_SEARCH(filter_apps, 'all', 'c130b917983c719495042e31306ffb'))) AS hit
    FROM campaigns
) AS t
JOIN (SELECT  @N := @N +1 AS n FROM campaigns, (SELECT @N:=0) dum LIMIT 10) numbers
      ON CHAR_LENGTH(filter_apps) - CHAR_LENGTH(REPLACE(filter_apps, ',', '')) >= n - 1
WHERE hit IS NOT NULL;
    
# for the "JOIN-FROM" use a table that has more or equal entries than the length of your longest JSON array
# make sure the "JOIN-LIMIT" is higher or equal than the length of your longest JSON array

查询说明:

    内部选择: 使用 JSON_SEARCH Option 'all' 询问的主要选择 加入: a)选择表“数字”: 创建一个表,其中包含从 1 到用户定义的 LIMIT 的数字。 比较SQL SELECT to get the first N positive integers b) JOIN ON 与外部 SELECT SUBSTRING_INDEX 结合: 将定义的数组列“filter_apps”拆分为数组元素的数量。请注意用户定义的 2)a) 限制必须等于或大于要拆分的最长数组。比较SQL split values to multiple rows 外部 SELECT 的 REPLACE 和 LTRIM: 用于删除前一个数组的剩余括号和空格 WHERE 子句: 仅显示 Inner SELECT 的匹配结果

【讨论】:

请解释它如何与您的解决方案一起工作,以便人们可以轻松理解它。

以上是关于结合 JSON_SEARCH 和 JSON_EXTRACT 得到我:“无效的 JSON 路径表达式。”的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 中的 JSON_SEARCH

使用 mysql JSON_SEARCH:为啥我必须引用数字?

MYSQL 触发器:JSON_SEARCH 整数 json 数组中的整数值

使用 MySQL Json_search 函数使用不区分大小写的搜索获取 JSON 数据中值的路径表达式

如何在 laravel 中执行复杂的 mysql 查询

MySQL - 搜索 JSON 数据列