2016-10-26 11 views
0

私は基本的な推薦システムを構築しようとしています。まず、この映画が好きな人たち(コラボレーティブフィルタリング)(ユーザーベース)を入手してから、 )、なぜなら、おもちゃの話を好きな人はSCI-fi映画が好きかもしれないからです。このタイプの映画はおもちゃ物語にはあまり関係がないので、そのジャンルで結果をフィルタリングしたい、おもちゃ物語には5つのジャンル(アニメーション、アクション、アドベンチャーなど)があります。これらのジャンルを共有している映画のみを取得したい共通する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、..ですより良いCYPHER

答えて

1

を書いて私を助けていくつかがあります。クエリを改善するためにできること。

ジャンルを収集すると、後で正しいWHERE ALL句が許可されます。また、返す映画に絞り込むまで、推奨ムービーのリンクノードとのマッチングを延期することもできます。

はこの1つを試してみる:映画は、おそらく多くの多くの評価を持ってしようとしていると

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の評価に頼っている場合、ユーザーがムービーを5に評価するたびに別個の[:MAX_RATED]関係を作成し、これらのクエリに対して[:MAX_RATED]リレーションシップを使用することを検討することをお勧めします。それは、あなたが最初に、格付け値でフィルタリングされなければならないたくさんの定格ムービーに合っていないことを保証します。

ムービーの平均評価に基づいて推奨事項を検討する場合は、すべてのムービーのすべてのレーティングの計算平均をキャッシュすることを検討することをお勧めします。ムービーノードの平均レーティングプロパティにインデックスを追加すると、同様に評価されたムービーとのマッチングが速くなります。

関連する問題