3

我有一个使用主题标签来帮助标记帖子的应用程序。我正在尝试进行更详细的搜索。

假设我正在搜索的记录之一是:

The #bird flew very far.

当我搜索“fly”、“fle”或“#bird”时,它应该返回记录。

但是,当我搜索“#bir”时,它不应该返回句子,因为正在搜索的整个标签都不匹配。

我也不确定“鸟”是否应该返回句子。不过,我也会对如何做到这一点感兴趣。

现在,我有一个非常基本的搜索:

SELECT "posts".* FROM "posts" WHERE (body LIKE '%search%')

有任何想法吗?

4

2 回答 2

3

你可以用 LIKE 做到这一点,但这会很可怕,正则表达式在这里会更好地为你服务。如果您想忽略哈希,那么像这样的简单搜索就可以解决问题:

WHERE body ~ E'\\mbird\M''

那会找到'The bird flew very far.'and 'The #bird flew very far.'。你想#在搜索之前去掉任何 s ,尽管这样:

WHERE body ~ E'\\m#bird\M''

\m由于 和 的性质,\M找不到这些结果中的任何一个。

如果您不想忽略#s inbody那么您必须自己扩展和修改\m\M快捷方式,如下所示:

WHERE body ~ E'(^|[^\\w#])#bird($|[^\\w#])'
--   search term goes here^^^^^

使用E'(^|[^\\w#])#bird($|[^\\w#])'会找到'The #bird flew very far.'但不会'The bird flew very far.',而E'(^|[^\\w#])bird($|[^\\w#])'会发现'The bird flew very far.'但不会'The #bird flew very far.'。您可能还想查看\A而不是^\Z而不是$因为存在细微的差异,但我认为$并且^会是您想要的。

您应该记住,这些正则表达式搜索(或您的 LIKE 搜索)都不会使用索引,因此您正在为大量表扫描和性能问题设置自己,除非您可以使用将使用的东西来限制搜索指数。您可能想查看全文搜索解决方案。

于 2012-10-11T22:43:19.960 回答
3

当文章被插入/更新时,它可能有助于从文本中解析哈希标签并将它们存储在一个名为 say hashtags 的单独列中的数组中。body在将它们送入物品之前将它们从物品中取出并将其to_tsvector存储tsvector在表格的一列中。然后使用:

WHERE body_tsvector @@ to_tsquery('search') OR 'search' IN hashtags

您可以在表上使用触发器来维护hashtags列并body_tsvector去除哈希标记,这样应用程序就不必执行这项工作。INSERT当条目为ed 或UPDATEd时,将它们从文本中解析出来。

于 2012-10-14T05:06:47.170 回答