2

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);
}
}
4

2 に答える 2

0

Lucene Query 構文規則を参照して、 の検索を強制する方法を確認できますTest Engineer

基本的に、次のようなクエリを使用します

 AB4_Test AND Eng_AA0XY11

確かではありませんが、動作する可能性があります。上記のリンク先のページは非常に簡潔で、ニーズを満たすクエリをすばやく見つけることができます。

于 2012-09-19T11:17:58.697 に答える