简体   繁体   中英

LIKE Query on Postgres JSON array field in Rails

I have a table called messages which has a jsonB column called headers to store message headers. It looks like this:

[
   {
      "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"
   }
]

I want search records where 'name' = 'Subject' and 'unparsed_value' like %test% and return the result in Rails 6.0.2?

I'm trying the below mention code:

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

But it's throwing error!

You can do a sub query to get the elements you need to compare and then use them in the where clause:

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

The query you need looks like this:

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

Does this give you the result you're looking for?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM