首页 > 解决方案 > 在文本中存储单词

问题描述

我正在使用 Rails 和 Postgresql 构建一个学习语言的应用程序。

文本被上传。文本的长度会有所不同,但我们假设它们的长度为 100-3000 字。

在上传时,每个文本位置都被转换为一个“标记”,表示关于该位置的单词的信息(基本单词、名词/动词/形容词/等、语法标签、definition_id)。

单击文本中的单词时,我需要在数据库中查找(并显示)与单击的单词具有相同属性(base_word、词性、标签)的单词的所有其他文本。

执行此操作的最简单和最相关的方法是连接表TextWord,在表TextWord. 每个text_word都代表文本中的一个位置,并包含text_idword_idgrammar_tagsstart_indexend_index

但是,如果文本有 100-3000 个单词,这意味着每个文本对象有 100-3000 个条目。

那是疯了吗?昂贵的?这会导致什么问题?

有没有更好的办法?

我不能使用 Postgres 全文搜索,因为例如,如果我在“I left Nashville”中单击“left”,我不希望出现“take a left at the light”。我只想要“离开”作为动词,以及其他形式的“离开”作为动词。此外,我可能只想要具有特定定义 ID 的“左”(例如,“左”用作“政党”,而不是“右的对立面”)。

我能想到的另一个选择是将 JSON 存储在文本对象上,将标记作为哈希的大哈希或哈希数组(无论哪种方式)。Postgresql 有办法搜索这种嵌套的数据结构吗?

第三个选项是使用与选项 2 相同的 JSON(存储文本中的所有位置),以及每个单词对象/定义对象/语法对象上的第二个 json(存储该对象出现的所有文本中的所有位置)。但是,这似乎比连接表占用更多的存储空间,我不确定它是否会带来任何切实的好处。

任何建议将不胜感激。

谢谢,迈克尔。

标签: ruby-on-railspostgresqlnlp

解决方案


一个简单的解决方案是拥有一个包含多个索引的数据库:一个用于基本词,一个用于词性,一个用于您感兴趣的所有其他功能。

当您单击left时,您会发现它是“离开”的一种形式,以及“过去时”中的“动词”。现在您转到索引,并获取“离开”、“动词”和“过去时”的所有标记位置。您取所有索引位置的交集,剩下的是您所追求的表单的标记位置。

如果您想节省空间,请查看Managing Gigabytes,这是一本关于该主题的优秀书籍。我过去曾用它来完全索引包含数百万个单词的文本语料库(这在 20 年前是相当多的......)


推荐阅读