Настройка Sphinx и MongoDB

Sphinx + MongoDB, PHPСегодня я хочу поговорить о том, как настраивал работу sphinx с NoSQL базой данных — MongoDB. Передо мной стояла задача реализовать поиск по комментариям, учитывая три параметра — логин пользователя, ник(для незарегистрированных комментаторов) и поиск по тексту. Итак, начнем.

Для начала, нам необходимо написать скрипт, который будет формировать XML для индексатора sphinx. Структуру документа можно посмотреть в официальной документации. Для написания скрипта я использовал Python. Не знаю, почему я выбрал его, наверное просто хотел попробовать что то другое. Никто не мешает написать вам его на PHP или Perl.

import xml.etree.cElementTree as ET
import pymongo
import sys

# Conect to mongodb
conn = pymongo.Connection()
conn = pymongo.Connection('localhost', 27017)

#select DB
db = conn.mydb

docset = ET.Element("sphinx:docset")
schema = ET.SubElement(docset, "sphinx:schema")

# Generate COMMENTS index
if sys.argv[1] == "comments":
	field1 = ET.SubElement(schema, "sphinx:field")
	field1.set("name", "nick")

	field2 = ET.SubElement(schema, "sphinx:field")
	field2.set("name", "text")

	field3 = ET.SubElement(schema, "sphinx:field")
	field3.set("name", "login")

	# select collections
	coll = db.comment
	user_coll = db.user

	result = []

	for comments in coll.find():
		if comments["user_id"]:
			user = user_coll.find_one({'_id' : comments["user_id"]})
			comments["nick"] = user["realname"]
			comments["login"] = user["login"]
			result.append(comments)
		else:
			comments["login"] = "null";
			result.append(comments)
			# build XML tree
			for item in result:
				document = ET.SubElement(docset, "sphinx:document")
				document.set("id", str(int(item["_id"])))
				text = ET.SubElement(document, "text")
				text.text = item["text"]
				nick = ET.SubElement(document, "nick")
				nick.text = item["nick"]
				login = ET.SubElement(document, "login")
				login.text = item["login"]
# END generate COMMENTS index

# output index XML
print "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
ET.dump(docset)

В принципе, скрипт в объяснениях не нуждается, мы просто выбираем данные из коллекции MongoDB и на основании этих данных формируем XML документ, после чего выводим его в консоль.

if sys.argv[1] == "comments":

Это условие упрощает жизнь, если индексов должно быть несколько. Мы сможем в конфиге сфинкса просто запускать данный скрипт с параметром «comments» или «article», для разных типов контента.

Конфиг sphinx выглядит следующим образом:

source src_comments {
    type = xmlpipe2
    xmlpipe_command = python /var/www/mysite/sphinx_index.py comments
}

index comments {
        morphology              = stem_enru
        charset_type            = utf-8
        source                  = src_comments
        path                    = /var/lib/sphinxsearch/data/comment
}

indexer
{
        mem_limit = 32M
}

## настройки демона
searchd
{
    listen          = 127.0.0.1
    listen          = 3312
    read_timeout    = 5
    client_timeout  = 300
    max_children    = 0
    pid_file        = /var/log/sphinxsearch/searchd.pid
    max_matches     = 1000
}

После настройки запускаем индексацию, демона поиска, и уже с помощью SphinxApi реализовываем поиск на нашем сайте.

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s