Ruby on rails 查询RAIL 5.2 postgres12上的jsonb数组
在带有PostgreSQL 12.2的rails 5上,我有这个模型Ruby on rails 查询RAIL 5.2 postgres12上的jsonb数组,ruby-on-rails,postgresql,Ruby On Rails,Postgresql,在带有PostgreSQL 12.2的rails 5上,我有这个模型 create_table "training_opportunities", force: :cascade do |t| t.bigint "contact_id" t.string "situation" t.boolean "cpf" t.string "software_interest&quo
create_table "training_opportunities", force: :cascade do |t|
t.bigint "contact_id"
t.string "situation"
t.boolean "cpf"
t.string "software_interest"
t.string "training_type_interest"
t.string "month"
t.text "comment"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "status"
t.boolean "pole_emploi", default: false
t.jsonb "history", default: [], array: true
t.boolean "to_be_call", default: false
t.boolean "is_flag", default: false
t.boolean "is_star", default: false
t.index ["contact_id"], name: "index_training_opportunities_on_contact_id"
end
我试图通过历史的内容来质疑培训机会。例如,在rails c中
TrainingOpportunity.first.history
给予
我试图通过以下查询找到它:
TrainingOpportunity.where('history @> {"step":"ID POLE EMPLOI : 1242050E - architecture intérieur - débutante qlq notions de 3D - environ 2500€CPF - devis envoyé le 03/07"}')
但我有这个错误
ActiveRecord::StatementInvalid (PG::SyntaxError: ERROR: syntax error at or near "{")
LINE 1: ...* FROM "training_opportunities" WHERE (history @> {"step":"I...
^
: SELECT "training_opportunities".* FROM "training_opportunities" WHERE (history @> {"step":"ID POLE EMPLOI : 1242050E - architecture intérieur - débutante qlq notions de 3D - environ 2500€CPF - devis envoyé le 03/07"}) LIMIT $1
我试过:
TrainingOpportunity.where('history @> ?', '[{"step":"ID POLE EMPLOI : 1242050E - architecture intérieur - débutante qlq notions de 3D - environ 2500€CPF - devis envoyé le 03/07"}]')
但我有一个错误:
ActiveRecord::StatementInvalid (PG::InvalidTextRepresentation: ERROR: malformed array literal: "[{"step":"ID POLE EMPLOI : 1242050E - architecture intérieur - débutante qlq notions de 3D - environ 2500€CPF - devis envoyé le 03/07"}]")
LINE 1: ...* FROM "training_opportunities" WHERE (history @> '[{"step":...
^
DETAIL: "[" must introduce explicitly-specified array dimensions.
: SELECT "training_opportunities".* FROM "training_opportunities" WHERE (history @> '[{"step":"ID POLE EMPLOI : 1242050E - architecture intérieur - débutante qlq notions de 3D - environ 2500€CPF - devis envoyé le 03/07"}]') LIMIT $1
在rmlockerd提议之后,我尝试了以下解决方案
但没有人能奏效
TrainingOpportunity.where('history @> ?', {"date"=>"20/07/03"}.to_json)
TrainingOpportunity Load (1.0ms) SELECT "training_opportunities".* FROM "training_opportunities" WHERE (history @> '{"date":"20/07/03"}') LIMIT $1 [["LIMIT", 11]]
Traceback (most recent call last):
ActiveRecord::StatementInvalid (PG::InvalidTextRepresentation: ERROR: malformed array literal: "{"date":"20/07/03"}")
LINE 1: ...* FROM "training_opportunities" WHERE (history @> '{"date":"...
^
DETAIL: Unexpected array element.
: SELECT "training_opportunities".* FROM "training_opportunities" WHERE (history @> '{"date":"20/07/03"}') LIMIT $1
TrainingOpportunity.where('history @> ?', {'date'=>'20/07/03'}.to_json)
TrainingOpportunity Load (1.0ms) SELECT "training_opportunities".* FROM "training_opportunities" WHERE (history @> '{"date":"20/07/03"}') LIMIT $1 [["LIMIT", 11]]
Traceback (most recent call last):
ActiveRecord::StatementInvalid (PG::InvalidTextRepresentation: ERROR: malformed array literal: "{"date":"20/07/03"}")
LINE 1: ...* FROM "training_opportunities" WHERE (history @> '{"date":"...
^
DETAIL: Unexpected array element.
: SELECT "training_opportunities".* FROM "training_opportunities" WHERE (history @> '{"date":"20/07/03"}') LIMIT $1
TrainingOpportunity.where('history @> ?', {date:'20/07/03'}.to_json)
TrainingOpportunity Load (1.0ms) SELECT "training_opportunities".* FROM "training_opportunities" WHERE (history @> '{"date":"20/07/03"}') LIMIT $1 [["LIMIT", 11]]
Traceback (most recent call last):
ActiveRecord::StatementInvalid (PG::InvalidTextRepresentation: ERROR: malformed array literal: "{"date":"20/07/03"}")
LINE 1: ...* FROM "training_opportunities" WHERE (history @> '{"date":"...
^
DETAIL: Unexpected array element.
: SELECT "training_opportunities".* FROM "training_opportunities" WHERE (history @> '{"date":"20/07/03"}') LIMIT $1
TrainingOpportunity.where('history @> ?', [{date:'20/07/03'}].to_json)
TrainingOpportunity Load (1.0ms) SELECT "training_opportunities".* FROM "training_opportunities" WHERE (history @> '[{"date":"20/07/03"}]') LIMIT $1 [["LIMIT", 11]]
Traceback (most recent call last):
ActiveRecord::StatementInvalid (PG::InvalidTextRepresentation: ERROR: malformed array literal: "[{"date":"20/07/03"}]")
LINE 1: ...* FROM "training_opportunities" WHERE (history @> '[{"date":...
^
DETAIL: "[" must introduce explicitly-specified array dimensions.
: SELECT "training_opportunities".* FROM "training_opportunities" WHERE (history @> '[{"date":"20/07/03"}]') LIMIT $1
我尝试指定数组的第一个元素
编辑
我最初的回答(以及您最初的尝试)假设一个列是用Postgresjsonb
datatype声明的。然而,你有
还将其创建为Postgres数组(即jsonb[]
而不是jsonb
)。Postgres对数组和jsonb类型都支持@>
操作符,坦率地说,这两种类型之间存在某种交互作用,我没有能力帮助您解开这一难题。好消息是你似乎想要的东西我认为没有必要。您有两个选择:
<> LI>如果要对该数据进行大量查询,请考虑将其规范化为<代码>历史< /代码>模型,并在<代码>培训机会中使用<代码> HasyMuly关系。除了使查询更容易之外,您还可以获得模型的所有其他优点,如验证等
如果您真的想将其保留为JSON,我建议将history
列重新创建为jsonb
类型(不带array:true
)。在实践中,您仍然可以将其视为一个数组(因为数组是有效的JSON),并且@>
操作符将按照下面的概述工作
TrainingOpportunity.where('history@>?',[{step:“重新使用现有的自动程序”}]。to_json)
=>#“重新使用自动生存”}],…>
TrainingOpportunity.where('history@>?',[{date:'20/07/03}]。to_json)
=>#“重新使用自动生存”}],…>
谢谢你的回答,但它不起作用,我不知道为什么?我已经编辑了我的初始帖子。我将您的示例数据加载到我环境中的模型中,这些查询对我很有用。我来看看。谢谢mlockerd,我在mac os或heroku上,在postgres 12.2上,rails 5.2上。这个操作员可以帮忙吗?#>>不幸的是,没有。像#>
这样的JSON操作符在jsonb
列上工作,但您的设置为jsonb[]
列,这意味着Postgres主要将其视为数组,因此仅对其进行处理。如果您想使用JSON操作符直接查询数据,那么我的答案是正确的;迁移列以消除阵列部分。它增加了复杂性,但对你没有任何价值。
TrainingOpportunity.where('history @> ?', {"date"=>"20/07/03"}.to_json)
TrainingOpportunity Load (1.0ms) SELECT "training_opportunities".* FROM "training_opportunities" WHERE (history @> '{"date":"20/07/03"}') LIMIT $1 [["LIMIT", 11]]
Traceback (most recent call last):
ActiveRecord::StatementInvalid (PG::InvalidTextRepresentation: ERROR: malformed array literal: "{"date":"20/07/03"}")
LINE 1: ...* FROM "training_opportunities" WHERE (history @> '{"date":"...
^
DETAIL: Unexpected array element.
: SELECT "training_opportunities".* FROM "training_opportunities" WHERE (history @> '{"date":"20/07/03"}') LIMIT $1
TrainingOpportunity.where('history @> ?', {'date'=>'20/07/03'}.to_json)
TrainingOpportunity Load (1.0ms) SELECT "training_opportunities".* FROM "training_opportunities" WHERE (history @> '{"date":"20/07/03"}') LIMIT $1 [["LIMIT", 11]]
Traceback (most recent call last):
ActiveRecord::StatementInvalid (PG::InvalidTextRepresentation: ERROR: malformed array literal: "{"date":"20/07/03"}")
LINE 1: ...* FROM "training_opportunities" WHERE (history @> '{"date":"...
^
DETAIL: Unexpected array element.
: SELECT "training_opportunities".* FROM "training_opportunities" WHERE (history @> '{"date":"20/07/03"}') LIMIT $1
TrainingOpportunity.where('history @> ?', {date:'20/07/03'}.to_json)
TrainingOpportunity Load (1.0ms) SELECT "training_opportunities".* FROM "training_opportunities" WHERE (history @> '{"date":"20/07/03"}') LIMIT $1 [["LIMIT", 11]]
Traceback (most recent call last):
ActiveRecord::StatementInvalid (PG::InvalidTextRepresentation: ERROR: malformed array literal: "{"date":"20/07/03"}")
LINE 1: ...* FROM "training_opportunities" WHERE (history @> '{"date":"...
^
DETAIL: Unexpected array element.
: SELECT "training_opportunities".* FROM "training_opportunities" WHERE (history @> '{"date":"20/07/03"}') LIMIT $1
TrainingOpportunity.where('history @> ?', [{date:'20/07/03'}].to_json)
TrainingOpportunity Load (1.0ms) SELECT "training_opportunities".* FROM "training_opportunities" WHERE (history @> '[{"date":"20/07/03"}]') LIMIT $1 [["LIMIT", 11]]
Traceback (most recent call last):
ActiveRecord::StatementInvalid (PG::InvalidTextRepresentation: ERROR: malformed array literal: "[{"date":"20/07/03"}]")
LINE 1: ...* FROM "training_opportunities" WHERE (history @> '[{"date":...
^
DETAIL: "[" must introduce explicitly-specified array dimensions.
: SELECT "training_opportunities".* FROM "training_opportunities" WHERE (history @> '[{"date":"20/07/03"}]') LIMIT $1
TrainingOpportunity.where('history --> 0 = ?', '{"date"=>"20/07/03"}')
TrainingOpportunity Load (0.9ms) SELECT "training_opportunities".* FROM "training_opportunities" WHERE (history --> 0 = '{"date"=>"20/07/03"}') LIMIT $1 [["LIMIT", 11]]
Traceback (most recent call last):
ActiveRecord::StatementInvalid (PG::SyntaxError: ERROR: syntax error at end of input)
LINE 1: ...ies" WHERE (history --> 0 = '{"date"=>"20/07/03"}') LIMIT $1
^
: SELECT "training_opportunities".* FROM "training_opportunities" WHERE (history --> 0 = '{"date"=>"20/07/03"}') LIMIT $1