在数组里面模糊查询某个内容


搜索:张三  ,把:tags: [“张三”,"abc"]和 tags: ["张三风","万立"] 的记录都找出来。

这里用了个折中的办法:把tags数组组合成字符串,再来模糊搜索

一个关键字,匹配多个tags
Topic.select(:tags).where('concat(tags) ILIKE ?', "%张三%")

多个tags,去匹配一组关键字,那么可以参考,注意pg数据库,数组第一个是从1开始计数的.
Topic.where("tags is NOT NULL and tags[1] = ANY(ARRAY[?])",["张三风","万立"] )

Post.where("topic_id = ANY(ARRAY[?]) or id = ANY(ARRAY[?])",ids.push(0), post_ids.push(0)).where("created_at > ?",16.days.ago.beginning_of_day)

单个tag匹配一组关键字。
Topic.where("tag similar to  '%苹果%|%榴莲%')

上诉都有点缺陷。有待改进。

精准搜索tag:
Topic.where('? =ANY(tags)', "张三")

https://www.tutorialsteacher.com/postgresql/array-data-type

其它参考: 
参考这个例子:
select *
from people
where name like any (
    select concat(first_name, last_name, '%')
    from other_people
)

PostgreSQL also supports full POSIX regular expressions:
PostgreSQL支持正则表达式:
~* 忽略大小写,
~  大小写表示不同的字母.

select * from table where value ~* 'foo|bar|baz';

The ~* is for a case insensitive match, ~ is case sensitive.
这个是搜索value里面包含  foo或者bar或者baz 的记录,且忽略大小写.

下面这条和上面的实现的功能一样:

Another option is to use ANY:

select * from table where value  like any (array['%foo%', '%bar%', '%baz%']);
select * from table where value ilike any (array['%foo%', '%bar%', '%baz%']);

You can use ANY with any operator that yields a boolean. I suspect that the regex options would be quicker but ANY is a useful tool to have in your toolbox.
你可以使用ANY 加操作符号,得到一个布尔值.
我怀疑regex正则可能快一点,但是ANY是个有用的工具.

其他参考:
处理被搜索的代码,防止注入攻击等.
  5   def escape_search_term(term)
  6     "%#{term.gsub(/\s+/, '%')}%"
  7   end

传入多个被搜索的字段的例子:
name = 'abc,bdd,efg'
names = name.split(',').map{|x| escape_search_term(x) }
@words =Word.where("name ilike any(array[?])", names)


阅读量: 2219
发布于:
修改于: