Как правильно получить срочные позиции в документе Lucene? - PullRequest
0 голосов
/ 23 ноября 2018

Пример в этом вопросе и некоторые другие, которые я видел в Интернете, используют postings метод TermVector для получения позиций терминов.Скопируйте вставку из примера в связанном вопросе:

IndexReader ir = obtainIndexReader();
Terms tv = ir.getTermVector( doc, field );
TermsEnum terms = tv.iterator();
PostingsEnum p = null;
while( terms.next() != null ) {
    p = terms.postings( p, PostingsEnum.ALL );
    while( p.nextDoc() != PostingsEnum.NO_MORE_DOCS ) {
        int freq = p.freq();
        for( int i = 0; i < freq; i++ ) {
            int pos = p.nextPosition();   // Always returns -1!!!
            BytesRef data = p.getPayload();
            doStuff( freq, pos, data ); // Fails miserably, of course.
        }
    }
}

Этот код работает для меня, но меня бесит то, что тип Terms хранит информацию о местоположении.Во всей документации, которую я видел, говорится, что векторы терминов хранят данные о местоположении.Тем не менее, нет методов этого типа, чтобы получить эту информацию!

В старых версиях Lucene, по-видимому, был метод, но, по крайней мере, в версии 6.5.1 Lucene это не так.

Вместо этого я должен использовать метод postings и просматривать документы, но я уже знаю, над каким документом я хочу работать!

В документации API ничего не говорится о сообщениях, возвращаемых толькотекущий документ (тот, к которому относится термин vector), но когда я его запускаю, я получаю только текущий документ.

Это правильный и единственный способ получить данные о положении из векторов терминов?Почему такой не интуитивный API?Есть ли документ, который объясняет, почему предыдущий подход изменился в пользу этого?

1 Ответ

0 голосов
/ 23 ноября 2018

Не знаю, "правильно или неправильно", но для версии 6.6.3 это похоже на работу.

private void run() throws Exception {
    Directory directory = new RAMDirectory();
    IndexWriterConfig indexWriterConfig = new IndexWriterConfig(new StandardAnalyzer());
    IndexWriter writer = new IndexWriter(directory, indexWriterConfig);

    Document doc = new Document();
    // Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.YES
    FieldType type = new FieldType();
    type.setStoreTermVectors(true);
    type.setStoreTermVectorPositions(true);
    type.setStoreTermVectorOffsets(true);
    type.setIndexOptions(IndexOptions.DOCS);

    Field fieldStore = new Field("tags", "foo bar and then some", type);
    doc.add(fieldStore);
    writer.addDocument(doc);
    writer.close();

    DirectoryReader reader = DirectoryReader.open(directory);
    IndexSearcher searcher = new IndexSearcher(reader);

    Term t = new Term("tags", "bar");
    Query q = new TermQuery(t);
    TopDocs results = searcher.search(q, 1);

    for ( ScoreDoc scoreDoc: results.scoreDocs ) {
        Fields termVs = reader.getTermVectors(scoreDoc.doc);
        Terms f = termVs.terms("tags");
        TermsEnum te = f.iterator();
        PostingsEnum docsAndPosEnum = null;
        BytesRef bytesRef;
        while ( (bytesRef = te.next()) != null ) {
            docsAndPosEnum = te.postings(docsAndPosEnum, PostingsEnum.ALL);
            // for each term (iterator next) in this field (field)
            // iterate over the docs (should only be one)
            int nextDoc = docsAndPosEnum.nextDoc();
            assert nextDoc != DocIdSetIterator.NO_MORE_DOCS;
            final int fr = docsAndPosEnum.freq();
            final int p = docsAndPosEnum.nextPosition();
            final int o = docsAndPosEnum.startOffset();
            System.out.println("p="+ p + ", o=" + o + ", l=" + bytesRef.length + ", f=" + fr + ", s=" + bytesRef.utf8ToString());
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...