【发布时间】:2019-04-01 15:58:16
【问题描述】:
我是图形数据库的新手,需要针对这种情况的建议。我有人喜欢这些类别(只有树上的叶子),其他节点(父母)没有得到“喜欢”。然后我计算特定用户与其他用户的所有连接的分数。这是一个图形示例:
我尝试使用 neo4j,我没有问题(非常小的数据集),但我担心很多用户的性能。我用以下查询进行了测试:
MATCH (n:Person)-[:LIKES*]->()-[r:SUB*0..4]-()<-[:LIKES*]-(m:Person)
WHERE n.name='Gabriel' and n<>m
WITH n.name as user, m.name as connection, 1.0/(length(r)+1)*count(r) as score
RETURN user, connection, sum(score)
我也考虑过在关系数据库中做这件事,为类别喜欢(cat1,cat2,cat3)保存 3 个字段,然后进行 3 个自连接,在不同的类别级别中寻找匹配项。类似的东西(从用户 1 开始并尝试与其他人匹配):
select l2.user_id, sum(
case
when (l1.cat2 = l2.cat2 and l1.cat3 = l2.cat3) then 1
when (l1.cat2 = l2.cat2) then 0.25
else 0.05
end)
from likes l1
inner join likes l2 on l1.cat1 = l2.cat1 and l2.user_id <> 1
where l1.user_id = 1
group by l2.user_id
但我还读到您应该避免进行自联接。
我澄清一下,我正在寻找读取性能,写入无关紧要。 我的目标是它适用于 100 万用户,每个用户有 10 个赞。 我听取任何意见,谢谢!
【问题讨论】:
-
你好@diez-gabriel,这是一个非常好的问题,也在这里进行了一些探索:stackoverflow.com/questions/29629903/graph-database-performance。或许您可以让这里的每个人多了解一下数据的预期大小?
-
@TsTeaTime 感谢您的文章,澄清了我需要从子图开始。我用预期的尺寸数据编辑了帖子。
-
关于您的 Cypher 代码: 1. 除非
Person节点有可能具有一系列连续的传出LIKES关系,否则您应该使用[:LIKE]而不是[:LIKE*]. 2. aggregated valuecount(r)很可能始终为 1,因为(使用您的数据模型)查询不应该为给定的一对Person节点多次返回相同的r列表。 -
@cybersam 你是对的,它必须是 [:LIKES] 没有 *。另一方面,count(r) 可以不同于 1。例如,如果 (Gabriel)-[: LIKES]->(BocaJuniors),则 Gabriel 到 Raul 或 Juana 有两条长度为 4 的路径。
-
你说得对#2——我在想
COUNT(DISTINCT r)。但使用COUNT(*)可能更清楚。