Lucene を使用して、キーワードをアプリケーション内の単語のリストと照合しています。プロセス全体は、人間の介入なしで自動化されています。Lucene から返された結果リストから、最も一致した結果 (トップで最高のスコアのもの) が選択されます。
次のコードは上記の機能を示し、結果はコンソールに出力されます。
問題 :
問題は、lucene がキーワード (検索する単語) を検索し、その結果、キーワードに部分的に一致する単語が返されることです。一方、完全一致の結果も存在し、1 位にはランクインしません。
たとえば、「Test」と「Test Engineer」という単語を含む lucene RAM インデックスがあるとします。「AB4_Test Eng_AA0XY11」のインデックスを検索したい場合、結果は次のようになります
テスト
テスト エンジニア
「AB4_Test Eng_AA0XY11」の Eng は Engineer に一致しましたが (結果に表示されるのはそのためです)。しかし、トップの座を獲得することはできません。「テスト エンジニア」がキーワード全体を考慮したベスト マッチであるため、「テスト エンジニア」が最上位になるようにソリューションを最適化したいと考えています。この問題を解決するのを手伝ってくれる人はいますか?
public class LuceneTest {
private static void search(Set<String> keywords) {
StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_36);
try {
// 1. create the index
Directory luceneIndex = buildLuceneIndex(analyzer);
int hitsPerPage = 5;
IndexReader reader = IndexReader.open(luceneIndex);
for(String keyword : keywords) {
// Create query string. replace all underscore, hyphen, comma, ( , ), {, }, . with plus sign
StringBuilder querystr = new StringBuilder(128);
String [] splitName = keyword.split("[\\-_,/(){}:. ]");
// After tokenizing also add plus sign between each camel case word.
for (String token : splitName) {
querystr.append(token + "+");
}
// 3. search
IndexSearcher searcher = new IndexSearcher(reader);
TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, true);
Query q = new QueryParser(Version.LUCENE_36, "name", analyzer).parse(querystr.toString());
searcher.search(q, collector);
ScoreDoc[] hits = collector.topDocs().scoreDocs;
System.out.println();
System.out.println(keyword);
System.out.println("----------------------");
for (ScoreDoc scoreDoc : hits) {
Document d = searcher.doc(scoreDoc.doc);
System.out.println("Found " + d.get("id") + " : " + d.get("name"));
}
// searcher can only be closed when there
searcher.close();
}
}catch (Exception e) {
e.printStackTrace();
}
}
/**
*
*/
private static Directory buildLuceneIndex(Analyzer analyzer) throws CorruptIndexException, LockObtainFailedException, IOException{
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(1, "Test Engineer");
map.put(2, "Test");
Directory index = new RAMDirectory();
IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_36, analyzer);
// 1. create the index
IndexWriter w = new IndexWriter(index, config);
for (Map.Entry<Integer, String> entry : map.entrySet()) {
try {
Document doc = new Document();
doc.add(new Field("id", entry.getKey().toString(), Field.Store.YES, Field.Index.ANALYZED));
doc.add(new Field("name", entry.getValue() , Field.Store.YES, Field.Index.ANALYZED));
w.addDocument(doc);
}catch (Exception e) {
e.printStackTrace();
}
}
w.close();
return index;
}
public static void main(String[] args) {
Set<String> list = new TreeSet<String>();
list.add("AB4_Test Eng_AA0XY11");
list.add("AB4_Test Engineer_AA0XY11");
search(list);
}
}