我正在使用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
答案 0 :(得分:1)
这里有两件事看起来很可疑。
您的所有字段均为Field.Index.NOT_ANALYZED
。这意味着它们不会被标记化,而只会匹配整个字段上的完全匹配,就像您在此处搜索一样。这也是区分大小写的。准确查看索引的数据以及您要查询的内容将有助于了解这是否真的是问题。
其次,您的方法名称表示您需要前缀搜索,但您没有使用前缀搜索。 TermQuery
只能获得完全匹配。 PrefixQuery
将用于按前缀搜索,其使用方式与TermQuery完全相同:
Query query1 = new PrefixQuery(new Term("login", prefix));
booleanQuery.add(query1, BooleanClause.Occur.SHOULD);
答案 1 :(得分:0)
首先。谨慎提供lucene版本。
第二。你当然可以看到索引。获取与Lucene相同版本的版本。您将能够在luke中看到索引数据。只需执行java -jar jarname就可以运行它。
第三。检查在搜索过程中使用的索引过程和分析器期间使用的 Analyzer 是否相同。这是每个人都犯的一个非常常见的错误。< / p>
第四。由于您没有受到打击,请参阅此优秀链接,其中提到可能导致未找到HITS的一些要点。
http://wiki.apache.org/lucene-java/LuceneFAQ#Why_am_I_getting_no_hits_.2F_incorrect_hits.3F