предисловие
Последняя серия еще не закончилась, я здесь, чтобы открыть новую яму~
Работа, связанная с поиском/рекомендацией контактов, также имеет два года. Я много контактирую с люценом в своей работе, но у меня не очень хорошо получается. В последнее время я не был так занят на работе, поэтому хочу систематически изучать lucene, изучая исходный код.
Кроме того, я слышал, что исходный код Lucene является моделью объектно-ориентированного дизайна, и я также хочу поглотить некоторые знания дизайна / разработки кода от него. Недавно я всегда чувствую, что есть проблема с кодом, который я написал. Я хочу попытаться оптимизировать его, но я чувствую себя очень сложно. Я часто имеющую ограниченное улучшение после одной операции.
Знакомство с люценом
Следующее взято из Википедии:
Lucene — это набор библиотек с открытым исходным кодом для полнотекстового поиска и поиска, поддерживаемых и предоставляемых Apache Software Foundation. Lucene предоставляет простой, но мощный API для полнотекстового индексирования и поиска. Lucene в настоящее время является самой популярной бесплатной библиотекой программ для поиска информации на языке Java.
Полнотекстовый поиск (Full Text Retrieval) Полнотекстовый поиск относится к технологии поиска информации, которая принимает всю текстовую информацию в качестве объекта поиска. Наиболее распространенными системами полнотекстового поиска являются Google и Baidu.Они анализируют и индексируют все содержимое веб-страниц в Интернете, чтобы предоставить нам возможности поиска второго уровня. Во-вторых, многие современные мобильные приложения имеют встроенные функции поиска, которые также являются реализациями поиска в вертикальных полях. Разница между ними и google/baidu заключается в том, что они обеспечивают поиск информации только в текущем приложении, а не на всех веб-страницах в Интернете.
Предположим, есть 10 статей, каждая с заголовком и телом. Когда мы хотим найти текст, содержащийатомная энергия, что нам делать?
Во-первых, самый грубый подход, мы можем прочитать каждую статью последовательно и судить по одному на одну, если есть три последовательных символа.атомная энергия, мы записываем заголовок этой статьи, поэтому сканируем ее все и выполняем поиск.
Этот метод довольно прост и груб, и эффективен. В случае очень высокой производительности компьютера этот метод можно использовать для поиска файлов размером 1 ГБ (команда grep под Linux, если вы часто используете ее, вы должны знать, что даже если вы выполняете простой поиск файлов уровня ГБ, производительность обычно приемлемо. из).
Однако объем данных будет намного больше 1G, да и требования к поиску тоже более сложные, не простое сопоставление строк, а сочетание различных условий. Здесь необходим полнотекстовый поиск.
Поисковая система, такая как Google, может искать результаты 1230 Вт, связанные с «полнотекстовой поисковой системой», за 0,5 с. Очевидно, что это не последовательное посимвольное сравнение, а полнотекстовый поиск, аналогичный lucene.
Lucene Query можно сделать во втором этапе большие количества данных, должно быть называться зависимымпоказательСтруктура. Для понимания индексации есть много готовых примеров.Например, после многих книг предусмотрено сопоставление ключевых слов с номерами страниц.Это своеобразный индекс, который позволяет нам находить интересующие нас части, не читая вся книга.
В книге «Красота математики» автор считает, что сутью полнотекстового поиска является булева алгебра. С постепенным углубленным пониманием полнотекстового поиска я чувствую, что это предложение становится все более и более точным.На этапе индексации/поиска полнотекстового поиска фундаментальным принципом является простейшая булева алгебра, а остальное — только сложность инженерной реализации.
lucene-beta
В настоящее время Lucene разрабатывает версию 9.0 Весь проект разделен на несколько модулей, что очень сложно.
Прежде чем изучать исходный код lucene, я долго думал, какой путь мне выбрать, чтобы изучить lucene, я не могу найти случайный класс, чтобы начать читать, и я боюсь, что упаду в море деталей.
Первоначальная идея состояла в том, чтобы начать с создания индекса, выбрать путь построения индекса -> запись на диск -> поисковый запрос -> анализ запроса -> оценка релевантности -> возврат результатов и учиться шаг за шагом.
Потом вдруг пришла в голову смелая идея, которую захотелось попробоватьСущность абстрактного полнотекстового поиска, написать инструмент полнотекстового поиска, самый простой во всех аспектах (желательно простой, как один или два класса), а затем как развить различные аспекты этого инструмента в соответствующие модули lucene, и как улучшить различные дефекты lucene, приходите Проведите исследование lucene.
Это название этого разделаlucene-betaпроисхождение.
Я ожидаю, что это должно иметь два преимущества:
- Он может приблизиться к сути и не потеряться в местных деталях.
- Разумнее перейти от вопроса к заключению. чувствовать более глубокотак так такнеобходимость. Какой смысл просто хвастаться своими навыками, если в этом нет необходимости?
public class LuceneBeta {
private static final Logger logger = LoggerFactory.getLogger(LuceneBeta.class);
public static void main(String[] args) {
LuceneBeta beta = new LuceneBeta();
String[] arr = new String[]{"原子能研究所", "原子弹威力很大"};
Map<Character, int[]> index = beta.build(arr);
int[] searchRet = beta.search('威', index);
System.out.println(Arrays.toString(searchRet));
}
/**
* 对传入的字符串数组进行字符级别的构建索引
*/
public Map<Character, int[]> build(String[] arr) {
Set<Character> all = new HashSet<>();
for (String s : arr) {
for (char c : s.toCharArray()) {
all.add(c);
}
}
Map<Character, int[]> index = new HashMap<>();
for (Character c : all) {
int[] perContains = new int[arr.length];
for (int w = 0; w < arr.length; w++) {
if (arr[w].contains(String.valueOf(c))) {
perContains[w] = 1;
} else {
perContains[w] = 0;
}
}
index.put(c, perContains);
}
logger.info("build {} strings. indexed: ", arr.length);
for (Map.Entry<Character, int[]> e : index.entrySet()) {
logger.info("{} ==> {}", e.getKey(), Arrays.toString(e.getValue()));
}
return index;
}
/**
* 查询目标字符都在哪些字符串中出现过
*/
public int[] search(char target, Map<Character, int[]> index) {
if (!index.containsKey(target)) {
return null;
}
int[] ints = index.get(target);
int[] tmp = new int[index.size()];
int j = 0;
for (int i = 0; i < ints.length; i++) {
if (ints[i] == 1) {
tmp[j] = i;
j++;
}
}
int[] ret = new int[j];
System.arraycopy(tmp, 0, ret, 0, j);
return ret;
}
}
Если он простой, он должен быть простым в конце концов, весь код составляет 70 строк. Какую функцию он выполняет?
В данной серии строк вы можете искать все номера строк, в которых встречается определенный символ.
гугл можетНайдите соответствующую веб-страницу в соответствии с вашими ключевыми словами, приведенный выше код можетНайдите соответствующую строку на основе введенных вами ключевых символов., Исходный код был разработан, просто жду обнародования финансирования, я следующий гугл...
Хотя приведенный выше код чрезвычайно прост, для последующего анализа люцена мне все равно придется тщательно обобщать каждый шаг.
В приведенной выше программе она разделена на две части, а именно два методаbuildи search.
прежде всегоbuildпроцесс:
- Перебрать входную строку и получить все вхождения символов.
- Для каждого символа подсчитайте массив символов, каждый из которых представляет, появляется ли текущий символ в пронумерованной строке. 1 означает наличие, 0 означает отсутствие. Если «Исходный» появляется в обеих входных строках, то соответствующий ему статистический массив равен [1,1].
- Возвращает массив всех символов и их статистику в виде «индекса».
процесс поиска
- Если вводимого символа не существует, верните значение сразу пустым
- Выньте статистический массив, соответствующий символу, и восстановите его до исходного строкового номера с помощью двоичного представления.
- Возвращает все номера строк, в которых встречается этот символ.
Введение в архитектуру исходного кода Lucene
Будучи зрелым программным обеспечением с открытым исходным кодом, lucene включает несколько модулей, ядром которых является пакет lucene.core. Он разделен на следующие каталоги:
в:
- org.apache.lucene.analysis в основном отвечает за лексический анализ и языковую обработку.
- org.apache.lucene.codecs в основном отвечает за кодирование и декодирование текстового содержимого в инвертированные индексы.
- org.apache.lucene.document предоставляет абстрактный документ и поля для пользовательского контента.
- org.apache.lucene.index в основном отвечает за чтение и запись индекса.
- org.apache.lucene.search в основном отвечает за процесс поиска.
- org.apache.lucene.store в основном отвечает за сохранение индекса и так далее.
- набор инструментов org.apache.lucene.util.
Эпилог
В этой статье реализована минималистская версия lucene-beta, конечно, не для того, чтобы заменить lucene. Просто создайте простую абстракцию для полнотекстового поиска и сопоставьте превосходную реализацию Lucene с простыми функциями.
В последнем разделе описывается несколько простых каталогов в пакете lucene.core, основной источник последующего исследования, проблема будет заключаться в том, чтобы lucene-бета направлял, постепенно подмодуль.
Изучение исходного кода Lucene официально началось~
Заканчивать.
свяжитесь со мной
Наконец, приглашаю вас обратить внимание на мой личный публичный аккаунт [Huyan Shi], я буду время от времени обновлять учебные заметки многих бэкенд-инженеров. Вы также можете связаться со мной напрямую в публичном аккаунте, личном сообщении или электронной почте, Вы должны все знать и все говорить.
Все вышеизложенное является личными мыслями, если есть какие-либо ошибки, пожалуйста, исправьте их в комментариях.
Добро пожаловать на перепечатку, пожалуйста, подпишите и сохраните исходную ссылку.
Электронное письмо:huyanshi2580@gmail.com
Дополнительные учебные заметки, чтобы увидеть личный блог или обратить внимание на общедоступный номер WeChat ------>Хуян тен