0

我正在使用 Lucene 进行用户搜索。对于索引,我有以下代码

private void internalAddUser(User user) throws IOException {
    Document document = new Document();
    document.add(new Field("login", user.getLogin(), Field.Store.YES, Field.Index.NOT_ANALYZED));
    document.add(new Field("firstName", user.getFirstName(), Field.Store.YES, Field.Index.NOT_ANALYZED));
    document.add(new Field("lastName", user.getLastName(), Field.Store.YES, Field.Index.NOT_ANALYZED));
    userIndexWriter.addDocument(document);
}

对于搜索,我使用以下代码,但没有得到任何结果。

@Override
@Cacheable("user-prefix-cache")
public Collection<String> searchUserByPrefix(String prefix) {
    IndexSearcher searcher = null;
    List<String> logins = new ArrayList<String>();
    try {
        searcher = userSearcherManager.acquire();

        BooleanQuery booleanQuery = new BooleanQuery();

        Query query1 = new TermQuery(new Term("login", prefix));
        Query query2 = new TermQuery(new Term("firstName", prefix));
        Query query3 = new TermQuery(new Term("lastName", prefix));

        booleanQuery.add(query1, BooleanClause.Occur.SHOULD);
        booleanQuery.add(query2, BooleanClause.Occur.SHOULD);
        booleanQuery.add(query3, BooleanClause.Occur.SHOULD);

        SortField sortField = new SortField("login", SortField.STRING, true);
        Sort sort = new Sort(sortField);

        TopDocs topDocs = searcher.search(booleanQuery, DEFAULT_TOP_N_SEARCH_USER, sort);
        int totalHits = topDocs.totalHits;
        if (totalHits == 0) {
            return new ArrayList<String>();
        }

        ScoreDoc[] scoreDocArray = topDocs.scoreDocs;
        for (int i = 0; i < scoreDocArray.length; i++) {
            int documentId = scoreDocArray[i].doc;
            Document document = searcher.doc(documentId);
            logins.add(document.get("login"));
        }
    } catch (IOException e) {
        log.error("A Lucene query had a I/O error : " + e.getMessage());
        if (log.isDebugEnabled()) {
            e.printStackTrace();
        }
    } finally {
        try {
            userSearcherManager.release(searcher);
        } catch (IOException e) {
            log.error("The Lucene searcher could not be given back to the searcherManager pool. " +
                    e.getMessage());

            if (log.isDebugEnabled()) {
                e.printStackTrace();
            }
        }
    }
    return logins;
}

我不是一个 lucene 期望,但我不确定它为什么不工作。有没有人有任何想法。

[DEBUG] in.daydiary.web.rest.SearchController - REST request to find users starting with : j
[DEBUG] in.daydiary.web.rest.SearchController - REST request to find users starting with : j
[DEBUG] in.daydiary.web.rest.SearchController - REST request to find users starting with : ju
[DEBUG] in.daydiary.web.rest.SearchController - REST request to find users starting with : jul
[DEBUG] in.daydiary.web.rest.SearchController - REST request to find users starting with : juli
[DEBUG] in.daydiary.web.rest.SearchController - REST request to find users starting with : julia
[DEBUG] in.daydiary.web.rest.SearchController - REST request to find users starting with : julianb
[DEBUG] in.daydiary.web.rest.SearchController - REST request to find users starting with : julianb
[DEBUG] in.daydiary.web.rest.SearchController - REST request to find users starting with : julian
[DEBUG] in.daydiary.web.rest.SearchController - REST request to find users starting with : julia
[DEBUG] in.daydiary.web.rest.SearchController - REST request to find users starting with : juli
[DEBUG] in.daydiary.web.rest.SearchController - REST request to find users starting with : jul
[DEBUG] in.daydiary.web.rest.SearchController - REST request to find users starting with : ju
[DEBUG] in.daydiary.web.rest.SearchController - REST request to find users starting with : j
4

2 回答 2

1

这里有两件事看起来很可疑。

您的所有字段都是Field.Index.NOT_ANALYZED. 这意味着它们不会被标记化,而只会匹配整个字段上的完全匹配,正如您在此处搜索的那样。这也将区分大小写。准确查看索引了哪些数据以及您要查询的内容将有助于了解这是否真的是问题所在。

其次,您的方法名称表明您需要前缀搜索,但您没有使用前缀搜索。ATermQuery只会得到完全匹配。APrefixQuery将用于按前缀搜索,其使用方式与 TermQuery 完全相同:

    Query query1 = new PrefixQuery(new Term("login", prefix));
    booleanQuery.add(query1, BooleanClause.Occur.SHOULD);
于 2013-09-06T15:22:38.140 回答
0

第一的。注意提供lucene版本。

第二。您当然可以看到索引。获取和Lucene相同版本的luke..就可以看到luke里面的索引数据了..执行java -jar jarname即可运行。

第三。检查在索引过程中使用的Analyzer和在搜索过程中使用的Analyzer是否相同。这是每个人都犯的一个很常见的错误。

第四。由于您没有受到打击,请参考这个优秀的链接,其中提到了一些可能导致找不到 HITS 的点。

http://wiki.apache.org/lucene-java/LuceneFAQ#Why_am_I_getting_no_hits_.2F_incorrect_hits.3F

于 2013-09-12T12:54:39.920 回答