2016-10-26 3 views
0

Итак, я пытаюсь создать базовую систему рекомендаций, я сначала получаю то, что понравилось людям, которым понравился этот фильм (совместная фильтрация) (на основе пользователя), затем я получаю кусок различных данных (фильмы), потому что, скажем, людям, которые любят игрушечную игру, также могут нравиться фильмы SCI-fi. но фильмы такого типа очень похожи на игрушку, поэтому я хочу снова фильтровать результаты по жанрам, история игрушек имеет 5 жанров (Animation, Action, Adventure и т. д.). Я хочу только получать фильмы, которые делятся этими жанрами в общем.Соответствие между массивами в neo4j

это мой высчитывать запрос

match (x)<-[:HAS_GENRE]-(ee:Movie{id:1})<-[:RATED{rating: 5}] 
-(usr)-[:RATED{rating: 5}]->(another_movie)<-[:LINK]-(l2:Link), 

(another_movie)-[:HAS_GENRE]->(y:Genre) 

WHERE ALL (m IN x.name WHERE m IN y.name) 
return distinct y.name, another_movie, l2.tmdbId limit 200 

первая запись я получить обратно Звездные войны 1977, который имеет только Приключенческий жанр соответствует игрушечные сюжетные жанры .. помочь мне писать лучше шифровать

ответ

1

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

Сбор жанров должен допускать правильное предложение WHERE ALL позже. Мы также можем удержаться на совпадении с узлом ссылки рекомендуемого фильма, пока мы не отфильтровываем фильмы, которые хотим вернуть.

дать этому попытку:

MATCH (x)<-[:HAS_GENRE]-(ee:Movie{id:1}) 
// collect genres so only one result row so far 
WITH ee, COLLECT(x) as genres 
MATCH (ee)<-[:RATED{rating: 5}]-()-[:RATED{rating: 5}]->(another_movie) 
WITH genres, DISTINCT another_movie 
// don't match on genre until previous query filters results on rating 
MATCH (another_movie)-[:HAS_GENRE]->(y:Genre) 
WITH genres, another_movie, COLLECT(y) as gs 
WHERE size(genres) <= size(gs) AND ALL (genre IN genres WHERE genre IN gs) 
WITH another_movie limit 200 
// only after we limit results should we match to the link 
MATCH (another_movie)<-[:LINK]-(l2:Link) 
RETURN another_movie, l2.tmdbId 

В фильмах, вероятно, будет иметь много много оценок, матч, чтобы найти фильмы и рейтинга 5 будет самая дорогая часть запроса. Если многие ваши запросы зависят от рейтинга 5, вы можете захотеть создать отдельную связь [: MAX_RATED], когда пользователь оценивает фильм 5 и использует эти [: MAX_RATED] отношения для таких запросов. Это гарантирует, что вы изначально не соответствовали тонне номинальных фильмов, которые все должны быть отфильтрованы по их номинальному значению.

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