Neo4j 查找所有不存在的项目';不要被人买了,数一数买的次数

Neo4j 查找所有不存在的项目';不要被人买了,数一数买的次数,neo4j,cypher,gremlin,Neo4j,Cypher,Gremlin,我有一个像这样的图表 我想找到那些使用cypher购买与Gremlin相同物品的人所购买的所有物品 基本上,我想模拟gremlin示例中的查询,如下所示 g.V().has("name","gremlin") .out("bought").aggregate("stash") .in("bought").out("bought") .where(not(within("stash"))) .groupCount() .order(loca

我有一个像这样的图表

我想找到那些使用
cypher
购买与
Gremlin
相同物品的人所购买的所有物品

基本上,我想模拟
gremlin
示例中的查询,如下所示

g.V().has("name","gremlin")
    .out("bought").aggregate("stash")
    .in("bought").out("bought")
        .where(not(within("stash")))
    .groupCount()
        .order(local).by(values,desc) 
MATCH (n)-[:BOUGHT]->(g_item)<-[:BOUGHT]-(r),
      (r)-[:BOUGHT]->(n_item)
WHERE 
    n.name = 'Gremlin' 
    AND NOT (n)-[:BOUGHT]->(n_item)
RETURN n_item.id, count(*) as frequency
ORDER by frequency DESC
我试着这样做

g.V().has("name","gremlin")
    .out("bought").aggregate("stash")
    .in("bought").out("bought")
        .where(not(within("stash")))
    .groupCount()
        .order(local).by(values,desc) 
MATCH (n)-[:BOUGHT]->(g_item)<-[:BOUGHT]-(r),
      (r)-[:BOUGHT]->(n_item)
WHERE 
    n.name = 'Gremlin' 
    AND NOT (n)-[:BOUGHT]->(n_item)
RETURN n_item.id, count(*) as frequency
ORDER by frequency DESC
3
5
只购买了一次,
4
购买了两次。
有什么问题吗?

Cypher对路径感兴趣,您的匹配项会发现以下内容:

  • 通过Rexter(通过项目2和1)到项目3的2条路径
  • 通过管道(通过项目1和2)到项目5的2条路径
  • 通过Rexter和管道到项目4的4条路径(每人通过项目1和2)
基本上,物品被计数多次,因为每个人都有多条路径通过不同的通用物品与Gremlin连接到同一物品

要获得准确的计数,您需要匹配不同的
r
用户,然后才匹配
r
用户购买的项目(只要他们不在Gremlin购买的项目集合中),或者您需要进行整个匹配,但在进行计数之前,获取每个人的不同项目,这样每个人的每个项目只发生一次…然后获取每个项目的计数(所有人的计数)

下面是一个使用第二种方法的查询

MATCH (n:Person)-[:BOUGHT]->(g_item) 
WHERE n.name = 'Gremlin' 
WITH n, collect(g_item) as excluded
UNWIND excluded as g_item // now you have excluded list to use later
MATCH (g_item)<-[:BOUGHT]-(r)-[:BOUGHT]->(n_item)
WHERE r <> n AND NOT n_item in excluded
WITH DISTINCT r, n_item
WITH n_item, count(*) as frequency
RETURN n_item.id, frequency
ORDER by frequency DESC

我在你的比赛中添加了一个快捷方式,使用:bunded*2表示两个:bunded-hops到
r
,因为我们并不真正关心中间的项目。

Hm…Cypher上的查询看起来不像Gremlin上的查询那么直观。Cypher不是为这种查询而设计的?分组是不同的。如前所述,Cypher是以路径为中心的,它正在寻找到相关节点的所有可能路径,并且由于查询多次通过相同的人(每个普通项目和起始人员),因此计数为off。如果您不需要首先获得不同的人员(或不同的人员/项目组合),那么最初的方法是正确的。这个特定的用例恰好更加冗长。此外,在处理排除的项目和在最后进行属性访问方面,我在性能方面也犯了错误。
如果您不需要先获取不同的人员(或不同的人员/项目组合)
hm,可以避免吗?我只需要项目不同的人员/项目对是必要的,以便您的计数是准确的。被抛弃的是,不同的人通过不同的路径/项目被多次匹配,因此在某一点上(在人级别或人/项目级别),您必须在聚合之前获得不同的值。如果您只需要没有计数的建议项,那么很简单,只需执行完全匹配模式并
返回不同的n_item.id
。我猜你需要计数,每个匹配它的人都需要一个项目计数。是的,我需要计数是因为我想对它进行排序(虽然我可能可以在这里应用一些算法)