我正在使用Lucene直接搜索联系人,查找人员数据库的常规联系信息,例如姓名,电话号码,地址等。此问题特别适用于按名字和姓氏搜索。这是我如何索引名称。
document.add(new Field("firstName", contact.getFirstName(), Field.Store.NO, Field.Index.NOT_ANALYZED));
document.add(new Field("lastName", contact.getLastName(), Field.Store.NO, Field.Index.NOT_ANALYZED));
我正在搜索索引:
IndexReader indexReader = IndexReader.open(FSDirectory.open(directory));
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
int hitsPerPage = indexSearcher.maxDoc();
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_35);
String[] fields = {"id", "firstName", "lastName", "phoneNumber", "email", "address", "website"};
BooleanQuery booleanQuery = new BooleanQuery();
String[] terms = queryString.split(" ");
for(String term : terms) {
for(String field : fields) {
booleanQuery.add(new FuzzyQuery(new Term(field, term)), BooleanClause.Occur.SHOULD);
}
}
TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, true);
indexSearcher.search(booleanQuery, collector);
ScoreDoc[] hits = collector.topDocs().scoreDocs;
我使用布尔查询而不是MultiFieldQuery的原因是因为它允许我在字段不精确时获得结果。基本上我用空格分割查询字符串,然后在索引中的每个字段上为每个关键字添加术语。我是Lucene的新手,所以我真的不知道这是否是最佳方式,但到目前为止,它对我来说还不错。
我唯一的打嗝是,当按全名搜索时,它不会以正确的顺序返回结果。
索引有2条记录,John Doe和John Smith。
当我搜索John Doe时,我的结果将如下所示: 1)约翰史密斯 2)John Doe
如果我输入John Smith,它将反转并首先显示John Doe。为什么它没有返回完全匹配作为第一个结果?
答案 0 :(得分:0)
如果要在所有字段中搜索所有字词,为什么不将整个文本编入索引作为另一个字段的一部分?然后你可以发出像
这样的查询/*
\\\\ is for escaping "
*/
String searchCriteria = "all:\\\\"John Doe\\\\"^3 OR all:(John Doe)";
IndexSearcher is = new IndexSearcher(indexDirectory);
Analyzer analyzer = new StandardAnalyzer();
QueryParser parser = new QueryParser("all", analyzer);
Query query = parser.parse(searchCriteria);
TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, true);
indexSearcher.search(query, collector);
ScoreDoc[] hits = collector.topDocs().scoreDocs;
但是,如果您想继续使用当前的设计,可以尝试http://lucene.apache.org/java/3_5_0/api/all/org/apache/lucene/search/IndexSearcher.html#explain(org.apache.lucene.search.Query,int)来找出文档得分高于其他文档的原因。
答案 1 :(得分:0)
使用布尔查询和for循环结果是在我的情况下搜索索引的正确方法。由于我在客户端解析和显示它们的方式,结果被颠倒了所以这是一个完全不相关的问题。