【问题标题】:Modeling large datasets to avoid long-running queries对大型数据集进行建模以避免长时间运行的查询
【发布时间】:2015-09-10 16:41:10
【问题描述】:

我目前正在使用由 3 种类型的节点组成的 neo4j 数据库:“用户”、“商家”和“报价”。

用户点击优惠,然后从商家处购买。因此,存在以下关系:

(:User)-[:PURCHASED_FROM]->(:Merchant)
(:User)-[:CLICKED_ON]->(:Offer)

我想执行一个密码查询,该查询将根据有多少其他具有相似品味的用户从该商家购买过商品,向特定用户推荐商家。所以我相信这是一个非常标准的协同过滤查询。

查询如下所示:

MATCH(u:User{userId:1234)-[:PURCHASED_FROM]->(:Merchant)<-[:PURCHASED_FROM]-(:User)-[r:PURCHASED_FROM]->(newMerchants:Merchant)
WHERE NOT (u)-[:PURCHASED_FROM]->(newMerchants)
RETURN DISTINCT newMerchants.name, newMerchants.merchantId, count(r) AS rel_count
ORDER BY rel_count DESC
LIMIT 30

我的问题是这个查询需要很长时间才能运行。事实上,这需要很长时间,我还没有看到它完成。删除 count() 聚合函数会有所帮助,但我需要按此关系计数进行排序,以便用户看到与他们最相关的商家。

我认为问题是由于图中节点和关系的数量以及执行上述查询时发生的遍历次数造成的。

单个商家节点拥有 >1m :PURCHASED_FROM 关系的情况并不少见。

我认为这一定是一个在大图中经常出现的问题。有哪些建模方法可用于减少查询时所需的遍历次数?

【问题讨论】:

标签: neo4j


【解决方案1】:

UserMerchant 之间是否有多个 PURCHASED_FROM 关系?如果是这样,使用MERGE 在每对之间仅创建一个并在关系上存储count 属性可能更有意义。那么也许你可以这样总结count

MATCH(u:User{userId:1234)-[:PURCHASED_FROM]->(:Merchant)<-[:PURCHASED_FROM]-(:User)-[r:PURCHASED_FROM]->(newMerchants:Merchant)
WHERE NOT (u)-[:PURCHASED_FROM]->(newMerchants)
RETURN DISTINCT newMerchants.name, newMerchants.merchantId, sum(r.count) AS rel_count
ORDER BY rel_count DESC
LIMIT 30

【讨论】:

  • 肯定存在两个节点之间存在多个 PURCHASED_FROM 关系的情况。将这些关系扁平化为具有计数属性的单个关系非常有意义 - 感谢您的建议。
猜你喜欢
  • 2022-01-15
  • 1970-01-01
  • 1970-01-01
  • 2020-10-09
  • 1970-01-01
  • 2010-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多