结合 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 整数 json 数组中的整数值