【发布时间】:2020-05-15 04:53:45
【问题描述】:
我正在使用 Rails 和 Postgresql 构建一个学习语言的应用程序。
文本被上传。文本的长度会有所不同,但我们假设它们的长度为 100-3000 字。
在上传时,每个文本位置都被转换为一个“标记”,表示该位置的单词信息(基本单词、名词/动词/形容词/等、语法标签、定义 ID)。
点击文本中的一个词时,我需要在数据库中查找(并显示)所有其他文本,这些文本与点击的词具有相同的属性(base_word、词性、标签)。
最简单和最相关的方法是在表Text 和Word 之间连接表TextWord。每个text_word 将代表文本中的一个位置,并包含text_id、word_id、grammar_tags、start_index 和end_index。
但是,如果文本包含 100-3000 个单词,这意味着每个文本对象有 100-3000 个条目。
这很疯狂吗?昂贵的?这会导致什么问题?
有没有更好的办法?
我不能使用 Postgres 全文搜索,因为例如,如果我在“我离开纳什维尔”中单击“左”,我不希望“在灯下左转”出现。我只想要“离开”作为动词,以及其他形式的“离开”作为动词。此外,我可能只想要具有特定定义 ID 的“左”(例如,“左”用作“政党”,而不是“右的对立面”)。
我能想到的另一个选择是在文本对象上存储一个 JSON,将标记作为一个大的 散列散列,或散列数组(无论哪种方式)。 Postgresql 有办法搜索这种嵌套的数据结构吗?
第三个选项是使用与选项 2 相同的 JSON(存储文本中的所有位置),以及每个单词对象/定义对象/语法对象上的第二个 json(存储所有文本中的所有位置,其中该对象出现)。但是,这似乎比连接表占用更多的存储空间,我不确定它是否会带来任何切实的好处。
任何建议将不胜感激。
谢谢, 迈克尔。
【问题讨论】:
-
为什么要重新发明轮子?使用 PostgreSQL 全文搜索。
-
因为如果我点击“我离开纳什维尔”中的“左”,我不希望出现“左转”(left => 名词)。它们需要在基本词/词性级别链接。我只想要动词“离开”(“离开”,还有“离开”、“离开”)。另外,我最终可能只想要那些标记为特定定义_id的。
-
换句话说(不是双关语),我需要通过附加到每个位置的特定属性进行搜索,而不仅仅是直接的文本匹配。我希望它是那么简单。但是……通天塔,哟。
-
但是:postgres 全文搜索是否让我可以像搜索文本一样搜索哈希?要在哈希中查找特定属性?
-
您从文本中计算出
tsvector(这可能是您设想的 PostgreSQL 等价的哈希值),然后使用@@运算符搜索tsquery。但是,如果您需要基于文本的语法分析进行匹配(即消除不同的left),则无法通过 PostgreSQl 全文搜索来完成。 PostgreSQL 全文搜索的一个很酷的地方(或者更好的是,其中一个很酷的地方)是它可以使用 GIN 索引非常快。
标签: ruby-on-rails postgresql nlp