【问题标题】:Mysql 5.7 json datatype, query with activerecord in Rails 5Mysql 5.7 json 数据类型,在 Rails 5 中使用 activerecord 查询
【发布时间】:2016-09-14 23:39:31
【问题描述】:

我正在使用 Rails 5 rc1 创建一个应用程序。 Rails 5 支持 mysql 5.7 json 数据类型。

add_column :organizations, :external, :json

假设该列的值如下:

+---------------------------+
| external                  |
+---------------------------+
| {"id": 10, "type": "mos"} |
+---------------------------+

要在外部列中搜索特定的“id”和“type”,我在 mysql 中使用以下查询:

select external from organizations where JSON_CONTAINS(external,'{"id": 10, "type": "mos"}') ;

现在,我想知道如何使用 rails 进行相同的查询。 以下不起作用:

Organization.where("JSON_CONTAINS(external,'{"id": 10, "type": "mos"}')")

注意:我无法删除 json 文本周围的引号,因为它是查询的一部分。

【问题讨论】:

    标签: mysql ruby-on-rails activerecord ruby-on-rails-5 mysql-5.7


    【解决方案1】:

    您仍然可以利用 ActiveRecord 的 where 方法并绑定变量,而无需借助 find_by_sql。

    Organization.where("external->'$.id' = :id and external->'$.type' = :type", id: 10, type: "mos")
    

    【讨论】:

    • 这仅适用于postgresql,不适用于mysql。
    • 在 Rails 5.1 和 Mysql 5.7 中为我工作
    • 不适用于 MariaDB 10.4,但 JSON_EXTRACT() 可以。
    【解决方案2】:

    使用 MYSQL,您可以使用 JSON_EXTRACT 从存储在字段中的 JSON 对象中提取值。在您的情况下,请尝试使用...

    Organization.where("JSON_EXTRACT(external, '$.id') = 10 AND JSON_EXTRACT(external, '$.type') = 'mos'")
    

    只是为了好玩,在伪代码中......

    <Class>.where("JSON_EXTRACT(<column_header>, '$.<object key>') <comparison operator> <object value>")
    

    这应该可以完成工作,尽管可能有更漂亮的方式来编写它:)

    【讨论】:

    • 我更喜欢这个,因为它适用于 MySQL 和 MariaDB。
    【解决方案3】:

    像这样:

    id_field = '$."id"'
    type_field = '$."type"'    
    Organization.where("JSON_UNQUOTE(json_extract(external, '#{id_field}')) = ? AND JSON_UNQUOTE(json_extract(external, '#{type_field}')) = ?", 10, "mos")
    

    【讨论】:

      【解决方案4】:

      到目前为止,我还没有通过 activerecord 找到任何解决方案。另一种查询方式如下:

      type = "mos"
      id = 10
      
      organization = Organization.find_by_sql(["select * from organizations where JSON_CONTAINS(external_ref ,'{\"id\": ?, \"type\": \"#{ActiveRecord::Base::sanitize(type).remove("'")}\"}')", id]).first
      

      一旦有带有activerecord查询接口的解决方案,我会更新。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-12-21
        • 2014-05-05
        • 2014-04-10
        • 2021-01-04
        • 2023-03-11
        • 2016-11-07
        • 2016-06-18
        相关资源
        最近更新 更多