RAILS / POSTGRESQL中的多个LIKE和AND运算符
我使用Rails 5.0.1和Postgresql作为我的数据库。 我有一个包含列的表:content
包含单词。
问题:当我在找一个特定的单词时,我想看看这个单词是否包含我选择的字母(字符)。 假设我想要DB返回包含字母“a”,“b”和“c”的单词(所有这些单词,但没有特定的顺序)
我在做什么:我发现我可以使用Word.where("content like ?", "%a%").where("content like ?", "%b%").where("content like ?", "%c%")
或Word.where("content like ? content like ? content like ?", "%a%", "%b%", "%c%")
在这两种情况下即使我切换给定字母/子串的顺序它工作正常,例如。 两者都会找到“后退”,“出租车”等字样。
问题是:有没有更好/更干的方法呢? 如果想找到8个不同字母的单词怎么办? 我必须使用“喜欢的内容吗?” 8次? 是否可以将参数作为数组传递? (假设我不知道用户输入了多少个字母)
PostgreSQL有一个方便的expr op all (array)
表达式,所以你可以这样说:
where content like all (array['%a%', '%b%', '%c'])
作为简短forms:
where content like '%a%' and content like '%b%' and content like '%c%'
另外,ActiveRecord会方便地替换一个?
如果您将Ruby数组交给它,则使用逗号分隔的列表占位符。 这可以让你说:
Word.where('content like all (array[?])', %w[abc].map { |c| "%#{c}%" })
和:
Word.where('content like all (array[?])', some_other_array.map { |c| "%#{c}%" })
我认为SIMILAR TO
运算符可能有所帮助。 它允许您传入可以动态构建的正则表达式。
letters = ['a', 'b', 'c'] pattern = "%(#{letters.join('|')})%" Word.where("content SIMILAR TO ?", pattern)
我找到了解决方案:
letters = ["%a%", "%b%", "%c%"] Word.where((['content LIKE ?'] * letters.size).join(' AND '), *letters)
这比我使用的简单易行。
- RAILS:如何查询每个关联都具有非null属性的所有对象
- Rails / Postgresql SQL差异w /日期
- 在Rails中的一个ActiveRecord事务中更新多个记录
- 连接集必须包含所有值但可能包含更多值的SQL
- Heroku架构加载:数据库“postgres”用户的权限被拒绝
- 将字符串化数组转换回数组
- Rails / postgres,’外键’存储在数组中以创建1-many关联
- Rails 4 / postgresql index – 我应该使用一个datetime列作为索引filter,它可以有无限数量的值吗?
- 迭代大型外部postgres db,操作行,将输出写入rails postgres db