高效的数据库模型,用于存储由n-gram索引的数据


12

我正在开发一个应用程序,该应用程序需要创建一个存在于大型文本语料库中的非常大的n-gram数据库。

我需要三种有效的操作类型:由n-gram本身索引的查找和插入,以及查询包含子n-gram的所有n-gram。

在我看来,数据库应该是一个巨大的文档树,而文档数据库(例如Mongo)应该能够很好地完成工作,但是我从来没有大规模使用过。

了解Stack Exchange问​​题格式后,我想澄清的是,我并不是在寻求有关特定技术的建议,而是要寻求大规模实施此类数据库的一种类型的数据库。


2
我认为您要实现的结构是一个“尝试”-无论您是找到一个可以有效地使用该结构的数据库,还是需要在您选择的RDBMS中滚动自己的数据库,我无法说。
尼尔·斯莱特

Answers:


9

参见Lucene NGramTokenizer

您确定不能只使用Lucene或类似的索引技术吗?

倒排索引将只存储n-gram一次,然后仅存储包含ngram的文档ID。他们不会将其存储为高度冗余的原始文本。

至于查找包含查询子n-gram的ngram,我会在观察到的ngram上建立索引,例如使用第二个lucene索引或任何其他子字符串索引(例如trie或后缀树)。如果您的数据是动态的,那么使用短语查询来查找您的n-gram可能是合理的选择。


3

基本上,对于此任务,您可以有效地使用任何具有基于B + tree索引的良好支持的SQL数据库(MySQL将满足您的需要)。

创建3个表:

  1. 文件表格,栏:编号/文件
  2. N-gram表:n_gram_id / n_gram
  3. n-gram和文档之间的映射:document_id / n_gram_id

在N-gram表/ n_gram字符串和Mapping表/ n_gram_id上创建索引,默认情况下主键也将被很好地索引。

您的运营将高效:

  1. 插入文档:仅提取所有n-gram并插入到文档表和N-grams表中
  2. 支持索引,可以快速查找in_gram
  3. 查询包含子n-gram的所有n-gram:分2步-仅根据索引从第二个表中查询包含子n-gram的所有n-gram。然后-为这些n-gram中的每一个检索所有对应的文档。

您甚至不需要使用联接来完成所有这些操作,因此索引将大有帮助。同样,如果数据不能容纳在一台机器上,则可以实施分片方案,例如将n_grams从一台服务器上存储,然后在另一台服务器上存储oz,或者在其他合适的方案上存储。

您也可以使用MongoDB,但是我不确定您需要多么精确地实现索引方案。对于MongoDB,您将免费获得分片方案,因为它已内置。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.