Как стать автором
Поиск
Написать публикацию
Обновить

Индексация документов MongoDB с помощью Sphinx

Как обстоит дело с полнотекстовым поиском в MongoDB? Встроенный механизм поиска по тексту абсолютно не подходит для реальных целей (кроме случая с метками, когда искать нужно по слову целиком). Напомню, что в эта БД предоставляет лишь возможность индексации вложенных массивов. Т.е. механизм поиска вовсе не полнотекстовый. На помощь приходит Sphinx. Но как же быть с индентификаторами Mongo, которые представлены в буквенно-числовом виде (Sphinx поддерживает только числовые идентификаторы документов)?

Есть два варианта решения этой проблемы:

1. Дополнительный или кастомный ID в документе Mongo


Раз стандартный Mongo ID не подходит, можно создать свой. Mongo позволяет вставлять в свойство "_id" любое пользовательское значние, но в этом случае нужно брать всю заботу о его уникальности на себя. Это решение подойдет для новых коллекций. С уже созданными и работающими на основе стандартного функционала чуть сложнее. Для таких случаев можно создать избыточное свойство в каждом документе, которое будет хранить числовой ID. Использоваться это свойство будет только на этапе индексации и поиска документов:
document: {
"_id" : ObjectId("4bf2c7f38ead0e0d05070001"),
"id" : 1,
"text" : "Текст"
}


2. Строчный атрибут в индексе


В sphinx 0.9.10 появится отличная возможность использовать строчные атрибуты при построении индекса. В текущей версии есть тип ordinal string, который может использоваться только для сортировки, но не для выборки, поэтому он не подойдет.

Как будет вяглядеть решение? Индекс будет иметь приблизительно следующий вид:

Индекс (используем XMLpipe2 и схему, объявленную в XML)

source test {
type = xmlpipe
xmlpipe_command = php indexer.pipe.php
}


XML схема индекса

<sphinx:schema>
<sphinx:field name="content"/>
<sphinx:attr name="_id" type="string"/>
</sphinx:schema>

Что останется сделать, это генерировать уникальный числовой идентификатор документов на этапе индексации. По сути он будет не нужен приложению, но обязательно нужен для индекса Sphinx.

Пример XML

...
<sphinx:document id="<?=$i++?>">
<![CDATA[[<?=$document['text']?>]]>
<_id><?=$document['_id']?></_id>
</sphinx:document>
...


Единственный недостаток этого решения — 0.9.10 еще не в релизе. Тем не менее эта версия уже успешно применяется на проекте craiglist, поэтому не следует сильно бояться попробовать новую версию.
Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.