LIKE 查询 Rails 中的 Postgres JSON 数组字段

LIKE Query on Postgres JSON array field in Rails

我有一个名为 messages 的 table,它有一个名为 headersjsonB 列来存储消息 headers。它看起来像这样:

[
   {
      "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% 和 return [=32] 中的结果=] 6.0.2?

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

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

但是报错!

你可以做一个子查询来获取你需要比较的元素,然后在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%'")

您需要的查询如下所示:

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%');

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