Подтвердить что ты не робот

Как ElasticSearch может использоваться для реализации социального поиска?

Я пытаюсь создать бизнес-поиск с помощью социальных функций с помощью ElasticSearch. У меня есть бизнес-каталог, и пользователи могут взаимодействовать с этими предприятиями по-разному: просматривая их, проверяя их и т.д.

Когда пользователь ищет бизнес, я хотел бы показать им предприятия, с которыми их друзья взаимодействовали в верхней части результатов (или фильтр на основе этих взаимодействий). Какой лучший способ настроить мой индекс для достижения этого?

Я думаю, что есть несколько возможных решений, но я начинаю с ES, и я не уверен, что вызовет проблемы:

  • Я мог бы использовать многозначность и создать отдельный индекс для каждого пользователя. Я решил это, потому что количество пользователей намного больше, чем количество предприятий или количество пользовательского контента.

  • Я мог бы добавить список пар user/score для каждого проиндексированного бизнеса. Каждый пользователь, который взаимодействовал с бизнесом, будет там, и оценка будет представлять собой количество взаимодействия, которое они имели с бизнесом (это достаточно хорошо для моих целей фильтрации/сортировки). Каждый раз, когда они взаимодействуют с бизнесом, я бы обновил счет в индексе. Проблема в том, что я забочусь только о деятельности моих друзей, поэтому мне нужно будет выяснить, каким образом учесть, кто мои друзья, создавая составную оценку для бизнеса. Я не знаю, как это сделать в ES.

  • Я мог бы создать подобную схему, но вместо того, чтобы держать оценку моих взаимодействий с бизнесом, оценка будет отражать взаимодействие моих друзей с бизнесом. Это устраняет необходимость моделирования моего социального графика в ElasticSearch, но это означает, что в любое время, когда человек взаимодействует с бизнесом, мне нужно будет обновить все оценки своих друзей. Это также означает, что список пар пользователей/пар для каждого бизнеса будет больше, так как он должен будет включать любого, у кого есть друг, который взаимодействовал с бизнесом.

  • Последнее решение, о котором я могу думать, - следить за каждым отдельным взаимодействием, которое происходит с бизнесом, и добавлять его в бизнес-документ в ES. Это не кажется мне реалистичным - оно сочетает проблемы с другими решениями. Но, вероятно, это самый простой подход в плане поддержания индекса в актуальном состоянии.

Спасибо за вашу помощь!

4b9b3361

Ответ 1

Я голосую за измененный # 2.

Вместо того, чтобы хранить каждую пару пользователя/пар внутри самого бизнес-документа, я бы создал отношения родителя/ребенка. Это позволяет вам обновлять оценку ребенка (оценки пользователя) без необходимости переиндексации всего бизнес-документа (и всех других пользовательских оценок).

Посмотрите эту страницу для отличного учебного родителя/детей примерно на полпути вниз: http://www.spacevatican.org/2012/6/3/fun-with-elasticsearch-s-children-and-nested-documents/

Затем вы можете использовать фильтр has_child или запрос top_children, чтобы найти только те предприятия, которые есть у ваших друзей. оценки для. Есть несколько предостережений о заказе детских документов, но они охватываются этим учебником, поэтому убедитесь, что вы читаете снизу.

Затем я просто выполнил обычный запрос для всех "несоциальных" ранжированных поисков.

В качестве альтернативы вы можете объединить все вместе и добавить стимулы к матчам, которые ваши друзья забили, чтобы все соответствовало. Это может быть проще выполнить два запроса и объединить их самостоятельно.

Ответ 2

Существует еще один набор решений, которые имеют преимущество в том, что они чрезвычайно быстрые (т.е. используют преимущества ES), но выглядят ужасно для всех, кто знает даже первое, что связано с проектированием систем хранения/поиска данных.

Если ваш индекс "бизнеса" меньше, чем ваш "пользовательский" индекс (т.е. 10 000 бизнес, 1 000 000 пользователей)

  • Создайте 2 индекса: Пользователь и Бизнес.
  • Бизнес-индекс должен иметь поле "массив", которое содержит идентификаторы каждого пользователя, который когда-либо "взаимодействовал" с ним (то есть "пользователи: 1,4,23,26,127,8678" ).
  • Пользовательский индекс должен иметь поле вложенного массива с бизнес-идентификаторами и отзывами, проверками и т.д. во вложенном объекте с метаинформацией (т.е. "business_id: 1233, рейтинг: 7.5, checkins: 21" )

При поиске бизнеса выполните быстрый запрос строки или запрос на фильтрацию с идентификаторами пользователя User (ИЛИ, конечно), против индекса Business. Tf-idf должен автоматически фильтровать компании, с которыми вы больше всего взаимодействовали своими друзьями на вершине. Если вам нужна дополнительная информация, просто нажмите индекс пользователя, чтобы получить метаданные для каждого из ваших друзей (рейтинг, проверки и т.д.). Это должно быть быстро и быстродействующим, потому что ES абсолютно фантастично подходит для сопоставления массивов как отдельных терминов. Это то, что для тебя!

Если ваш индекс "бизнеса" значительно больше, чем ваш "пользовательский" индекс, отмените шаблон... поместите индексированный массив бизнес-приложений, с которыми пользователь взаимодействовал с пользовательским индексом.

Ответ 3

Отъезд Titan https://github.com/thinkaurelius/titan/wiki/Using-Elastic-Search

У этого есть механизм графика, который может работать с Elasticsearch в качестве задней части. Вы можете выполнить обход графика, например (me) → (friend) - [review] → (business), чтобы найти все эти соединения и настроить ранг ваших поисков.

Ответ 4

Просто spitballing здесь, но я думаю, что хотел бы использовать графическую базу данных, такую ​​как Neo4J, где было бы тривиально делать такой запрос, как "предприятия, которые мои друзья проверили", и запросить как эту базу данных, так и elasticsearch на том же времени и результатов возврата из вашей базы данных графа. Или вы можете просто получить результаты этого графического запроса и сопоставить результаты в elasticsearch (соответствие идентификаторам), а затем применить увеличение времени запроса к результатам упругого поиска, чтобы они перемещались в начало возвращаемых результатов.

Ответ 5

Solr может сделать это с помощью оператора GraphQuery.

https://issues.apache.org/jira/browse/SOLR-7543

Это позволяет вам помещать документы в ваш индекс, содержащие поле для "node_id" и (многозначное) поле для "edge_id"

Существует несколько способов структурирования этого:

  • У вас может быть пользовательский документ со списком идентификаторов друзей на нем. Или
  • У вас может быть отдельная таблица, которая является таблицей ссылок, которая связывает между пользовательскими записями.

В случае 1: Индексируйте документ для каждого пользователя в системе с полем, содержащим "user_id" и другое поле, содержащее "friend_ids".

В этот момент для поиска всех друзей для пользователя 555 будет:

{!graph from="user_id" to="friend_ids" maxDepth=1}user_id:555

Найти друзей друзей пользователя

{!graph from="user_id" to="friend_ids" maxDepth=2}user_id:555

Если у вас есть другие поля метаданных в пользовательских записях, таких как поле местоположения, вы можете добавить это как фильтр обхода, чтобы найти моих друзей, которые живут в Бостоне. Этот фильтр обхода применяется к каждому прыжку.

{!graph from="user_id" to="friend_ids" maxDepth=2 traversalFilter="location:Boston"}user_id:555

В приведенном выше запросе найдутся друзья, которые живут в Бостоне, которые являются пользователями User 555, которые живут в Бостоне.