我正在使用Lucene来获取文档中的术语频率,即每个文档中某些术语的出现次数。我为此目的使用IndexReader.termDocs()
,它适用于单字词,但由于所有词都分别存储在索引中,因此它不适用于多词术语。
示例(取自this问题):我对术语“篮球”(甚至“篮球”)的频率感兴趣,但在标记后会有两个字,我将能够得到术语“篮子”和术语“球”的频率,但不能用术语“篮球”。
我知道我想要获得频率的所有多字词,我也不想存储原始文本 - 仅用于获取统计数据。所以,我的第一个方法是连接术语中的单词。例如。 “昨天我玩篮球”变成“我昨天打了篮球”和“我最喜欢的作家是 Kurt Vonnegut ”成为“我最喜欢的作家是库尔特·冯内古特”。这个工作:连接术语被视为任何其他单个单词,所以我可以轻松获得频率。但是这种方法很丑陋,更重要的是,这种方法很慢。所以我来到另一个。
我的第二个方法是编写特殊令牌过滤器,它会捕获令牌并检查它们是否属于要替换的术语(类似SynonymFilter
来自Lucene in Action)。在我们的例子中,当过滤器将看到单词“basket”时,它将再读取一个标记,如果它是“ball”,过滤器将放置一个术语(“篮球”)而不是两个(“篮子”和“球”)输出令牌流。与之前的方法相比,此方法的优点在于,它搜索完整单词之间的匹配,并且不扫描子串的全文。事实上,大多数令牌将具有不同的长度,因此将被丢弃,甚至不检查其中任何字母的对应关系。但是这样的过滤器不易编写,而且,我不确定它是否足够快以满足我的需求。
第三种方法是在相同的文档中使用两个单词的位置。但最有可能的是,它会涉及在获取频率时间期间迭代TermDocs
,这比索引时间要多得多。
所以,最后,我的问题是:有没有办法在Lucene中有效地索引并获得多字词的频率?