Процесс, которым Lucene токенизирует текст - PullRequest
3 голосов
/ 13 января 2011

Это можно рассматривать как общий вопрос Java, но для лучшего понимания я использую Lucene в качестве примера.

Вы можете использовать различные токенизаторы в Lucene для токенизации текста. Есть основной абстрактный класс Tokenizer, а затем множество различных классов, расширяющих его. То же самое для TokenFilter.

Теперь кажется, что каждый раз, когда вы хотите проиндексировать документ, создается новый Tokenizer. Вопрос в том, что Tokeinzer - это просто служебный класс, почему бы не сделать его статичным? например, Tokenizer, который преобразует все буквы в нижний регистр, может иметь статический метод, который делает это только для каждого входного сигнала, который он получает. Какой смысл создавать новый объект для каждого фрагмента текста, который мы хотим проиндексировать?

Стоит упомянуть одну вещь - у Tokeinzer есть приватное поле, содержащее входные данные, которые он получает для токенизации. Я просто не понимаю, почему мы должны хранить его таким образом, потому что объект уничтожается сразу после завершения процесса токенизации и возвращается новый токенизированный текст. Единственное, о чем я могу подумать, так это о многопоточном доступе?

Спасибо!

Ответы [ 2 ]

6 голосов
/ 14 января 2011

Теперь кажется, что каждый раз, когда вы хотите проиндексировать документ, создается новый токенизатор

Это не так, вызывается метод Analyzer.reusableTokenStream, который повторно использует не только Tokenizer, но и вся цепочка (TokenFilters и т. д.). См http://lucene.apache.org/java/3_0_0/api/core/org/apache/lucene/analysis/Analyzer.html#reusableTokenStream(java.lang.String, java.io.Reader)

Стоит упомянуть одну вещь - у Tokeinzer есть приватное поле, содержащее входные данные, которые он получает для токенизации. Я просто не понимаю, почему мы должны хранить его таким образом, потому что объект уничтожается сразу после завершения процесса токенизации и возвращается новый токенизированный текст. Единственное, о чем я могу думать, так это о многопоточном доступе?

Как упоминалось ранее, вся цепочка токенизаторов и токен-фильтров повторно используется в документах. Таким образом, все их атрибуты используются повторно, но также важно отметить, что атрибуты являются общими для всей цепочки (например, все ссылки Tokenizer и TokenFilters Attribute указывают на одни и те же экземпляры). Вот почему крайне важно вызывать clearAttributes () в вашем токенизаторе для сброса всех атрибутов.

В качестве примера, токенизатор Whitespace добавляет ссылку на TermAttribute в свой ctor, и он оборачивается в LowerCaseFilter, который добавляет ссылку на TermAttribute в его ctor. Оба эти атрибута TermAttributes указывают на один и тот же базовый символ []. Когда новый документ обрабатывается, вызывается Analyzer.reusableTokenStream, который возвращает ту же цепочку TokenStream (в данном случае Whitespace, заключенную в LowerCaseFilter), использованную в предыдущем документе. Вызывается метод reset (Reader), который сбрасывает ввод токенайзера в новое содержимое документа. Наконец, метод reset () вызывается для всего потока, который сбрасывает любое внутреннее состояние из предыдущего документа, и содержимое обрабатывается до тех пор, пока incrementToken () не возвращает false.

0 голосов
/ 14 января 2011

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

...