2012-02-28 32 views
0

Lucene_35でフィールドを検索しています。私は、自分の言葉からいくつの単語がフィールドに一致するかを知りたい。 たとえば、私のフィールドはです。「JavaServer Faces(JSF)は、Webベースのユーザーインターフェイスの開発統合を簡素化するためのJavaベースのWebアプリケーションフレームワークです。、私のクエリ用語はの "Java/JSF /フレームワーク/のDoesNotExist"であり、唯一のの "Java""JSF""フレームワーク" 以来3を引き起こすたいフィールドに存在しています。ここ は、私は、次の午前の簡単な例である:私はこの3を取得したいLuceneの一致用語を一致させる

0.021505041 = (MATCH) product of: 
    0.028673388 = (MATCH) sum of: 
    0.0064956956 = (MATCH) weight(title:java in 0), product of: 
     0.2709602 = queryWeight(title:java), product of: 
     0.30685282 = idf(docFreq=1, maxDocs=1) 
     0.8830299 = queryNorm 

....

 0.033902764 = (MATCH) fieldWeight(title:framework in 0), product of: 
     1.4142135 = tf(termFreq(title:framework)=2) 
     0.30685282 = idf(docFreq=1, maxDocs=1) 
     0.078125 = fieldNorm(field=title, doc=0) 
    0.75 = coord(3/4) 

:上記のパラメータを持つ

public void explain(String document, String queryExpr) throws Exception { 

     StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_35); 
     Directory index = new RAMDirectory(); 
     IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_35, analyzer); 
     IndexWriter w = new IndexWriter(index, config); 
     addDoc(w, document); 
     w.close(); 
     String queryExpression = queryExpr; 
     Query q = new QueryParser(Version.LUCENE_35, "title", analyzer).parse(queryExpression); 

     System.out.println("Query: " + queryExpression); 
     IndexReader reader = IndexReader.open(index); 
     IndexSearcher searcher = new IndexSearcher(reader); 
     TopDocs topDocs = searcher.search(q, 10); 
     for (int i = 0; i < topDocs.totalHits; i++) { 
      ScoreDoc match = topDocs.scoreDocs[i]; 
      System.out.println("match.score: " + match.score); 
      Explanation explanation = searcher.explain(q, match.doc); //#1 
      System.out.println("----------"); 
      Document doc = searcher.doc(match.doc); 
      System.out.println(doc.get("title")); 
      System.out.println(explanation.toString()); 
     } 
     searcher.close(); 
    } 

出力されます/ 4となる。

よろしくお願いいたします。

+0

Luceneとはどのような関係がありますか? – jpountz

+0

申し訳ありませんjpountz、どういう意味ですか?私はLUCENE_35とRAMDirectoryインデックスを使用しています。今私は、私が必要としているものを正確に与えてくれるが、そのcoord factorをどうやって得るのか分からないcoord因子があることに気づいた。 –

+0

あなたの質問にはLuceneは言及されていませんでしたので、私はあなたの質問がLuceneと何をしているかはわかりませんでした。達成しようとしていることの詳細について質問を編集できますか?インデックスはどのように構造化されていますか?マッチの数に応じて文書をソートしますか? – jpountz

答えて

7

あなたは、次のメソッド定義でLuceneのDefaultSimilarityをオーバーライドすることによってこれを達成することができます - > state.getBoost()

  • TF(FREQ) -

    • computeNorm(フィールド、状態)> FREQ == 0 ? 0:1つの
    • IDF(docFreq、numDocs) - > 1
    • COORD(重複、maxOverlap) - > 1/maxOverlap
    • queryNorm(sumOfQuareWeights) - > 1

    このように、最終的な文書のスコアは、coor factor(1/maxOverlap)に一致する用語の数を掛けたものになります。

    Directory dir = new RAMDirectory(); 
    
    Similarity similarity = new DefaultSimilarity() { 
        @Override 
        public float computeNorm(String fld, FieldInvertState state) { 
        return state.getBoost(); 
        } 
    
        @Override 
        public float coord(int overlap, int maxOverlap) { 
        return 1f/maxOverlap; 
        } 
    
        @Override 
        public float idf(int docFreq, int numDocs) { 
        return 1f; 
        } 
    
        @Override 
        public float queryNorm(float sumOfSquaredWeights) { 
        return 1f; 
        } 
    
        @Override 
        public float tf(float freq) { 
        return freq == 0f ? 0f : 1f; 
        } 
    }; 
    IndexWriterConfig iwConf = new IndexWriterConfig(Version.LUCENE_35, 
        new WhitespaceAnalyzer(Version.LUCENE_35)); 
    iwConf.setSimilarity(similarity); 
    IndexWriter iw = new IndexWriter(dir, iwConf); 
    Document doc = new Document(); 
    Field field = new Field("text", "", Store.YES, Index.ANALYZED); 
    doc.add(field); 
    for (String value : Arrays.asList("a b c", "c d", "a b d", "a c d")) { 
        field.setValue(value); 
        iw.addDocument(doc); 
    } 
    iw.commit(); 
    iw.close(); 
    
    IndexReader ir = IndexReader.open(dir); 
    IndexSearcher searcher = new IndexSearcher(ir); 
    searcher.setSimilarity(similarity); 
    BooleanQuery q = new BooleanQuery(); 
    q.add(new TermQuery(new Term("text", "a")), Occur.SHOULD); 
    q.add(new TermQuery(new Term("text", "b")), Occur.SHOULD); 
    q.add(new TermQuery(new Term("text", "d")), Occur.SHOULD); 
    
    TopDocs topDocs = searcher.search(q, 100); 
    System.out.println(topDocs.totalHits + " results"); 
    ScoreDoc[] scoreDocs = topDocs.scoreDocs; 
    for (int i = 0; i < scoreDocs.length; ++i) { 
        int docId = scoreDocs[i].doc; 
        float score = scoreDocs[i].score; 
        System.out.println(ir.document(docId).get("text") + " -> " + score); 
        System.out.println(searcher.explain(q, docId)); 
    } 
    ir.close(); 
    
  • +0

    ありがとう、あなたは非常にjpountz!私の場合、今結果を取得する方法を教えてください。それは私の最初の日Lucine、それについて申し訳ありません:) –

    +0

    こんにちはトス、私は詳細で私の答えを更新しました。 – jpountz

    +0

    ありがとう、jpountz! –

    関連する問題