Люк Ловетт, инженер Python в MongoDB
Вступление
Предположим, вы работаете с MongoDB. Большой! Теперь вы можете найти точные совпадения со всеми запросами, которые вы можете бросить в базу данных. Теперь представьте, что вы также встраиваете функцию текстового поиска в свое приложение. Он должен рисовать слова из шума с ошибками, и результаты могут совпадать и с синонимами! Для этой сложной задачи вы выбрали один из проектов на основе Lucene, Elasticsearch или Solr . Но теперь у вас есть проблема — как этот инструмент будет искать ваши документы, хранящиеся в MongoDB? И как вы будете обновлять содержимое поисковой системы?
Mongo Connector заполняет пробел между MongoDB и некоторыми лучшими инструментами поиска, такими как Elasticsearch и Solr. Он не только способен экспортировать данные из набора реплик MongoDB или сегментированного кластера в эти системы, но также поддерживает согласованность данных между этими системами: при вставке, обновлении и удалении документов в MongoDB эти изменения вскоре отражаются на других сторона через разъем Монго. Вы даже можете использовать Mongo Connector для потоковой передачи изменений, выполненных на одной первичной реплике, в другую, имитируя кластер с несколькими хозяевами.
Когда Mongo Connector увидел свой первый выпуск в августе 2012 года, он был очень прост в своих возможностях и не обладал отказоустойчивостью. Я работаю над Mongo Connector с ноября 2013 года с помощью команды MongoDB Python, и я рад сообщить, что Mongo Connector прошел большой путь с точки зрения предоставляемых им функций и (особенно) стабильности. В этом посте будут показаны некоторые из этих новых функций и приведен пример того, как реплицировать операции из MongoDB в Elasticsearch, поисковую систему с открытым исходным кодом, используя Mongo Connector. В конце этого поста мы сможем выполнять текстовые запросы с нечетким соответствием для потоков данных в Elasticsearch.
Получение нашего набора данных
Для этого поста мы будем публиковать посты с популярного сайта агрегации ссылок Reddit. Недавно мы добавили безопасное кодирование типов данных, поддерживаемых MongoDB (т. Е. Типов BSON), к типам, которые могут обрабатывать внешние драйверы баз данных (в данном случае , asticsearch-py ). Это делает безопасным использование для репликации документов, содержание которых мы не можем контролировать (например, с помощью веб-скрапинга). Используя этот скрипт, который извлекает новые сообщения из reddit , мы будем транслировать новые сообщения Reddit в MongoDB:
./reddit2mongo --mongo-host localhost --mongo-port 27017
По мере обработки сообщения вы должны увидеть первые 20 символов заголовка. Это (я допускаю, медленно, благодаря ограничениям Reddit API) эмулирует вставки в MongoDB, которые делает ваше приложение.
Разжигание соединителя
Далее мы запустим Mongo Connector. Чтобы загрузить и установить Mongo Connector, вы можете использовать pip:
pip install mongo-connector
Для этой демонстрации мы предполагаем, что Elasticsearch уже настроен и запущен на локальном компьютере и прослушивает порт 9200. Вы можете начать репликацию из MongoDB в Elasticsearch с помощью следующей команды:
mongo-connector -m localhost:27017 -t localhost:9200 -d mongo_connector/doc_managers/elastic_doc_manager.py
Конечно, если мы хотим выполнять текстовый поиск только по заголовкам и тексту постов, мы можем ограничить то, через какие поля Elasticsearch передается, используя опцию —fields. Таким образом, мы можем минимизировать объем данных, которые мы на самом деле дублируем:
mongo-connector -m localhost:27017 -t localhost:9200 --fields title,text -d mongo_connector/doc_managers/elastic_doc_manager.py
Подобно тому, как вы видите сообщения Reddit, напечатанные в STDOUT reddit2mongo, вы должны увидеть выходные данные, полученные из Mongo Connector, регистрирующие факт, что каждый документ был перенаправлен в ES примерно в одно и то же время! Какая красивая сцена!
В поисках, упруго
Теперь мы готовы использовать Elasticsearch для выполнения нечетких текстовых запросов к нашему набору данных по мере его поступления из MongoDB. Поскольку мы транслируем прямо с веб-сайта Reddit, я не могу точно сказать, какие результаты вы найдете в своем наборе данных, но, поскольку этот конкретный уголок Интернета, кажется, любит кошек почти так же, как мы любим поисковые системы, вероятно, это безопасно Сказать, что запрос котенка приведет вас куда-то:
curl -XPOST ‘http://localhost:9200/reddit.posts/_search’ -d’{ "query": { "match": { "title": { "query": "kitten", "fuzziness": 2, "prefix_length": 1 } } } }’
Поскольку мы выполняем нечеткий поиск, мы можем даже выполнить поиск для слов без слов . Поскольку большинство людей не слишком осторожны с написанием, вы можете представить, насколько мощна эта функция при выполнении текстового поиска, основанного непосредственно на вводе пользователя:
curl -XPOST ‘http://localhost:9200/reddit.posts/_search’ -d’{ "query": { "match": { "title": { "query": "kiten", "fuzziness": 2, "prefix_length": 1 } } } }’
fuzziness
Параметр определяет максимальное «расстояние редактирования» текст запроса может быть для того , чтобы соответствовать поле. prefix_length
Параметр говорит , что результаты должны соответствовать первой букве запроса. Эта статья предлагает отличное объяснение того, как это работает. Этот поиск дал мне те же результаты, что и его правильно написанная версия.
Больше, чем просто вставки
Хотя наша демонстрация просто использовала преимущества непрерывной потоковой передачи документов из MongoDB в Elasticsearch, Mongo Connector — это больше, чем просто инструмент импорта / экспорта. Когда вы обновляете или удаляете документы в MongoDB, эти операции реплицируются и на другие ваши системы, поддерживая синхронизацию всех систем с текущим первичным набором реплик. Если основной отказоустойчивый и происходит откат, Mongo Connector может обнаружить их и сделать все правильно, чтобы сохранить согласованность независимо.
резюмировать
Самое замечательное в этом то, что мы выполняем операции в MongoDB и Elasticsearch одновременно. Без такого инструмента, как Mongo Connector, нам пришлось бы использовать такой инструмент, как mongoexport
периодическая выгрузка данных из MongoDB в JSON, а затем загрузить эти данные в пустой индекс Elasticsearch, чтобы у нас не было ранее удаленных документов. Это, вероятно, было бы огромной проблемой, и мы потеряли бы возможности нашего поискового движка, работающего на ES, почти в реальном времени.
Хотя Mongo Connector значительно улучшился с момента его первого выпуска, это все еще экспериментальный проект, и у него есть способы до официальной поддержки MongoDB, Inc. Но я полон решимости отвечать на вопросы, а также просматривать запросы функций и отчеты об ошибках, сообщаемые Mongo. Страница с сообщениями о соединителях на Github. Также обязательно ознакомьтесь с полной документацией на вики-странице Github.
Ресурсы
- Откройте запрос функции, сообщите об ошибке или задайте вопрос о Mongo Connector
- Монго Коннектор домашняя страница
- Просмотрите полную документацию Mongo Connector
- Узнайте больше о нечетком текстовом поиске Elasticsearch