在文本中查找常用短语

时间:2015-07-30 14:44:34

标签: lucene

有没有办法搜索Lucene的常用短语?

我成功搜索了频繁的单词:

TermStats[] ts = HighFreqTerms.getHighFreqTerms(reader, 20, fieldName, comparator);

但是这会带来单个单词,而我正在寻找一种搜索频繁的两个(或任意数字)单词组合的方法。

为了澄清,我不是在寻找我所知道的前两个单词(例如快速和汽车),而是排在前两个频繁的单词组合。所以,如果我的文字是"这是一辆快车,这也是一辆快车"我得到的结果是"快车"和"这是"是前两个单词组合。

我查看了讨论here,但它提供了solr的解决方案,我正在寻找Lucene的内容,并且无论如何相关链接都被破坏了。

编辑:关注femtoRgon的评论来自我Analyzer的一些代码。这是应该添加ShingleFilter的地方吗?它似乎不起作用,因为我的输出看起来像这样:

ed d 
d 
d   p
 p
 p pl  
pl
pl le

我需要的是输出包含完整单词对。

这是我的createComponents方法:

@Override
protected TokenStreamComponents createComponents(String fieldName, Reader reader) {
    Tokenizer source = new NGramTokenizer(Version.LUCENE_47, reader, 2, 2);     
    ShingleFilter sf = new ShingleFilter(source, 2, 2);

    TokenStreamComponents tsc = new TokenStreamComponents(source, sf);  
    return tsc;
}

EDIT2:我在femtoRgon的评论之后将NGramTokenizer更改为StandardTokenizer,现在我得到了完整的文字,但我不需要单词,只是对。

这是代码:

Tokenizer source = new StandardTokenizer(Version.LUCENE_47, reader);        
ShingleFilter sf = new ShingleFilter(source, 2, 2);

注意2, 2根据文档应生成最小单词2,最大单词为2.但实际上它会生成此输出:

and
and other
other
other airborne
airborne
airborne particles

那么如何摆脱单个单词并获得此输出呢?

and other
other airborne
airborne particles

1 个答案:

答案 0 :(得分:0)

这是完成这项工作的完整Analyzer课程。请注意,TokenStreamComponents方法是在femtoRgon对我的问题提出优秀评论后声明ShingleFilter的方法。只需输入您自己的字符串,指定minWordsmaxWords并运行它。

public class RMAnalyzer extends Analyzer {

    public static String someString = "some string";
    private int minWords = 2;
    private int maxWords = 2;


    public static void main(String[] args) {
        RMAnalyzer rma = new RMAnalyzer(2, 2);
        rma.findFrequentTerms();
        rma.close();
    }


    public RMAnalyzer(int minWords, int maxWords) { 
        this.minWords = minWords;
        this.maxWords = maxWords;
    }

    public void findFrequentTerms() {
        StringReader sr = new StringReader(someString);
        try {
            TokenStream tokenStream = tokenStream("title", sr);
            OffsetAttribute offsetAttribute = tokenStream.addAttribute(OffsetAttribute.class);
            CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);
            tokenStream.reset();

            while (tokenStream.incrementToken()) {
                String term = charTermAttribute.toString();
                System.out.println(term);
            }                       
        } catch(Exception e) {
            e.printStackTrace();
        }
    }


    @Override
    protected TokenStreamComponents createComponents(String fieldName, Reader reader) {
        Tokenizer source = new StandardTokenizer(Version.LUCENE_47, reader);        
        ShingleFilter sf = new ShingleFilter(source, minWords, maxWords);
        sf.setOutputUnigrams(false); // makes it so no one word phrases out in the output.
        sf.setOutputUnigramsIfNoShingles(true); // if not enough for min, show anyway.

        TokenStreamComponents tsc = new TokenStreamComponents(source, sf);  
        return tsc;
    }
}