如何在续集中的where语句中使用json字段?

时间:2017-07-20 09:56:52

标签: ruby postgresql sequel sequel-gem

我有一张表transactions

 id             | bigint                      | NOT NULL DEFAULT nextval('transactions_id_seq'::regclass)
 transaction_id | bigint                      | NOT NULL
 middleware_id  | text                        | 
 opname         | optype                      | NOT NULL
 created_at     | timestamp without time zone | NOT NULL
 finished_at    | timestamp without time zone |
 request        | jsonb                       | NOT NULL
 answer         | jsonb                       | 

请求可以包含以下数据: { plugin_id: string, item_src_id: string, item_dst_id: string, payload: {}} 要么 { plugin_id: string, item_id: string, payload: {}}

我可以使用纯SQL选择某些item_id的事务列表:

SELECT id, request
  FROM transactions
  WHERE 'BEX456'
    IN (request->>'item_id', request->>'item_src_id', request->>'item_dst_id')

但是,当我在续集中使用该请求时,它会警告我

  

SEQUEL DEPRECATION警告:使用调用数据集过滤方法   多个参数或第一个参数/元素为a的数组   字符串已弃用,将在续集5中删除。

对于该请求:

$db[:transactions].
  where("? IN (request->>'item_id', request->>'item_src_id', request->>'item_dst_id')", data[:item_id]).all

我可以在where op中使用Sequel.lit作为该字符串,但我的问题是 - 我可以使用原生续集运算符来选择字段内的json 吗?

这对我有用:

$db[:transactions].where(
  data[:item_id] => [
    Sequel.lit("request->>'item_id'"),
    Sequel.lit("request->>'item_dst_id'"),
    Sequel.lit("request->>'item_src_id'") ] ).first

1 个答案:

答案 0 :(得分:1)

Postgres的JSON运算符位于pg_json_ops extension

预先加载:

Sequel.extension :pg_json_ops

然后,在您的特定情况下:

# request ->> 'item_id'
:request.pg_jsonb.get_text('item_id') # WITH core extensions
Sequel.pg_jsonb_op(:request).get_text('item_id') # or WITHOUT

你也拥有Ruby的力量:

["item_id", "item_dst_id", "item_src_id"].map { |key| :request.pg_jsonb.get_text(key) }