Как увеличить смещения позиции в индексе люцены, чтобы они соответствовали тегам <p>? - PullRequest
7 голосов
/ 22 апреля 2011

Я использую Lucene 3.0.3. Готовясь к использованию SpanQuery и PhraseQuery, я хотел бы отметить границы абзаца в моем индексе таким образом, чтобы не допустить совпадения этих запросов между границами абзаца. Я понимаю, что мне нужно увеличить позицию на некоторое подходящее большое значение в PositionIncrementAttribute при обработке текста, чтобы отметить границы абзаца. Давайте предположим, что в исходном документе мои границы абзаца отмечены парами <p>...</p>.

Как настроить поток токенов для обнаружения тегов? Кроме того, я не хочу индексировать сами теги. Для целей индексации я бы предпочел увеличить позицию следующего легитимного токена, а не выдавать токен, соответствующий тегу, поскольку я не хочу, чтобы он влиял на поиск.

1 Ответ

9 голосов
/ 22 апреля 2011

Самый простой способ добавить пробелы (= PositionIncrement> 1) - предоставить собственный TokenStream.Вам не нужно менять свой анализатор для этого.Тем не менее, разбор HTML должен выполняться в восходящем направлении (т. Е. Вы должны сегментировать и очищать введенный текст соответствующим образом перед передачей его в Lucene).

Вот полный рабочий пример (импорт исключен):

public class GapTest {

    public static void main(String[] args) throws Exception {
        final Directory dir = new RAMDirectory();
        final IndexWriterConfig iwConfig = new IndexWriterConfig(Version.LUCENE_4_10_1, new SimpleAnalyzer());
        final IndexWriter iw = new IndexWriter(dir, iwConfig);

        Document doc = new Document();
        doc.add(new TextField("body", "A B C", Store.YES));
        doc.add(new TextField("body", new PositionIncrementTokenStream(10)));
        doc.add(new TextField("body", "D E F", Store.YES));

        System.out.println(doc);
        iw.addDocument(doc);
        iw.close();

        final IndexReader ir = DirectoryReader.open(dir);
        IndexSearcher is = new IndexSearcher(ir);

        QueryParser qp = new QueryParser("body", new SimpleAnalyzer());

        for (String q : new String[] { "\"A B C\"", "\"A B C D\"",
                "\"A B C D\"", "\"A B C D\"~10", "\"A B C D E F\"~10",
                "\"A B C D F E\"~10", "\"A B C D F E\"~11" }) {
            Query query = qp.parse(q);
            TopDocs docs = is.search(query, 10);
            System.out.println(docs.totalHits + "\t" + q);
        }
        ir.close();
    }

    /**
     * A gaps-only TokenStream (uses {@link PositionIncrementAttribute}
     * 
     * @author Christian Kohlschuetter
     */
    private static final class PositionIncrementTokenStream extends TokenStream {
    private boolean first = true;
    private PositionIncrementAttribute attribute;
    private final int positionIncrement;

    public PositionIncrementTokenStream(final int positionIncrement) {
        super();
        this.positionIncrement = positionIncrement;
        attribute = addAttribute(PositionIncrementAttribute.class);
    }

    @Override
    public boolean incrementToken() throws IOException {
        if (first) {
            first = false;
            attribute.setPositionIncrement(positionIncrement);
            return true;
        } else {
            return false;
        }
    }

    @Override
    public void reset() throws IOException {
        super.reset();
        first = true;
    }
}

}

...