Что такое docID в IndexReader.getTermVector (int docID, поле String) в Lucene 8.5.1 и как это работает?

Я пытаюсь получить все термины и связанные сообщения, которые вызывали Terms из поля документа Lucene (например, как рассчитать частоту терминов в Lucene?). Согласно документации есть способ сделать это:

public final Terms getTermVector​(int docID, String field) throws IOException

Получить вектор терминов для этого документа и поля или значение null, если векторы терминов не были проиндексированы. Возвращенный экземпляр Fields действует как инвертированный индекс для одного документа (docID будет 0).

Есть поле под названием int docID. Что это?? для данного документа, что это за поле id и как Lucene это распознает? Согласно документации Lucene, я использовал StringField в качестве идентификатора, а это не int.

import org.apache.lucene.document.*;
Document doc = new Document();
Field idField = new StringField("id",post.Id,Field.Store.YES);
Field bodyField = new TextField("body", post.Body, Field.Store.YES);
doc.add(idField);
doc.add(bodyField);

Соответственно, у меня пять вопросов:

  1. Как Lucene распознает, что поле id используется как docId в этом документе? или даже Люцен это делает или нет ???
  2. Я использовал String для id, но этот метод дает int. Это вызывает проблемы?
  3. Есть ли подходящий способ получения сообщений?
  4. Я использовал TextField. Есть ли способ получить вектор терминов (Terms) этого поля? Я не хочу повторно индексировать мой документ, как описано в здесь, потому что он великоват (35 гб).
  5. Есть ли способ получить количество терминов и частоту каждого термина из TextField?

person Hamed Sanaei    schedule 17.06.2020    source источник


Ответы (1)


Чтобы рассчитать частоту использования термина, мы можем использовать IndexReader.getTermVector(int docID ,String field). int docID - это поле, которое ссылается на идентификатор документа, созданный Lucene. Вы можете получить docID с помощью следующего кода:

String index = "index/AIndex/";
String query = "the query text"

IndexReader reader = DirectoryReader.open(FSDirectory.open(Paths.get(index)));
IndexSearcher searcher = new IndexSearcher(reader);
Analyzer analyzer = new StandardAnalyzer();

QueryParser parser = new QueryParser("docField", analyzer);
Query lQuery = parser.parse(query);

]TopDocs results = searcher.search(lQuery ,  requiredHits);
ScoreDoc[] hits = results.scoreDocs;
int numTotalHits = (int) results.totalHits.value;

for (int i = start; i < numTotalHits; i++)
 {
   int docID = hits[i].doc;
   Terms termVector = reader.getTermVector(docID, "docField");
 }

У каждого termVector объекта есть термин и частота, связанные с полем документа, и вы можете получить это с помощью следующего кода:

private HashMap<String,Long> termsFrequency = new HashMap<>();
TermsEnum itr = termVector.iterator();
int allTermFrequency=0;
BytesRef term;

while ((term = itr.next()) != null){
  String termText = term.utf8ToString();
  long tf = itr.totalTermFreq();
  termsFrequency.put(termText, tf);
  allTermFrequency += itr.totalTermFreq();
}

Примечание. Не забудьте установить вектор терминов хранилища, как я объяснил здесь (Или этот) при индексировании документов. Если вы индексируете свой документ без настройки для хранения вектора терминов, метод getTermVector вернет null. Все виды предопределенного поля Lucene по умолчанию отключили эту опцию. Значит, вам нужно его установить.

person Hamed Sanaei    schedule 18.06.2020