Postgres JSON data type Rails query

…衆ロ難τιáo~ 提交于 2019-11-26 08:46:56

问题


I am using Postgres\' json data type but want to do a query/ordering with data that is nested within the json.

I want to order or query with .where on the json data type. For example, I want to query for users that have a follower count > 500 or I want to order by follower or following count.

Thanks!

Example:

model User

data: {
     \"photos\"=>[
       {\"type\"=>\"facebook\", \"type_id\"=>\"facebook\", \"type_name\"=>\"Facebook\", \"url\"=>\"facebook.com\"}
      ], 
     \"social_profiles\"=>[
         {\"type\"=>\"vimeo\", \"type_id\"=>\"vimeo\", \"type_name\"=>\"Vimeo\", \"url\"=>\"http://vimeo.com/\", \"username\"=>\"v\", \"id\"=>\"1\"},
         {\"bio\"=>\"I am not a person, but a series of plants\", \"followers\"=>1500, \"following\"=>240, \"type\"=>\"twitter\", \"type_id\"=>\"twitter\", \"type_name\"=>\"Twitter\", \"url\"=>\"http://www.twitter.com/\", \"username\"=>\"123\", \"id\"=>\"123\"}
     ]
}

回答1:


For any who stumbles upon this. I have come up with a list of queries using ActiveRecord and Postgres' JSON data type. Feel free to edit this to make it more clear.

Postgres important rails commands:

# Sort based on the Hstore data:
2.1.1 :022 > Post.order("data->'hello' DESC")

=> #<ActiveRecord::Relation [#<Post id: 4, created_at: "2014-04-16 01:05:49", updated_at: "2014-04-16 01:05:49", data: {"hi"=>"23", "hello"=>"22"}>, #<Post id: 3, created_at: "2014-04-16 01:05:37", updated_at: "2014-04-16 01:05:37", data: {"hi"=>"13", "hello"=>"21"}>, #<Post id: 2, created_at: "2014-04-16 01:05:28", updated_at: "2014-04-16 01:05:28", data: {"hi"=>"3", "hello"=>"2"}>, #<Post id: 1, created_at: "2014-04-16 01:05:05", updated_at: "2014-04-16 01:05:05", data: {"hi"=>"2", "hello"=>"1"}>]> 



# Where inside a JSON object:
Record.where("data ->> 'likelihood' = '0.89'")

# Searching nested json object:
2.1.1 :130 > r.column_data
 => {"data1"=>[1, 2, 3], "data2"=>"data2-3", "array"=>[{"hello"=>1}, {"hi"=>2}], "nest"=>{"nest1"=>"yes"}} 

2.1.1 :130 > Record.where("column_data -> 'nest' ->> 'nest1' = 'yes' ")

# Searching within array:
Record.where("column_data #>> '{data1,1}' = '2' ")


# Searching within a value that’s an array:
Record.where("column_data #> '{array,0}' ->> 'hello' = '1' ")
# this only find for one element of the array. 

# All elements:
Record.where("column_data ->> 'array' LIKE '%hello%' ")
# This is advised against in rails, use below:
Record.where("column_data ->> 'array' LIKE ?", "%hello%")

Update I will be writing a blog post on this very shortly and will put the link here.




回答2:


According to this http://edgeguides.rubyonrails.org/active_record_postgresql.html#json there's a difference in using -> and ->>:

# db/migrate/20131220144913_create_events.rb
create_table :events do |t|
  t.json 'payload'
end

# app/models/event.rb
class Event < ActiveRecord::Base
end

# Usage
Event.create(payload: { kind: "user_renamed", change: ["jack", "john"]})

event = Event.first
event.payload # => {"kind"=>"user_renamed", "change"=>["jack", "john"]}

## Query based on JSON document
# The -> operator returns the original JSON type (which might be an object), whereas ->> returns text
Event.where("payload->>'kind' = ?", "user_renamed")

So you should try Record.where("data ->> 'status' = 200 ") or the operator that suits your query (http://www.postgresql.org/docs/current/static/functions-json.html).




回答3:


Your question doesn't seem to correspond to the data you've shown, but if your table is named users and data is a field in that table with JSON like {count:123}, then the query

SELECT * WHERE data->'count' > 500 FROM users

will work. Take a look at your database schema to make sure you understand the layout and check that the query works before complicating it with Rails conventions.



来源:https://stackoverflow.com/questions/22667401/postgres-json-data-type-rails-query

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!