2013-04-25 65 views
3

是否有一个默认的方式如何匹配只有前n个关系,除了在LIMIT n以后过滤?neo4j - 如何匹配只有前n关系

我有这个疑问:

START n=node({id}) 
MATCH n--u--n2 
RETURN u, count(*) as cnt order by cnt desc limit 10; 

但假设的n--u关系的数量是非常高的,我想放松一下这个查询并采取例如第100间随机的关系,不是继续u--n2...

这是为了协作过滤任务,并且假设用户更不相似,我不想匹配所有用户u而是随机子集。这种方法在性能上应该更快 - 现在我的查询时间达到了500毫秒左右,但想要将其降低到50毫秒以下。

我知道我可以将上面的查询分成两个单独的查询,但仍然在第一个查询中,它经历了所有用户,并且不久后它限制了输出。我想在match阶段限制最大值。

回答

1

可以通过管道使用WITH,然后LIMIT这些初步结果,然后继续在同一查询您的查询的最新结果:

START n=node({id}) 
MATCH n--u 
WITH u 
LIMIT 10 
MATCH u--n2 
RETURN u, count(*) as cnt 
ORDER BY cnt desc 
LIMIT 10; 

上面的查询将会给你的第一个10名u作者发现,然后继续找到前10个匹配的n2

可选,可以去掉第二LIMIT,你会得到所有匹配n2 S为前十u秒(这意味着你可以有,如果他们匹配的第一个10个u S比超过十行返回)。

+0

对,但恐怕第一个“限制10”确实限制了所有发现的“u”因此仍在处理我不想要的东西。或者有什么变化,并且密码分析器现在没有经过所有的关系,但真的只解析前10个? – ulkas 2013-04-26 13:05:59

+2

第一个“限制10”应该导致移动者在找到前10个“u”后停下来。它不应该处理所有可能的'u's。如果您怀疑它正在处理的比应该更多,那么您应该向neo4j提交一个错误。 – ean5533 2013-04-26 14:55:51

1

这不是您的问题的直接解决方案,但由于我遇到了类似的问题,我的解决方法可能对您很有意思。

我需要做的是:通过索引获得关系(可能会产生数千)并获得这些关系的开始节点。由于起始节点始终与该索引查询相同,因此我只需要第一个关系的startnode。由于我无法用密码实现(由ean5533提出的查询不会更好),所以我使用简单的unmanaged extensionnice template)。

@GET 
@Path("/address/{address}") 
public Response getUniqueIDofSenderAddress(@PathParam("address") String addr, @Context GraphDatabaseService graphDB) throws IOException 
{ 
    try { 
     RelationshipIndex index = graphDB.index().forRelationships("transactions"); 
     IndexHits<Relationship> rels = index.get("sender_address", addr); 

     int unique_id = -1; 
     for (Relationship rel : rels) { 
      Node sender = rel.getStartNode(); 
      unique_id = (Integer) sender.getProperty("unique_id"); 
      rels.close(); 
      break; 
     } 

     return Response.ok().entity("Unique ID: " + unique_id).build(); 
    } catch (Exception e) { 
     return Response.serverError().entity("Could not get unique ID.").build(); 
    } 
} 

对于这种情况下,加速是相当不错的。

我不知道你的确切用例,但由于Neo4j甚至支持HTTP流afaik,你应该能够创建转换你的查询到一个非托管的扩展,并仍然得到完整的性能。 例如,“java-查询”所有合格的节点并将部分结果发送到HTTP流。