Здравствуйте.
Цель скрипта - поиск по токенам. Всё это дело работает под Python (фреймворк Flask) + MongoDB и установлено на VDS с 400 мегабайт памяти, поэтому ставить Sphinx очень бы не хотелось, проще тогда вообще убрать поиск, тем более что смысла в нём особенного нет.
Коллекция в Mongo имеет вид
{
"token": "слово",
"haystack": {
"тип": [список ключей],
"тип2": [список ключей2]
}
}
То есть для поиска собственно документов нужно сделать запрос к базе, а после - сделать пересечение списков одного типа. К сожалению, аггрегация в этом случае вообще никак не поможет (используется MongoDB версии 2.4.9, ключ $setIntersection в блоке $project появится в MongoDB 2.6)
Пока используется следующий код:
def intersect(array):
def intersection(a, b):
if not a or not b:
return []
return list(set(a).intersection(b))
ret = {}
for val in array:
if not ret: # если первый словарь
ret = val['haystack']
else:
current = val['haystack']
ret = {
'goods': intersection(ret.get('goods'), current.get('goods')),
'pages': intersection(ret.get('pages'), current.get('pages')),
'news': intersection(ret.get('news'), current.get('news'))
}
return ret
Если получаемые списки небольшие - всё отрабатывается за миллисекунды. Но в текущей базе порядка 10К записей и при этом токенов слишком мало, каждый документ содержит в себе до 7 тысяч значений. Интересно, что получение данных при следующем вызове занимает 63 мс (два документа, 1597 и 6602 значений списка, после пересечения получается список из 1448 элементов)
result = list(db.search.find({'token': {'$in': tokens}}))
...а пересечение списков добавляет... всего миллисекунду. Хм.
В связи с этим есть вопрос: нельзя ли как-нибудь ускорить это дело?
Индекс по токенам есть, само собой, тот же запрос с .explain() в консоли mongo утверждает, что выполняется за минимальное время - 0 мс. Но почему возвращаются эти результаты ТАК ДОЛГО? Что можно сделать в таком странном случае?