一个不寻常的密码查询挑战:查找与按标签分组的节点的交集

An unusual cypher query challenge: finding intersections with nodes grouped by label

我正在尝试找到一个通用的(ist)密码查询,而无需指定标签,这将实现以下用例。

catch 试图找到一个有效的查询来验证以下内容:用户必须与至少一个与广告具有相同标签的节点相关才能看到它。一般架构如下所示:

我查看了 cypher 中的交集和并集技术,包括 apoc.intersection 过程,但它在这种情况下确实有效。

数据库包含大约 6M 关系,效率至关重要。我们总是试图为一个用户找到一个随机广告(查询总是以 MATCH (u:User{id:"1"})... 开头。我写了很多不成功的测试,但我不确定我可以使用哪种有效的方法来解决这样的问题。任何帮助将不胜感激!

一个简单的匿名模式匹配就会得到结果,例如:

MATCH (u:User {id:'1'})-->()<--(a:Ad)
RETURN DISTINCT a.id, ...
[ORDER BY] 
[LIMIT 1]

它需要分析才能了解它在您的数据集上的行为,但它不太可能满足您的效率需求。

强制随机排序会进一步降低查询速度,例如

MATCH (u:User {id:'1'})-->()<--(a:Ad)
WITH a, rand() as sortOrder
RETURN DISTINCT a.id, ..., sortOrder
ORDER BY sortOrder ASC 
LIMIT 1

如果我在我的一个图形数据库(在 m5.xlarge EC2 实例上)尝试类似的操作,其中大约有 35k 'u' 个节点、600k 'a' 个节点和 1700 万个节点它们之间的边缘 - 在分析时,我在 9852 毫秒内看到 11,054,599 次数据库命中!

APOC/GDS路径功能好像不能满足你的需求。 尽管您可以考虑编写一个用户定义的函数,例如基于APOC's Neighbors code

图表增长的速度有多快以及更新的频率如何? 只是想知道是否有其他方法(例如预先计算的图形嵌入)可以帮助满足您的响应时间要求。

您是否尝试过类似的方法,即两步法,从用户的广告中减去“标签”的标签?

MATCH (u:User {id:'1'})-->()<--(a:Ad)
WITH DISTINCT u,a
WHERE 
     SIZE(apoc.coll.subtract( 
                              [(a)-->(tag) | labels(tag)[0]],
                              [(u)-->(tag)<--(a) | labels(tag)[0]]
                            )
         ) = 0
RETURN a,rand() AS rand
ORDER BY rand LIMIT 1