Многие из тех, кто успел попробовать
Основная проблема заключается в том, что sphinx не позволяет использовать буквенно-цифровые значения в качестве ID документов. Есть несколько вариантов решения этой проблемы.
Строим индекс с помощью xmlpipe
Поскольку в Sphinx пока нет реализации источника данных для mongo, то придется использовать XMLpipe для индексации:
source src_test {
type = xmlpipe
xmlpipe_command = php /home/golotyuk/www/mongosphinx/index.php
}
index test {
morphology = stem_enru
charset_type = utf-8
source = src_test
path = /var/lib/sphinxsearch/data/test
}
Реализация XML генератора может быть приблизительно такая:
<?='<?xml version="1.0" encoding="utf-8"?><sphinx:docset>'?>
<sphinx:schema>
<sphinx:field name="content"/>
</sphinx:schema>
<?
$m = new Mongo();
$c = $m->test->documents;
$list = $c->find();
?>
<? foreach ( $list as $document ) { ?>
<sphinx:document id="<?=$document['numeric_id']?>">
<content><![CDATA[[<?=$document['text']?>]]></content>
</sphinx:document>
<? } ?>
</sphinx:docset>
Все предельно просто кроме одной проблемы — ID mongo документа представлен в буквенно-цифровом виде, чего не понимает сфинкс. Есть несколько подходов:
Решение проблемы с ID документа
Пользовательский ID
Первый вариант — хранить в каждом mongo-документе пользовательский (сгенерированный руками) цифровой ID отдельным свойством:
{
"_id" : ObjectId("4bf2c7f38ead0e0d05070000"),
"sid" : 7,
"text" : "Много текста"
}
В этом случае свойство sid будет использоваться для индексации в качестве ID документа (в примере выше атрибут называется “numeric_id”).
Неудобство этого решения заключается в ручной реализации всех примитивных функций касательно идентификатора — проверка на уникальность, инкремент, выборка по новому идентификатору. Поэтому данное решение лучше подойдет для статичных данных (справочная документация), но несколько усложнит динамику (форумы и т.п.).
В качестве альтернативного решения можно использовать таблицы соответствий ID документа Mongo и ID документа Sphinx (например в MySQL). В этом случае не нужно будет руками реализовывать механизм автоинкремента, но придется использовать дополнительную СУБД.
Выборка ID, как атрибута
ID mongo-документа можно выбирать как атрибут при индексации. Это наиболее верное решение, но учитывая, что атрибут строчный, понадобится обновиться до версии 0.9.10 (на этот момент эта версия еще не в релизе).
В этом случае Вам просто придется генерировать уникальные ID для сфинкса (которые будут фактически бесполезными для Вас — их можно генерировать на этапе индексации), а mongo ID доставать как свойство. Схема индекса будет следующая:
<sphinx:schema>
<sphinx:field name="content"/>
<sphinx:attr name="_id" type="string"/>
</sphinx:schema>
Как видно, id mongo-документа описан как строчный атрибут. Для генерации id документа sphinx можно использовать простой инкремент, например:
<? $i = 0; foreach ( $list as $document ) { ?>
<sphinx:document id="<?=$i + 1?>">
<content><![CDATA[[<?=$document['text']?>]]></content>
<_id><?=$document['_id']?></_id>
</sphinx:document>
<? } ?>
В результате sphinx будет возвращать атрибут “_id”, в котором будет находится идентификатор документа Mongo.
Related posts:
Комментариев нет:
Отправить комментарий