【问题标题】:Matching entire contents of a MySQL JSON column匹配 MySQL JSON 列的全部内容
【发布时间】:2018-10-27 09:35:31
【问题描述】:

如何匹配整个 MySQL JSON 列的内容?

例如

SELECT COUNT(id) as matches 
FROM my_table
WHERE my_table.settings = '{ "color": "red", "location": "Australia", "flavour": "cheese" }'

其中 settings 是 JSON 列类型。问题是当我在字段中存储 JSON 时,键的排列方式不同。

上面会产生matches === 0,而实际上有很多匹配项。

【问题讨论】:

  • 我知道 MySQL 现在支持 JSON,但老实说,将序列化数据(这就是 JSON)存储在单个列中仍然不是一个好主意,因为从仅包含 SQL 的序列化列令人头疼。是否可以重构您的数据库架构,以便可以以更容易查询的方式存储这些数据(例如额外的颜色、位置和风味列,或者作为依赖表中的键和值)?
  • 不 - 是的 - 虽然适应非常频繁变化的方案的成本更高
  • 也许值得考虑使用不同的非 SQL 数据库?像 Mongo 或 Couch 之类的东西?
  • 再一次,与将实际解决方案(见下文)与我们的 ACTUAL 主存储引擎集成在一起相比,运营开销几乎不值一提。您能认真地想象仅仅因为一张表上的一列而迁移整个应用程序吗?我的朋友是荒谬的本质。

标签: php mysql json laravel database-design


【解决方案1】:

答案是使用JSON_CONTAINS函数。

SELECT COUNT(id) as matches 
FROM my_table
WHERE JSON_CONTAINS(my_table.settings, '{ "color": "red", "location": "Australia", "flavour": "cheese" }')

这适用于您正在搜索 JSON 的用例,其中您 不知道结构,而 JSON 您不知道结构

在 Laravel Eloquent ORM 中,你会:

MyTable::whereRaw('JSON_CONTAINS(my_table.settings, ?)', json_encode($jsonString));

【讨论】:

    【解决方案2】:

    您必须使用JSON_EXTRACT 函数。

    SELECT COUNT(id) as matches
    FROM my_table
    WHERE
    JSON_EXTRACT(`settings` , '$.color') = "red"
    AND JSON_EXTRACT(`settings` , '$.location') = "Australia"
    AND JSON_EXTRACT(`setting`, '$.flavour') = "cheese";
    

    我大部分时间都在使用 ORM,所以我可能会混淆一些反引号和引号,但我希望你明白了!

    【讨论】:

    • 这种方式的问题是我们需要在高级中知道json的内容...
    • 如果不知道要匹配什么,你打算如何匹配一整列json?也许我误解了你的问题,但我的回答解决了你的代码示例。
    • 例如我在一个我不知道其结构的变量中有 JSON。我在 JSON 的列中搜索我不知道的结构
    • 对不起,你没有任何意义。如果变量中有 JSON,则根据定义,您知道它的结构:json_decode()。使用JSON_EXTRACT 的全部意义在于您不需要知道数据库中JSON 的结构。您只需匹配键和值,让数据库完成它的工作。
    • 很高兴您以适合您的方式解决了它!即使我仍然不明白为什么我的答案有问题,但无论如何。它现在可以工作了:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-15
    • 1970-01-01
    • 2012-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多