我正在尝试使用lucene搜索功能进行自动完成。我有下面的代码,它通过查询前缀进行搜索,但同时它也给了我包含该单词的所有句子,而我希望它只显示以该前缀开头的句子或单词。
ex: m --holiday m ansion船屋 - 眼睛 m uscles - m 有史以来的卵子 - 的米 achine
我希望它只显示最后2个查询。如何做到这里也被困在这里我也是lucene的新手。请任何人帮助我。提前谢谢。
addDoc(IndexWriter w, String title, String isbn) throws IOException {
Document doc = new Document();
doc.add(new Field("title", title, Field.Store.YES, Field.Index.ANALYZED));
// use a string field for isbn because we don't want it tokenized
doc.add(new Field("isbn", isbn, Field.Store.YES, Field.Index.ANALYZED));
w.addDocument(doc);
}
主:
try {
// 0. Specify the analyzer for tokenizing text.
// The same analyzer should be used for indexing and searching
StandardAnalyzer analyzer = new StandardAnalyzer();
// 1. create the index
Directory index = FSDirectory.open(new File(indexDir));
IndexWriter writer = new IndexWriter(index, new StandardAnalyzer(Version.LUCENE_30), true, IndexWriter.MaxFieldLength.UNLIMITED); //3
for (int i = 0; i < source.size(); i++) {
addDoc(writer, source.get(i), + (i + 1) + "z");
}
writer.close();
// 2. query
Term term = new Term("title", querystr);
//create the term query object
PrefixQuery query = new PrefixQuery(term);
// 3. search
int hitsPerPage = 20;
IndexReader reader = IndexReader.open(index);
IndexSearcher searcher = new IndexSearcher(reader);
TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, true);
searcher.search(query, collector);
ScoreDoc[] hits = collector.topDocs().scoreDocs;
// 4. Get results
for (int i = 0; i < hits.length; ++i) {
int docId = hits[i].doc;
Document d = searcher.doc(docId);
System.out.println(d.get("title"));
}
reader.close();
} catch (Exception e) {
System.out.println("Exception (LuceneAlgo.getSimilarString()) : " + e);
}
}
}
答案 0 :(得分:1)
如果我理解您的方案正确,您希望在标题字段上自动填充。
解决方案是有两个字段:一个是分析的,是为了能够对它进行查询,一个是非分析的,可以将标题编入索引,而不会将它们分成单个术语。 您的自动完成逻辑应针对未分析字段发出前缀查询,以仅匹配第一个字。您的术语查询应针对标题中匹配的分析字段发布。
我希望这是有道理的。
答案 1 :(得分:0)
我看到两个解决方案:
,保存标题字段两次,一次作为TextField(=已分析),一次作为StringField(未分析)
将其保存为TextField,但在查询时使用SpanFirstQuery
// 2. query Term term = new Term("title", querystr); //create the term query object PrefixQuery pq = new PrefixQuery(term); SpanQuery wrapper = new SpanMultiTermQueryWrapper<PrefixQuery>(pq); Query final = new SpanFirstQuery(wrapper, 1);