Изменение структуры индексации (проводок) Lucene

Я занимаюсь исследованиями новых способов индексирования документов. В частности, я хотел бы изменить существующие структуры индекса, чтобы экспериментировать с методами индексации. Например, если Lucene имеет инвертированный индекс, который сохраняет термин и идентификатор документа во время индексации, я хотел бы расширить эту структуру, чтобы сохранить другую информацию, такую ​​как позиция или статистика о термине. Как мне сделать такие расширения? Есть ли лучший проект с открытым исходным кодом, чем Lucene для таких расширений? Благодарю.

2 ответа

Решение

Например, если Lucene имеет инвертированный индекс, который сохраняет термин и идентификатор документа во время индексации, я хотел бы расширить эту структуру, чтобы сохранить другую информацию, такую ​​как позиция или статистика о термине...

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

Очень распространенное использование полезной нагрузки - хранение срочных позиций. Например, для термина t, если он встречается в документах D1 в позициях 1 и 3 и в D2 в позициях 2 и 5, вы можете сохранить их как разные записи в проводках для t, как показано ниже.

*t* => (D1,1) (D1,3) (D2, 2) (D2, 5)

Самый простой способ сделать это - использовать класс Lucene DelimitedPayloadTokenFilter. При анализе текста все, что вам нужно сделать, это выписать положение терминов рядом с каждым термином, разделенным определенным символом, например, "|", как показано в следующем примере.

class PayloadAnalyzer extends Analyzer {
private PayloadEncoder encoder;

PayloadAnalyzer(PayloadEncoder encoder) {
  this.encoder = encoder;
}

public TokenStream tokenStream(String fieldName, Reader reader) {
  TokenStream result = new WhitespaceTokenizer(reader);
  result = new LowerCaseFilter(result);
  result = new DelimitedPayloadTokenFilter(result, '|', encoder);
  return result;
}
}

Для декодирования значений, хранящихся в полезных нагрузках, вы используете что-то вроде следующего.

class PayloadSimilarity extends DefaultSimilarity {
    @Override
    public float scorePayload(String fieldName, byte[] bytes, int offset, int length) {
      return PayloadHelper.decodeFloat(bytes, offset);
    }
}

Затем вы можете использовать класс PayloadTermQuery, чтобы использовать эти смещения терминов при ранжировании документов.

Размышляя вслух, я думаю, что хорошим упражнением для вас было бы сохранение другой информации, относящейся к конкретным терминам, - это: i) теги части речи (POS), ii) векторы слов терминов и т. Д. В полезной нагрузке и использовать комбинацию всех этих функций во время рейтинга.

Да, Lucene - хорошая цель (если честно, не уверен, что есть лучший вариант).

Я думаю, вы бы в конечном итоге создать свой собственный кодек. Посмотрите этот пост в блоге, от главного человека, стоящего за текущими кодеками в современном Lucene. Там он упоминает полезный SimpleTextCodec, который позволит вам понимать кодеки и играть с ними. Не для производственного использования, конечно.

Другие вопросы по тегам