Lucene外卡搜索

时间:2014-02-21 12:15:35

标签: search lucene

如何在Lucene中执行通配符搜索?
我有文字:“1997_titanic”
如果我搜索“1997_titanic”,它会返回一个结果,但我无法在两次搜索中进行搜索:

1)如果我只用1997年搜索,则不会返回任何结果 2)如果有空间,例如“蜘蛛侠”,也没有找到任何结果。

我从数据库中检索所有电影信息并将其存储在Lucene Documents中:

public Document createMovieDoc(Movie m){
    document.add(new StoredField("moviename", m.getName()));  
    TextField field = new TextField("movienameSearch", m.getName().toLowerCase(),  Store.NO);
    field.setBoost(5.0f);
    document.add(field);
}

要搜索,我有这个方法:

public List searh(String txt){ 
    PhraseQuery phQuery= new PhraseQuery();
    Term term = new Term("movienameSearch", txt.toLowerCase());

    BooleanQuery b = new BooleanQuery();
    b.add(phQuery, Occur.SHOULD);

    TopFieldDocs tp= searcher.search(b, 20, ..);
    for(int i=0;i<tp.length;i++)      
    {
        int mId = tp[i].doc;
        Document d = searcher.doc(mId);
        String moviename = d.get("moviename");

        list.add(moviename);
    }
    return list;
}

1 个答案:

答案 0 :(得分:0)

我不确定您使用哪种分析仪进行索引。听起来像是WhitespaceAnalyzer?听起来,当索引“1997_titanic”仍然是单个令牌时,“蜘蛛侠”被分成令牌“蜘蛛”和“男人”。

也可以SimpleAnalyzer使用LetterTokenizer。这将使得无法搜索“1997”,因为该标记化器将消除文本的索引表示的所有数字。

您的搜索方法看起来不正确。您没有向PhraseQuery添加任何字词,因此我不希望它能找到任何内容。您必须add一些条款才能找到任何内容。您在所提供的内容中创建了Term,但该术语并未执行任何操作。也许这与你如何选择你的摘录或某事有关?不确定,我有点困惑。

为了手动构建PhraseQuery,您必须单独添加每个术语,因此要搜索“蜘蛛侠”,您可以执行以下操作:

PhraseQuery phQuery= new PhraseQuery();
phQuery.add(new Term("movienameSearch", "spider"));
phQuery.add(new Term("movienameSearch", "man"));

这需要您了解分析仪在索引时执行的操作,并自行标记输入以适应。更简单的解决方案是使用QueryParser

//With whatever analyzer you like to use.
QueryParser parser = new QueryParser(Version.LUCENE_46, "defaultField", analyzer);
Query query = parser.parse("movienameSearch:\"" + txt.toLowerCase() + "\"");
TopFieldDocs tp= searcher.search(query, 20);

这允许您依靠相同的分析器进行索引和查询,因此您不必知道如何将您的短语标记为适合。

就单独找到“1997”和“泰坦尼克号”而言,我建议只使用StandardAnalyzer。它会将它们标记为离散标记,使用简单的查询(例如movienameSearch:1997)可以非常轻松地搜索它们。