Neo4j在四度密码查询时崩溃

Neo4j在四度密码查询时崩溃,neo4j,cypher,Neo4j,Cypher,neo4j noob在这里,在neo4j 2.0.0社区上 我有一个包含24000部电影和2700个用户的图形数据库,以及大约60000个用户和电影之间的关系 比如说,我脑子里有一部特别的电影(电影1) START movie1=node:Movie("MovieId:88cacfca-3def-4b2c-acb2-8e7f4f28be04") MATCH (movie1)<-[:LIKES]-(usersLikingMovie1) RETURN usersLikingMovie1;

neo4j noob在这里,在neo4j 2.0.0社区上

我有一个包含24000部电影和2700个用户的图形数据库,以及大约60000个用户和电影之间的关系

比如说,我脑子里有一部特别的电影(电影1)

START movie1=node:Movie("MovieId:88cacfca-3def-4b2c-acb2-8e7f4f28be04") 
MATCH (movie1)<-[:LIKES]-(usersLikingMovie1)
RETURN usersLikingMovie1;
START movie1=节点:电影(“电影ID:88cacfca-3def-4b2c-acb2-8e7f4f28be04”)

MATCH(movie1)Cypher是一种模式匹配语言,记住MATCH子句在图形中的任何位置都会找到模式,这一点很重要

您使用的MATCH子句的问题是,有时Cypher会发现不同的模式,其中“usersGen2”与“usersLikingMovie1”相同,而“movie1”与“movieGen1”在不同的模式中相同。因此,本质上,Cypher每次都会在图形中找到该模式,在查询期间将其保存在内存中,然后返回所有moviesGen2节点,实际上可能是相同的节点n次

MATCH (movie1)<-[:LIKES]-(usersLikingMovie1)-[:LIKES]->(moviesGen1)<-[:LIKES]-(usersGen2)

MATCH(movie1)(moviesgene1)Cypher是一种模式匹配语言,重要的是要记住,MATCH子句在图形中的任何地方都会找到模式

您使用的MATCH子句的问题是,有时Cypher会发现不同的模式,其中“usersGen2”与“usersLikingMovie1”相同,而“movie1”与“movieGen1”在不同的模式中相同。因此,本质上,Cypher每次都会在图形中找到该模式,在查询期间将其保存在内存中,然后返回所有moviesGen2节点,实际上可能是相同的节点n次

MATCH (movie1)<-[:LIKES]-(usersLikingMovie1)-[:LIKES]->(moviesGen1)<-[:LIKES]-(usersGen2)

MATCH(movie1)(moviesgene1)Cypher是一种模式匹配语言,重要的是要记住,MATCH子句在图形中的任何地方都会找到模式

您使用的MATCH子句的问题是,有时Cypher会发现不同的模式,其中“usersGen2”与“usersLikingMovie1”相同,而“movie1”与“movieGen1”在不同的模式中相同。因此,本质上,Cypher每次都会在图形中找到该模式,在查询期间将其保存在内存中,然后返回所有moviesGen2节点,实际上可能是相同的节点n次

MATCH (movie1)<-[:LIKES]-(usersLikingMovie1)-[:LIKES]->(moviesGen1)<-[:LIKES]-(usersGen2)

MATCH(movie1)(moviesgene1)Cypher是一种模式匹配语言,重要的是要记住,MATCH子句在图形中的任何地方都会找到模式

您使用的MATCH子句的问题是,有时Cypher会发现不同的模式,其中“usersGen2”与“usersLikingMovie1”相同,而“movie1”与“movieGen1”在不同的模式中相同。因此,本质上,Cypher每次都会在图形中找到该模式,在查询期间将其保存在内存中,然后返回所有moviesGen2节点,实际上可能是相同的节点n次

MATCH (movie1)<-[:LIKES]-(usersLikingMovie1)-[:LIKES]->(moviesGen1)<-[:LIKES]-(usersGen2)

MATCH(movie1)(moviesgene1)这是一个非常激烈的查询,你越深入,你可能就越接近一组曾经为任何电影评分的用户,因为你基本上只是从给定的电影开始以树状图的形式展开@Huston的
WHERE
DISTINCT
子句将有助于修剪您已经看到的分支,但您仍然只是在树中展开

可以使用两个值来估计树的长度:

  • u、 喜欢电影的平均用户数(传入到:电影)
  • m、 每个用户喜欢的电影的平均数量(从:user传出)
对于估算,您的第一步将返回
m
users。在下一步中,对于每个用户,您将获得他们喜欢的所有电影,然后是喜欢所有这些电影的所有用户:

gen(1) => u
gen(2) => u * (m * u)
对于每一代人,您都会添加另一个
m*u
,因此您的第三代人是:

gen(3) => u * (m * u) * (m * u)
或者更一般地说:

gen(n) => u^n * m^(n-1)
您可以通过计算喜欢/用户和喜欢/电影的平均值来估计分支因子,但这可能非常不准确,因为它为您提供22.2喜欢/用户和2.5喜欢/电影。这些数字对于任何值得评级的电影来说都是不合理的。一个更好的方法是采用评级的中位数或查看直方图,并使用峰值作为分支因子

要正确地看待这一点,请参阅。该培训集拥有17770部电影、480189名用户和100480507名收视率。这是209个收视率/用户和5654个收视率/电影

为了保持简单(假设您的数据集小得多),让我们使用:

m = 20 movie ratings/user 
u = 100 users have rated/movie
您在gen-3中的查询(无差异)将返回:

gen(3) = 100^3 * 20^2
       = 400,000,000
4亿个节点(用户)

由于您只有2700个用户,我认为可以肯定地说,您的查询可能会返回数据集中的每个用户(而是每个用户的148000个ish副本)

ASCII格式的电影节点--
(n:movie{movieid:“88cacfca-3def-4b2c-acb2-8e7f4f4f28be04”}
最小为58字节。如果用户大致相同,假设每个节点有60个字节,则此结果集的存储需求为:

400,000,000 nodes * 60 bytes
= 24,000,000,000 bytes
= 23,437,500 kb
= 22,888 Mb
= 22.35 Gb
因此,根据我的保守估计,您的查询需要22 GB的存储空间。Neo4j会耗尽内存,这似乎很合理

我的猜测是,您试图在用户模式中找到相似之处,但您使用的查询返回数据集中重复多次的所有用户。也许你想问一些关于数据的问题,比如:

  • 哪些用户评价最像我的电影
  • 哪些用户对大多数与我评价相同的电影进行了评价
  • 哪些电影的用户对我看过的类似电影进行了评级,而我还没有看过
干杯,
cm

这是一个非常激烈的问题,你越深入,你可能就越接近一组对任何电影进行评级的用户,
START movie1=node:Movie("MovieId:88cacfca-3def-4b2c-acb2-8e7f4f28be04") 
MATCH (movie1)<-[:LIKES]-(usersLikingMovie1)-[:LIKES]->(moviesGen1)
WITH distinct moviesGen1
MATCH (moviesGen1)<-[:LIKES]-(usersGen2)-[:LIKES]->(moviesGen2)
RETURN moviesGen2;
START movie1=node:Movie("MovieId:88cacfca-3def-4b2c-acb2-8e7f4f28be04") 
MATCH (movie1)<-[:LIKES]-(usersLikingMovie1)-[:LIKES]->(moviesGen1)
WITH distinct moviesGen1
MATCH (moviesGen1)<-[:LIKES]-(usersGen2)
WITH distinct usersGen2
MATCH (usersGen2)-[:LIKES]->(moviesGen2)
RETURN distinct moviesGen2;