除了稍后在LIMIT n
上过滤之外,是否有一种默认方式如何只匹配前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
,而是一个随机子集。这种方法应该在性能上更快 - 现在我有~500ms的查询时间但是想要将其降低到50ms以下。
我知道我可以将上面的查询分成两个独立的查询,但仍然在第一个查询中它会通过所有用户,而后来它会限制输出。我想在match
阶段限制最大相对数。
答案 0 :(得分:2)
您可以使用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
的前十个u
(意味着您可以拥有如果它们与前10个u
匹配,则返回超过10行。
答案 1 :(得分:1)
这不是你问题的直接解决方案,但由于我遇到了类似的问题,我的解决方案对你来说可能很有趣。
我需要做的是:通过索引获取关系(可能会产生数千个)并获取这些关系的起始节点。由于起始节点始终与索引查询相同,因此我只需要第一个关系的startnode。
由于我无法通过cypher实现这一点(ean5533提出的查询效果不佳),我使用的是简单unmanaged extension(nice 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流式传输,您应该能够创建将您的查询转换为非托管扩展并仍然获得完整性能。 例如,“java-querying”所有符合条件的节点,并将部分结果发送到HTTP流。