Изменение структуры индексации (проводок) 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, который позволит вам понимать кодеки и играть с ними. Не для производственного использования, конечно.