Rails:在Postgres字符串数组中使用通配符进行搜索

时间:2015-05-29 21:17:22

标签: ruby-on-rails postgresql activerecord

我们的应用程序运行Rails 4.2和Postgres,并使用字符串数组。例如:

add_column :things, :identifiers, :string, array: true, default: []

Thing.create(identifiers: ['blahsomething', 'other'])
Thing.create(identifiers: ['blahother', 'yetanother'])

我想使用ActiveRecord查询标识符LIKE'blah%'的所有内容。

使用原始SQL,我相信这可以通过Postgres的unnest命令实现:Postgres Query of an Array using LIKE

但是如何通过ActiveRecord范围查询字符串数组中的LIKE,以便它可以与其他ActiveRecord查询链接?

1 个答案:

答案 0 :(得分:2)

我做了2次查询。我创建了一个表,如:

sti_development=> select * from posts;
 id |            tags             |         created_at         |         updated_at         
----+-----------------------------+----------------------------+----------------------------
  1 | {blahsomething,other}       | 2015-05-30 06:08:51.668394 | 2015-05-30 06:08:51.668394
  2 | {blahother,yetanother}      | 2015-05-30 06:09:12.350234 | 2015-05-30 06:09:12.350234
  3 | {otherblahother,yetanother} | 2015-05-30 06:09:32.534039 | 2015-05-30 06:09:32.534039
(3 rows)

这是我的Rails查询:

[arup@sti (master)]$ rails c
Loading development environment (Rails 4.2.1)
=> Unable to load pry
>> Post.where(id: Post.select("distinct x.id").from(Post.select("id, unnest(tags) tag"), :x).where("x.tag like ?", 'blah%').pluck("x.id"))
   (1.3ms)  SELECT x.id FROM (SELECT id, unnest(tags) tag FROM "posts") x WHERE (x.tag like 'blah%')
  Post Load (1.4ms)  SELECT "posts".* FROM "posts" WHERE "posts"."id" IN (1, 2)
=> #<ActiveRecord::Relation [#<Post id: 1, tags: ["blahsomething", "other"], created_at: "2015-05-30 06:08:51", updated_at: "2015-05-30 06:08:51">, #<Post id: 2, tags: ["blahother", "yetanother"], created_at: "2015-05-30 06:09:12", updated_at: "2015-05-30 06:09:12">]>

Rails确实支持from方法来支持内部查询。

另一种方法是选择一个分隔符,它不是标记的一部分。如下所示:

sti_development=> SELECT "posts".* from "posts" WHERE ('|' || array_to_string(tags, '|')) LIKE ('%|' || 'blah%');
 id |             tags             |         created_at         |         updated_at
----+------------------------------+----------------------------+----------------------------
  1 | {blahsomething,other}        | 2015-05-30 06:08:51.668394 | 2015-05-30 06:08:51.668394
  2 | {blahother,yetanother}       | 2015-05-30 06:09:12.350234 | 2015-05-30 06:09:12.350234
  4 | {otherblahother,blahanother} | 2015-05-30 06:46:12.929428 | 2015-05-30 06:46:12.929428
(3 rows)

sti_development=> \q

现在在Rails中。

[arup@sti (master)]$ rails c
Loading development environment (Rails 4.2.1)
=> Unable to load pry
>> Post.where("'|' || array_to_string(tags, '|') LIKE ? ", "%|blah%")
  Post Load (1.5ms)  SELECT "posts".* FROM "posts" WHERE ('|' || array_to_string(tags, '|') LIKE '%|blah%' )
=> #<ActiveRecord::Relation [#<Post id: 1, tags: ["blahsomething", "other"], created_at: "2015-05-30 06:08:51", updated_at: "2015-05-30 06:08:51">, #<Post id: 2, tags: ["blahother", "yetanother"], created_at: "2015-05-30 06:09:12", updated_at: "2015-05-30 06:09:12">, #<Post id: 4, tags: ["otherblahother", "blahanother"], created_at: "2015-05-30 06:46:12", updated_at: "2015-05-30 06:46:12">]>
>>