# Работа с социальными данными. Персонализированная выдача. Ранжирование результатов выдачи по нескольким критериям

**URL:** <https://discuss.elastic.co/t/topic/40553>\
**Category:** Вопросы на русском языке\
**Created:** [January 30, 2016, 12:12pm UTC](https://discuss.elastic.co/t/topic/40553 "2016-01-30T12:12:49Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![i.kozharov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/i.kozharov/32/7479_2.png) [@i.kozharov](https://discuss.elastic.co/u/i.kozharov)\
**Post date:** [January 30, 2016, 12:12pm UTC](https://discuss.elastic.co/t/topic/40553/1 "2016-01-30T12:12:49Z")

</div>

Здравствуйте, есть следующий кейс, индекс содержит данные о пользователях. Ищем по полному или частичному совпадению в username или full\_name. В приоритете совпадения в username. Результат нужно сортировать по нескольким критериям, я имею в виду, что первыми должны быть результаты с полным совпадением в username или full\_name. Далее необходимо первыми показать тех пользователей, у которых есть связи с автором запроса, по типу сначала друзей, потом друзей друзей, критерий ранжирования в этом случае количество общих связей. И в завершении показать популярных пользователей.

Данные о связях берутся из другого места, так что на elasticsearch ложится только задача поиска и сортировки.  
На данный момент пользуюсь решением с помощью function score query.  
[https://www.elastic.co/guide/en/elasticsearch/reference/2.1/query-dsl-function-score-query.html](https://www.elastic.co/guide/en/elasticsearch/reference/2.1/query-dsl-function-score-query.html)  
Как бы вы подступились к этой задаче? Есть ли зарекомендовавшие себя подходы?

---

<div class="post-metadata">

**Author:** ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)\
**Post date:** [January 30, 2016, 5:20pm UTC](https://discuss.elastic.co/t/topic/40553/2 "2016-01-30T17:20:14Z")

</div>

Я думаю, проще всего начать с подхода, описанного в [этой теме](https://discuss.elastic.co/t/topic/36413). Если что-то не будет работать, присылайте пример и будем разбираться, что не работает.

Хочу только предупредить, что выборка связи из другого места - дело хитрое, потому что без локального кеширования вам придется проверять связь для большого количества пользователей через сеть. Причем, запросы должны будут посылаться по одной записи последовательно в каждой шарде. Так что, даже если вы сможете выполнять каждую проверку за пол миллисекунду (время пересылки пакета в одном и том же ВЦ), выполнение этой проверки для 10,000 пользователей займет 5 секунд. Вы не сказали о каком масштабе идет речь, так что в зависимости от размера вашего индекса это может и не быть серьезной проблемой.

Если это будет проблемой, то скорость выполнения, можно улучшить, если не проверять каждую запись, а воспользоваться запросом [rescore](https://www.elastic.co/guide/en/elasticsearch/reference/2.1/search-request-rescore.html#_query_rescorer) и проверять связь только для 1000 "лучших" записей отсортированных по всем другим, более быстрым, критериям.

Другой способ - это индексировать информацию о связях в elasticsearch. Переиндексировать каждую запись при изменении связи не реалистично. Но индексировать небольшую child запись с id друга вполне возможно. Этот подход хорошо работает если важена только прямая связь. С друзьями друзей популярные пользователи, к сожалению, вызывают проблему в лубом случае (если не ограничивать количество друзей или не игнорировать некоторых друзей, если их накопилось слишком много).

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [July 6, 2017, 1:49pm UTC](https://discuss.elastic.co/t/topic/40553/3 "2017-07-06T13:49:44Z")

</div>


