Полнотекстовый поиск и инвертированные индексы в MongoDB

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

Я экспериментировал с функцией поиска, которая использует класс MongoRegEx (драйвер PHP), где я просто ищу по всему содержимому сообщений и заголовкам сообщений после предложения «lorem ipsum» с учетом регистра в «/I».

Мой код выглядит так:

$regex = new MongoRegEx('/lorem ipsum/i');  
$query = array('post' => $regex, 'post_title' => $regex);

Но я смущен и ошеломлен тем, что происходит. Я проверяю время выполнения каждого запроса (устанавливаю микровремя до и после запроса и получаю время с 15 десятичными знаками).

Для моего первого теста я добавил 110 000 документов блога и 5000 авторов, все было сгенерировано случайным образом. Когда я выполняю поиск, он находит 6824 сообщения с предложением «lorem ipsum», и поиск занимает 0,000057935714722 секунды. И это после сброса службы MongoDB (используя Windows), и это без какого-либо индекса, кроме значения по умолчанию для _id.

MongoDB использует индекс B-дерева, который определенно не очень эффективен для полнотекстового поиска. Если я создаю индекс для своего атрибута контента сообщения, тот же запрос, что и выше, выполняется в 0,000150918960571, что достаточно забавно, медленнее, чем без какого-либо индекса (медленнее с коэффициентом 0,000092983245849). Теперь это может произойти по нескольким причинам, потому что он использует курсор B-дерева.

Но я пытался найти объяснение тому, как он может запрашивать его так быстро. Я предполагаю, что он, вероятно, хранит все в моей оперативной памяти (у меня 4 ГБ, а база данных составляет около 500 МБ). Вот почему я пытаюсь перезапустить службу mongodb, чтобы получить полный результат.

Может ли кто-нибудь, у кого есть опыт работы с MongoDB, помочь мне понять, что происходит с такого рода полнотекстовым поиском с индексом или без него и, безусловно, без инвертированного индекса?

С уважением - Местика


person Emil Devantie Brockdorff    schedule 03.05.2012    source источник
comment
Если вы еще не видели: mongodb.org/display/DOCS /Полный+Текст+Поиск+в+Монго   -  person Eve Freeman    schedule 03.05.2012
comment
Регулярное выражение mongodb не использует индексы, если только оно не начинается с регулярного выражения типа - мне удалось разбить все термины на массив и проиндексировать его. Я планирую перенести это решение на Elastic Search (для части полнотекстового поиска), сохраняя при этом все в монго для других типов запросов. Да, он будет хранить ваши данные в ОЗУ, если к ним обращаются, и у него есть свободная память.   -  person Eve Freeman    schedule 03.05.2012


Ответы (1)


Я думаю, вы просто не перебирали результаты? Только с помощью find() драйвер не отправит запрос на сервер. Для этого вам нужно получить хотя бы один результат. Я не верю, что MongoDB такая быстрая, и я считаю, что ваша ошибка связана с вашим тестом.

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

person Derick    schedule 03.05.2012