【问题标题】:LIKE Query on Postgres JSON array field in Rails在 Rails 中对 Postgres JSON 数组字段进行 LIKE 查询
【发布时间】:2020-10-26 18:52:48
【问题描述】:

我有一个名为messages 的表,其中有一个名为headersjsonB 列来存储邮件标题。它看起来像这样:

[
   {
      "name":"Cc",
      "field":{
         "name":"Cc",
         "value":"\"abc@gmail.com\" <abc@gmail.com>",
         "length":null,
         "charset":"UTF-8",
         "element":null,
         "address_list":{
            "addresses":[
               {
                  "data":{
                     "raw":"\"abc@gmail.com\" <abc@gmail.com>",
                     "error":null,
                     "group":null,
                     "local":"abc",
                     "domain":"gmail.com",
                     "comments":[

                     ],
                     "display_name":"abc@gmail.com",
                     "obs_domain_list":null
                  },
                  "parsed":true
               }
            ],
            "group_names":[

            ]
         }
      },
      "charset":"UTF-8",
      "field_order_id":14,
      "unparsed_value":"\"abc@gmail.com\" <abc@gmail.com>"
   },
   {
      "name":"Message-ID",
      "field":{
         "name":"Message-ID",
         "uniq":1,
         "value":"<sdasdasd+tkiCVQ@mail.gmail.com>",
         "length":null,
         "charset":"UTF-8",
         "element":{
            "message_ids":[
               "sdasdasd+tkiCVQ@mail.gmail.com"
            ]
         }
      },
      "charset":"UTF-8",
      "field_order_id":16,
      "unparsed_value":"<sdasdasd+tkiCVQ@mail.gmail.com>"
   },
   {
      "name":"Subject",
      "field":{
         "name":"Subject",
         "value":"Re: test email",
         "errors":[

         ],
         "length":null,
         "charset":"UTF-8",
         "element":null
      },
      "charset":"UTF-8",
      "field_order_id":19,
      "unparsed_value":"Re: test email"
   }
]

我想要搜索 'name' = 'Subject' 和 'unparsed_value' 的记录,例如 %test%,并在 Rails 6.0.2 中返回结果?

我正在尝试下面提到的代码:

messages.where("headers @> '[{\"name\": \"Subject\"}, {\"unparsed_value\" LIKE \"%test%\"}]'")

但它会抛出错误!

【问题讨论】:

    标签: ruby-on-rails json postgresql sql-like psql


    【解决方案1】:

    你可以做一个子查询来获取你需要比较的元素,然后在 where 子句中使用它们:

    Message
      .from(
        Message.select("
          id,
          headers,
          jsonb_array_elements(headers)->>'unparsed_value' AS unparsed_value,
          jsonb_array_elements(headers)->>'name' AS name
        "), :t
      )
      .select('t.*')
      .where("t.name = 'Subject' AND t.unparsed_value LIKE '%test%'")
    

    【讨论】:

    • 它返回的是空数组!
    • @SebastianPalma 我相信问题中的标题列包含哈希数组。你的包含一个哈希值。
    • 对@LesNightingill,刚刚更新了。感谢您指出这一点。
    • 感谢@LesNightingill。有效!我可以知道为什么需要对 Message 表进行自我内部查询吗?
    • 不是自我内部@Rivu(加入?),只是您需要以某种方式访问​​这两个列/值以在您的 where 子句中使用它们。最常见的是认为您可以在您的 select 语句中获取它们,但是无法在 where 中使用这些值,因此 from 是要走的路。
    【解决方案2】:

    您需要的查询如下所示:

    SELECT * FROM messages WHERE 
      (SELECT true FROM jsonb_to_recordset(messages.headers)
        AS x(name text, field jsonb)
        WHERE name = 'Subject'
        AND field->>'unparsed_value' LIKE '%test%');
    

    这是否会给您想要的结果?

    【讨论】:

      猜你喜欢
      • 2017-04-03
      • 2016-06-05
      • 2017-09-01
      • 1970-01-01
      • 2019-07-11
      • 2018-06-09
      • 2011-11-05
      • 1970-01-01
      相关资源
      最近更新 更多