5

Tôi đang sử dụng lớp Highlighter của Lucene để làm nổi bật các đoạn kết quả tìm kiếm phù hợp và nó hoạt động tốt. Tôi muốn chuyển từ tìm kiếm với StandardAnalyzer sang EnglishAnalyzer, điều này sẽ thực hiện các thuật ngữ.Lucene Highlighter với máy phân tích gốc

Kết quả tìm kiếm rất tốt, nhưng giờ đây, công cụ đánh dấu không phải lúc nào cũng tìm thấy kết quả phù hợp. Dưới đây là một ví dụ về những gì tôi đang tìm kiếm tại địa chỉ:

document field text 1: Everyone likes goats. 

document field text 2: I have a goat that eats everything. 

Sử dụng EnglishAnalyzer và tìm kiếm cho "dê", cả hai tài liệu được kết hợp, nhưng highlighter chỉ có thể tìm thấy một mảnh vỡ phù hợp từ tài liệu 2. Có một cách để có dữ liệu trả về highlighter cho cả hai tài liệu?

Tôi hiểu rằng các ký tự khác nhau đối với các mã thông báo, nhưng cùng một mã thông báo vẫn còn ở đó, vì vậy có vẻ hợp lý để chỉ làm nổi bật bất kỳ mã thông báo nào có mặt tại vị trí đó.

Nếu được, điều này đang sử dụng Lucene 3.5.

Trả lời

7

Tôi đã tìm thấy giải pháp cho vấn đề này. Tôi đã thay đổi từ sử dụng lớp Highlighter sang sử dụng FastVectorHighlighter. Có vẻ như tôi cũng sẽ nhận một số cải tiến về tốc độ (với chi phí lưu trữ dữ liệu vectơ hạn). Vì lợi ích của bất kỳ ai gặp phải câu hỏi này sau, đây là bài kiểm tra đơn vị cho thấy cách tất cả hoạt động cùng nhau:

package com.sample.index; 

import org.apache.lucene.analysis.Analyzer; 
import org.apache.lucene.analysis.en.EnglishAnalyzer; 
import org.apache.lucene.document.Document; 
import org.apache.lucene.document.Field; 
import org.apache.lucene.index.IndexReader; 
import org.apache.lucene.index.IndexWriter; 
import org.apache.lucene.index.IndexWriterConfig; 
import org.apache.lucene.queryParser.ParseException; 
import org.apache.lucene.queryParser.QueryParser; 
import org.apache.lucene.search.IndexSearcher; 
import org.apache.lucene.search.Query; 
import org.apache.lucene.search.ScoreDoc; 
import org.apache.lucene.search.TopDocs; 
import org.apache.lucene.search.vectorhighlight.*; 
import org.apache.lucene.store.RAMDirectory; 
import org.apache.lucene.util.Version; 
import org.junit.Before; 
import org.junit.Test; 

import java.io.IOException; 
import java.util.ArrayList; 
import java.util.List; 

import static junit.framework.Assert.assertEquals; 

public class TestIndexStuff { 
    public static final String FIELD_NORMAL = "normal"; 
    public static final String[] PRE_TAGS = new String[]{"["}; 
    public static final String[] POST_TAGS = new String[]{"]"}; 
    private IndexSearcher searcher; 
    private Analyzer analyzer = new EnglishAnalyzer(Version.LUCENE_35); 

    @Before 
    public void init() throws IOException { 
     RAMDirectory idx = new RAMDirectory(); 
     IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_35, analyzer); 

     IndexWriter writer = new IndexWriter(idx, config); 
     addDocs(writer); 
     writer.close(); 

     searcher = new IndexSearcher(IndexReader.open(idx)); 
    } 

    private void addDocs(IndexWriter writer) throws IOException { 
     for (String text : new String[] { 
       "Pretty much everyone likes goats.", 
       "I have a goat that eats everything.", 
       "goats goats goats goats goats"}) { 
      Document doc = new Document(); 
      doc.add(new Field(FIELD_NORMAL, text, Field.Store.YES, 
        Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); 
      writer.addDocument(doc); 
     } 
    } 

    private FastVectorHighlighter makeHighlighter() { 
     FragListBuilder fragListBuilder = new SimpleFragListBuilder(200); 
     FragmentsBuilder fragmentBuilder = new SimpleFragmentsBuilder(PRE_TAGS, POST_TAGS); 
     return new FastVectorHighlighter(true, true, fragListBuilder, fragmentBuilder); 
    } 

    @Test 
    public void highlight() throws ParseException, IOException { 
     Query query = new QueryParser(Version.LUCENE_35, FIELD_NORMAL, analyzer) 
        .parse("goat"); 
     FastVectorHighlighter highlighter = makeHighlighter(); 
     FieldQuery fieldQuery = highlighter.getFieldQuery(query); 

     TopDocs topDocs = searcher.search(query, 10); 
     List<String> fragments = new ArrayList<String>(); 
     for (ScoreDoc scoreDoc : topDocs.scoreDocs) { 
      fragments.add(highlighter.getBestFragment(fieldQuery, searcher.getIndexReader(), 
        scoreDoc.doc, FIELD_NORMAL, 10000)); 
     } 

     assertEquals(3, fragments.size()); 
     assertEquals("[goats] [goats] [goats] [goats] [goats]", fragments.get(0).trim()); 
     assertEquals("Pretty much everyone likes [goats].", fragments.get(1).trim()); 
     assertEquals("I have a [goat] that eats everything.", fragments.get(2).trim()); 
    } 
} 
Các vấn đề liên quan