【问题标题】:MySQL/MariaDB JSON_EXTRACT and JSON_CONTAINSMySQL/MariaDB JSON_EXTRACT 和 JSON_CONTAINS
【发布时间】:2019-02-04 14:33:29
【问题描述】:

我有一个结构如下的表:

select * from test_table;

id |load_balancer_name |listener_descriptions                                                                                                                                                                                       |
---|-------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
1  |with_cert_1        |[{"Listener": {"Protocol": "HTTPS", "LoadBalancerPort": 443, "InstanceProtocol": "HTTP", "InstancePort": 9005, "SSLCertificateId": "arn:aws:acm:us-west-2:xxxx:certificate/xxx"}, "PolicyNames": ["xxxx"]}] |
2  |with_cert_1        |[{"Listener": {"Protocol": "HTTPS", "LoadBalancerPort": 443, "InstanceProtocol": "HTTP", "InstancePort": 9005, "SSLCertificateId": "arn:aws:acm:us-west-2:xxxx:certificate/xxx"}, "PolicyNames": ["xxxx"]}] |
3  |with_cert_2        |[{"Listener": {"Protocol": "HTTPS", "LoadBalancerPort": 443, "InstanceProtocol": "HTTP", "InstancePort": 9005, "SSLCertificateId": "arn:aws:acm:us-west-2:xxxx:certificate/yyy"}, "PolicyNames": ["xxxx"]}] |
4  |no_cert            |                                                                                                                                                                                                            |

我需要根据listener_descriptions 列进行一些搜索。为了确保JSON_* 方法有效,我 做了这个查询,效果很好:

select 
id, load_balancer_name,
JSON_EXTRACT(listener_descriptions, "$[*].Listener.SSLCertificateId")
from test_table;

id |load_balancer_name |JSON_EXTRACT(listener_descriptions, "$[*].Listener.SSLCertificateId") |
---|-------------------|----------------------------------------------------------------------|
1  |with_cert_1        |["arn:aws:acm:us-west-2:xxxx:certificate/xxx"]                        |
2  |with_cert_1        |["arn:aws:acm:us-west-2:xxxx:certificate/xxx"]                        |
3  |with_cert_2        |["arn:aws:acm:us-west-2:xxxx:certificate/yyy"]                        |
4  |no_cert            |                                                                      |

现在我想选择匹配SSLCertificateId的所有行:

select 
*
from test_table
where JSON_CONTAINS(listener_descriptions, '"arn:aws:acm:us-west-2:xxxx:certificate/xxx"', "$[*].Listener.SSLCertificateId")
;

但没有找到结果。我在JSON_CONTAINS的第二个参数中尝试了单引号和双引号的多种组合,但没有成功。

version()                                |
-----------------------------------------|
10.3.8-MariaDB-1:10.3.8+maria~bionic-log |

【问题讨论】:

  • 出于好奇,您为什么使用 JSON 来存储这些数据? JSON 数据的每一行都有相同的属性集。您可以为每个属性创建真正的列。然后你可以搜索WHERE SSLCertificateId = '...'
  • @BillKarwin listener_descriptions 是一个列表,它可以包含多个对象,所以SSLCertificateId 可以是多个。有很多方法,其中大多数更好,但是...
  • 这听起来像是一个简单的一对多关系。您应该有一个load_balancer 表和一个listener 表,每行有一个侦听器,每个都引用它的load_balancer。如果每个侦听器有多个策略,则第三个表 listener_policy 每行一个策略,每个引用其侦听器。

标签: mysql json mariadb mysql-json


【解决方案1】:

JSON_CONTAINS() 不允许 [*] 在其路径中。相反,使用JSON_EXTRACT() 提取所有证书的数组,然后使用JSON_CONTAINS()

select *
FROM test_table
WHERE JSON_CONTAINS(JSON_EXTRACT(listener_descriptions, "$[*].Listener.SSLCertificateId"), '"arn:aws:acm:us-west-2:xxxx:certificate/xxx"')
;

DEMO

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-19
    • 2021-03-07
    • 2020-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-24
    相关资源
    最近更新 更多