Как обстоит дело с полнотекстовым поиском в MongoDB? Встроенный механизм поиска по тексту абсолютно не подходит для реальных целей (кроме случая с метками, когда искать нужно по слову целиком). Напомню, что в эта БД предоставляет лишь возможность индексации вложенных массивов. Т.е. механизм поиска вовсе не полнотекстовый. На помощь приходит Sphinx. Но как же быть с индентификаторами Mongo, которые представлены в буквенно-числовом виде (Sphinx поддерживает только числовые идентификаторы документов)?
Есть два варианта решения этой проблемы:
Раз стандартный Mongo ID не подходит, можно создать свой. Mongo позволяет вставлять в свойство "_id" любое пользовательское значние, но в этом случае нужно брать всю заботу о его уникальности на себя. Это решение подойдет для новых коллекций. С уже созданными и работающими на основе стандартного функционала чуть сложнее. Для таких случаев можно создать избыточное свойство в каждом документе, которое будет хранить числовой ID. Использоваться это свойство будет только на этапе индексации и поиска документов:
В sphinx 0.9.10 появится отличная возможность использовать строчные атрибуты при построении индекса. В текущей версии есть тип ordinal string, который может использоваться только для сортировки, но не для выборки, поэтому он не подойдет.
Как будет вяглядеть решение? Индекс будет иметь приблизительно следующий вид:
Что останется сделать, это генерировать уникальный числовой идентификатор документов на этапе индексации. По сути он будет не нужен приложению, но обязательно нужен для индекса Sphinx.
Единственный недостаток этого решения — 0.9.10 еще не в релизе. Тем не менее эта версия уже успешно применяется на проекте craiglist, поэтому не следует сильно бояться попробовать новую версию.
Есть два варианта решения этой проблемы:
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, поэтому не следует сильно бояться попробовать новую версию.