如何限制每个节点Neo4j Cypher的子节点

时间:2014-03-09 15:25:01

标签: cypher neo4jphp node-neo4j neo4j

我是Neo4j的新手,我有以下情况

enter image description here

在上图中,表示标签为user的节点,其子节点具有标签shops。这些子节点中的每一个都具有标签items的子节点。每个节点items具有属性size,并且每个节点size的{​​{1}}属性的项节点按降序排列,如图所示。

问题

我想从每个shops获得两个items节点,其大小小于或等于17。 怎么做?我试过了,但它不按我需要的方式工作

这是我试过的

shops

注意 - 这些match (a:user{id:20000})-[:follows]-(b:shops) with b match (b)-[:next*]->(c:items) where c.size<=17 return b limit 2 节点可以有数千个shops个节点。因此,如何在不遍历所有数千个items节点的情况下找到所需节点。 请提前帮助,谢谢。

2 个答案:

答案 0 :(得分:3)

现在Cypher不能很好地处理这个案例,我可能会为此做一个基于java的非托管扩展。

看起来像这样:

public List<Node> findItems(Node shop, int size, int count) {
   List<Node> results=new ArrayList<>(count);
   Node item = shop.getSingleRelationship(OUTGOING, "next").getEndNode();
   while (item.getProperty("size") > size && results.size() < count) {
       if (item.getProperty("size") <= size) result.add(item);
       item = item.getSingleRelationship(OUTGOING, "next").getEndNode();
   }
   return result;
}


List<Node> results=new ArrayList<>(count*10);
for (Relationship rel = user.getRelationships(OUTGOING,"follows")) {
   Node shop = rel.getEndNode();
   results.addAll(findItems(shop,size,count));
}

答案 1 :(得分:0)

您可以通过根据尺寸分组来避免遍历每个商店的所有商品。在这种方法中,您的图表看起来像这样

(:User)-[:follows]-(:Shop)-[:sells]-(:Category {size: 17})-[:next]-(:Item)

然后,您可以使用

找到每个商店的两件商品
match (a:User {id: 20000})-[:follows]-(s:Shop)-[:sells]-(c:Category)
where c.size <= 17
with *
match p = (c)-[:next*0..2]-()
with s, collect(tail(nodes(p))) AS allCatItems
return s, reduce(shopItems=allCatItems[..0], catItems in allCatItems | shopItems + catItems)[..2]

shopItems=allCatItems[..0]是一种类型检查问题的解决方法,它实际上将shopItems初始化为一个空的节点集合。