Neo4j-DB 中最常见的元组

Most common tuples in Neo4j-DB

我的数据库中的订单和产品节点通过包含关系连接:

(:order)-[:contains]->(:product)

我想知道是否有可能找到以相同顺序出现的最常见的 n 元组产品。

恐怕这是不可能的,因为我有超过 1500 种产品,即使对于小 n,这些产品之间可能的组合数量也非常多,例如1500^4 ≈ 5*10^12.

我为 n=3 编写了以下测试查询:

MATCH (o:order)-[r:contains]->(p:product)
WITH count(r) as NrProds, o 
MATCH (o)-[r:contains]->(p:product)
WHERE NrProds > 3
WITH o
MATCH  (o)-[r1:contains]->(p1:product),(o)-[r2:contains]->(p2:product),(o)-[r3:contains]->(p3:product)
WITH o,p1,p2,p3,count(r1) as r1,count(r2) as r2,count(r3) as r3
WITH  o,p1,p2,p3,
CASE WHEN r1<r2 AND r1<r3 THEN r1
     WHEN r2<r1 AND r2<r3 THEN r2
     WHEN r3<r1 AND r3<r2 THEN r3
     END as result
WITH result,o,p1,p2,p3
RETURN count(result) as NrPurchs, o.Id,p1.name,p2.name,p3.name ORDER BY NrPurchs DESC

首先,我确保不考虑任何产品数量少于 3 的订单,因为这些订单占所有订单的很大一部分,然后我匹配这些订单中的包含关系。 我的计算机没有完成查询,考虑到正在创建的大型连接,这并不奇怪。

有没有一种不用查询那么多可能性就能找到元组的方法,这样我的电脑就可以完成计算了?

正如您所指出的,产品的组合数量太多,因此最好从订单端开始生成元组,以仅生成现有的元组。

您的过滤器之前有一个不必要的 MATCH,以下应该足以过滤掉带有 :

的订单
MATCH (o:order)-[r:contains]->(p:product)
WITH count(r) as NrProds, o 
WHERE NrProds >= 3 // note >= sign for orders with 3 and more
WITH o
...

或者如果您的 order 仅针对产品使用 contains 关系:

MATCH (o:order)
WITH o,size((o)-[:contains]->()) as NrProds
WHERE NrProds >= 3
WITH o
...

为了避免重复,通过按 ID、名称等对相同产品进行排序来过滤掉相同产品的排列。(此 where 子句仅适用于唯一 names/ids。如果您有重复项,则需要 <= )

...
MATCH  (o)-[r1:contains]->(p1:product),(o)-[r2:contains]->(p2:product),(o)-[r3:contains]->(p3:product)
WHERE p1.name < p2.name AND p2.name < p3.name
...

然后 return 每个元组的订单数:

RETURN p1,p2,p3,COUNT(o) as c

(如果您在单个订单和产品之间有多个 contains 关系,您应该使用 COUNT(DISTINCT o)

最后return只有N个元组:

ORDER BY c DESC LIMIT {n}

整个查询:

MATCH (o:order)
WITH o,size((o)-[:contains]->()) as NrProds
WHERE NrProds >= 3
WITH o
MATCH 
  (o)-[r1:contains]->(p1:product),
  (o)-[r2:contains]->(p2:product),
  (o)-[r3:contains]->(p3:product)
WHERE p1.name < p2.name AND p2.name < p3.name
RETURN p1,p2,p3,COUNT(o) as c
ORDER BY c DESC LIMIT {n}