如果我有一个字符串'这是一个好的字符串'
我在数据库中有三条记录
1,"好"
2,"放屁"
3,"这个"
有没有办法查找作为我的源的子串的记录..
我问,因为我有一个black_list表,其中包含我从不想让我的用户存储的条目。就像他们想要存储www.google.com一样,我有" google"在我的黑名单中,我从存在中获得了积极的结果,并知道不要让他们......
我会继续挖掘,我可能会在这里发布我的答案,但要弄清楚这是一件有趣的事情。我宁愿在DB层中而不是在ruby / rails层中这样做。
答案 0 :(得分:2)
如果您只想匹配整个单词,那么使用更大的表会更快 ,因为它可以使用entry
上的索引(与您的解决方案不同,谓词的位置)不是sargable):
假设空格为单词分隔符(\s+
)。
SELECT *
FROM black_list
JOIN regexp_split_to_table('the task description', '\s+') entry USING (entry)
对于更具体的需求,您可以定制您提取的单词:
\m
的分词(由POSIX标准定义)。 Per documentation:
matches only at the beginning of a word
删除要忽略的前导,尾随或所有字符。由于我们在单词的开头处拆分,因此尾随字符可能就足够了。
最后转换为小写 - 假设black_list
中的小写条目:
分割单词并修剪给定的尾随字符:
SELECT *
FROM black_list
JOIN (
SELECT rtrim(w, ' /\,.-') AS entry -- add more?
FROM regexp_split_to_table('Oh - my, a4b smurf-village in/out.', '\m') w
) w USING (entry);
分词,删除所有非单词字符并转换为小写字母:
SELECT *
FROM black_list
JOIN (
SELECT lower(regexp_replace(w, '\W+', '')) AS entry
FROM regexp_split_to_table('Oh - my, a4b smurf-village in/out.', '\m') w
) w USING (entry);
您可以更进一步,测试相似性以捕获拼写错误。但你必须权衡alpha与beta错误(错误排除法律词语)。
SELECT set_limit(0.9); -- high example value
SELECT *
FROM black_list b
JOIN (
SELECT lower(regexp_replace(w, '\W+', '')) AS entry
FROM regexp_split_to_table('Oh - my, a4b smurf-village in/out.', '\m') w
) w ON b.entry % w.entry
%
运算符需要额外的模块pg_trgm。详细说明:
答案 1 :(得分:0)
它花费的时间比我想象的少得多......主要是因为我尝试了不同的东西。
select * from black_list
where 'this is the task description' like concat('%', entry, '%')
对于rails dev那里
scope :part_of, ->(source) { where("? like concat('%', entry, '%')", source) }
BlackList.part_of('this is a test fire').exists?
BlackList.part_of(task.description).exists?