首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >找到所有不是一个人购买的物品,并计算购买的次数

找到所有不是一个人购买的物品,并计算购买的次数
EN

Stack Overflow用户
提问于 2019-01-20 15:38:44
回答 1查看 44关注 0票数 0

我有一个图表,看起来像这样。

我想找到人们购买的所有物品,他们使用cypher购买了与Gremlin相同的物品。

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

代码语言:javascript
运行
AI代码解释
复制
g.V().has("name","gremlin")
    .out("bought").aggregate("stash")
    .in("bought").out("bought")
        .where(not(within("stash")))
    .groupCount()
        .order(local).by(values,desc) 

我试着这样做

代码语言:javascript
运行
AI代码解释
复制
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

但它似乎没有正确计算frequencies -它们似乎是两倍大。

代码语言:javascript
运行
AI代码解释
复制
4 - 4
5 - 2
3 - 2

35只被买了一次,4被买了两次。有什么问题吗?

EN

回答 1

Stack Overflow用户

发布于 2019-01-21 10:04:42

Cypher对路径感兴趣,您的匹配会找到以下内容:

  • 2通过Rexter (通过物料2和1)到物料3的路径
  • 2通过管道(通过物料1和2)到物料5的路径
  • 4通过Rexter和管道(通过每个人的物料1和2)到物料4的路径

基本上,这些项目会被计算多次,因为通过Gremlin的不同常见项目,每个人都有多条通往同一项目的路径。

为了获得准确的计数,你要么需要匹配不同的r用户,然后只匹配r用户购买的商品(只要他们不在Gremlin购买的商品集合中),要么你需要进行整个匹配,但在进行计数之前,获取每个人的不同商品,这样每个人的商品只发生once...then获得每件商品的数量(所有人的数量)。

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

代码语言:javascript
运行
AI代码解释
复制
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

您应该在图形中使用标签,并且应该在查询中使用它们,以便利用索引并在图形中快速找到起点。在您的例子中,在:Person(name)上建立索引,并在查询中使用:Person标签,即使向图中添加了更多的节点和更多的:Person,也应该会更快。

编辑

如果您只是在寻找查询的简洁性,并且没有足够大的图,而性能将是一个问题,那么您可以使用原始查询,但在计算项目之前添加一行以获得不同的rn_item行。这确保了当您获得计数时,每个人只计算一次物品。

请注意,放弃了处理排除项的优化(它将对每个项执行模式匹配,而不是聚合购买项的集合并执行集合成员关系检查),并且它在进行属性访问时聚合项,而不是仅在节点聚合之后才进行属性访问。

代码语言:javascript
运行
AI代码解释
复制
MATCH (n:Person)-[:BOUGHT*2]-(r)-[:BOUGHT]->(n_item)
WHERE n.name = 'Gremlin' 
WITH DISTINCT n, r, n_item
WHERE NOT (n)-[:BOUGHT]->(n_item)
RETURN n_item.id, count(*) as frequency
ORDER by frequency DESC

我在您的匹配中添加了一个快捷方式,使用: about *2来指示两个:已购买的到r的跳数,因为我们并不真正关心中间的项目。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54278050

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档