Pull to refresh

Индексация документов 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, поэтому не следует сильно бояться попробовать новую версию.
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.