PhraseQuery不工作Lucene 4.5.0

时间:2013-12-29 15:47:49

标签: java lucene

我尝试使用PhraseQuery,但无法从搜索中获得点击量。我正在使用Lucene 4.5.0

我的索引代码

private IndexWriter writer;

public LuceneIndexSF(final String indexDir) throws IOException {
    Analyzer analyzer = new KeywordAnalyzer();
    IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_45,
            analyzer);
    Directory directory = FSDirectory.open(new File(indexDir));
    writer = new IndexWriter(directory, config);
}
private Document getDocument(File f, String line, int lineNum)
            throws IOException {
        Document doc = new Document();
        Field field = null;
        if (line != null && line.split(DELIMITER).length >= 5) {
            String[] lineValues = line.split(DELIMITER);
            field = new Field("name", line.split("\t")[1],
                    TextField.TYPE_STORED);
            doc.add(field);
            if (lineValues[2] != null && !lineValues[2].trim().isEmpty()) {
                field = new Field("ref", lineValues[2], TextField.TYPE_STORED);
                doc.add(field);
            }
            field = new Field("type", lineValues[3], TextField.TYPE_STORED);
            doc.add(field);
            field = new LongField("code", Long.parseLong(lineValues[4]),
                    LongField.TYPE_STORED);
            doc.add(field);
            if (lineValues.length == 7 && lineValues[5] != null
                    && !lineValues[5].trim().isEmpty()) {
                field = new Field("alias1", lineValues[5],
                        TextField.TYPE_STORED);
                doc.add(field);
            }
            if (lineValues.length == 7 && lineValues[6] != null
                    && !lineValues[6].trim().isEmpty()) {
                field = new Field("alias2", lineValues[6],
                        TextField.TYPE_STORED);
                doc.add(field);
            }
        }
        field = new IntField("linenum", lineNum, IntField.TYPE_STORED);
        doc.add(field);
        return doc;
    }
.... and other code where i add document in writer using writer.addDocument(doc);

我的搜索代码

private static void search(String indexDir, String quer) throws IOException,
        ParseException {
    IndexReader inxRead = DirectoryReader.open(FSDirectory.open(new File(
            indexDir)));
    IndexSearcher is = new IndexSearcher(inxRead);
    String[] termArr = quer.split(" ");
    PhraseQuery phraseQuery= new PhraseQuery();
    for(int inx = 0; inx < termArr.length; inx++){
        phraseQuery.add(new Term("name", termArr[inx]));
    }
    phraseQuery.setSlop(4);
    long start = System.currentTimeMillis();
    TopDocs hits = is.search(phraseQuery, 1000);
    long end = System.currentTimeMillis();
    System.err.println("Parser> Found " + hits.totalHits
            + " document(s) (in " + (end - start)
            + " milliseconds) that matched query '" + multiQuery + "':");
    for (ScoreDoc scoreDoc : hits.scoreDocs) {
        Document doc = is.doc(scoreDoc.doc);
        System.out.println("Parser> " + scoreDoc.score + " :: "
                + doc.get("type") + " - " + doc.get("code") + " - "
                + doc.get("name") + ", " + doc.get("linenum"));
    }
    inxRead.close();
}

如果我做错了,请告诉我。

修改

还尝试使用标准分析器仍然没有结果

Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_45);

解决方案

根据Arun的回答PhraseQuery要正常工作,需要分析器对Document的{​​{1}}中的每个单词进行标记,对于我的情况,我使用Field将所有查询设为小写这样它可以在没有区分大小写的情况下工并使用LowerCaseFilter进行自动完成。

EdgeNGramTokenFilter

我的最终搜索方法

public LuceneIndexSF(final String indexDir) throws IOException {
Analyzer analyzer = new Analyzer() {
        @Override
        protected TokenStreamComponents createComponents(String fieldName,
                java.io.Reader reader) {
            Tokenizer source = new StandardTokenizer(Version.LUCENE_45,
                    reader);
            TokenStream result = new StandardFilter(Version.LUCENE_45,
                    source);
            result = new LowerCaseFilter(Version.LUCENE_45, result);
            result = new EdgeNGramTokenFilter(Version.LUCENE_45, result, 1,
                    20);
            return new TokenStreamComponents(source, result);
        }
    };
IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_45,
        analyzer);
Directory directory = FSDirectory.open(new File(indexDir));
writer = new IndexWriter(directory, config);
}

1 个答案:

答案 0 :(得分:1)

我使用KeywordAnalyzer玩你的代码,显然它不能用作KeywordAnalyzer“整数”整个流作为单个标记。这对于邮政编码,ID和某些产品名称等数据非常有用。 http://lucene.apache.org/core/4_5_0/analyzers-common/org/apache/lucene/analysis/core/KeywordAnalyzer.html,为此,您需要指定整个令牌而不做任何更改。

然后我使用了WhitespaceAnalyzer,它能够找到你的PhraseQuery匹配。其余代码没有变化。如果这对您有用,请告诉我。

搜索与MultiFieldQueryParser一起使用的原因是您在查询时被迫使用分析器与您的索引匹配。简而言之,您需要确保您的索引分析器和查询时间分析器是相似的。