Java 计算句子:数据库(如h2)与Lucene与。?

Java 计算句子:数据库(如h2)与Lucene与。?,java,database,lucene,lookup,performance,Java,Database,Lucene,Lookup,Performance,我正在做一些语言学研究,这取决于能否查询一亿个句子的语料库。我需要从语料库中获得的信息大致如下:有多少个句子的第一个单词是john,第二个单词是Gone,第五个单词是hospital……等等,所以我只需要计数,不需要实际检索句子 我的想法是将这些句子拆分成单词并存储到数据库中,其中的列是单词-1、单词-2、单词-3…等的位置,句子是行。所以它看起来像: 单词1单词2单词3单词4单词5 国会批准了一项新法案 约翰上学去了 然后通过调用类似COUNTSELECT*的东西来实现我的目的,其中Word

我正在做一些语言学研究,这取决于能否查询一亿个句子的语料库。我需要从语料库中获得的信息大致如下:有多少个句子的第一个单词是john,第二个单词是Gone,第五个单词是hospital……等等,所以我只需要计数,不需要实际检索句子

我的想法是将这些句子拆分成单词并存储到数据库中,其中的列是单词-1、单词-2、单词-3…等的位置,句子是行。所以它看起来像:

单词1单词2单词3单词4单词5

国会批准了一项新法案

约翰上学去了

然后通过调用类似COUNTSELECT*的东西来实现我的目的,其中Word1=John和Word4=school。但我想知道:使用Lucene或其他工具可以更好地实现这一点吗

我正在用Java编写的程序将在1亿个sentece语料库上进行数十次这样的查询。因此,查找速度非常重要

谢谢你的建议


Anas

查看并绘制地图。它是为这样的事情而开发的。

假设查询像您所指出的那样简单,一个简单的SQL db Postgres、MySQL,可能是H2将非常适合于此。

或者您可以手工完成,只需使用java即可

List triple = new ArrayList(3);    
for (String word: inputFileWords) {
  if (triple.size == 3) {
      resultFile.println(StringUtils.join(" ", triple));
      triple.remove(0);
  }
  triple.add(line);
}
然后对该文件进行排序,并手动或从某个命令行实用程序对所有重复的行求和,这将尽可能快

我建议你读一读。据我所知,您确实需要一个数据库,而不是全文搜索库。 在任何情况下,我建议您对文本进行预处理,并使用字典将每个单词/标记替换为数字。这将用一系列单词代码替换每个句子。然后,我会将每个单词的位置存储在一个单独的数据库列中,简化计数并使其更快。 例如: 一个男孩和一个女孩喝牛奶

翻译成:

12053014120619447253

我选择了导致存储行的任意单词代码

120 530 14 120 619 447 253 0 0 0

直到你分配给每个句子的字数用完为止


这在某种程度上是一个问题,因此可能会有所帮助。

我想您已经有了从给定句子创建令牌的基础设施。您可以为句子中的每个单词创建一个lucene文档,其中包含一个字段。您可以将字段命名为field1、field2等。由于lucene没有类似DB的模式,因此可以根据需要动态定义任意多的字段。如果要标识与查询匹配的句子,可以添加额外的标识符字段

搜索时,典型的lucene查询将是

+field1:John +field4:school
由于您不担心检索的速度,因此可以编写一个自定义收集器来忽略分数。这也将更快地返回结果

因为您不打算检索匹配的句子或单词,所以应该只为这些字段编制索引,而不存储。这将使性能提高一个档次。

Lucene可以实现位置搜索。使用SpanFirst在文档的前N个位置查找单词,并将其与span组合以不排除前N-1

您的示例查询如下所示:

<BooleanQuery: +(+spanFirst(john, 1) +spanFirst(went, 2)) +spanNot(spanFirst(hospital, 5), spanFirst(hospital, 4))>

Lucene当然也允许在不迭代所有文档的情况下获得搜索结果的总点击数。

MapReduce似乎是为集群计算设计的,我将在我的个人笔记本上做这件事语料库只有几GB大小。这是最初的想法,但我之所以发布这个问题,部分原因是担心数到1亿行是否会有点慢。我的意思是,如果计算满足select语句的行需要10秒,那么速度太慢了。我担心这不符合我的目的:我不想要重复的行,我想要计算满足某些属性的行数,例如,有多少行将car作为第二个字,而将崩溃作为第三个字。所以简单地折叠线是不行的。另外,我需要能够以合理的速度访问该帐户,因为我的代码将执行数以万计的此类查询。哦,对不起,我只是误解了你的情况。在这种情况下,使用DB将是最佳选择。例如,Postgres有一些易于索引和查询数组的功能,它可以帮助您。但是对于1亿行来说,它可能没有你希望的那么快。非常感谢你的链接,我发现它非常有用。事实上,我认为搜索索引器会比数据库快,所以我决定用它,上帝愿意。再次感谢。