如何使用Cypher

时间:2015-08-22 22:12:56

标签: neo4j cypher graph-databases

我是neo4j的新手,毫无疑问我喜欢它。

现在我的查询是我有一个数据库,其中有用户访问过一个或多个网址,这些网址包含一个或多个标记。

现在我想要的是为访问过多个网址的特定用户检索标记。

这种关系有点像这样:

(适用:用户) - [:VISITED] - GT;(:URL) - [:含有] - >(:标记)

现在我想要检索访问过多个网址的用户以及所有这些网址中包含的所有标记。所以基本上我想要用户访问过的所有标签,其中访问的网址不止一个。

2 个答案:

答案 0 :(得分:3)

使用 Cypher 2.X ,这应该可以完成工作:

MATCH (user:User)
MATCH user-[:VISITED]->(url:URL)
WITH count(url) AS countUrl, url
WHERE countUrl > 1
MATCH url-[:CONTAINS]->(tag:Tag)
RETURN user.id, collect(tag) AS tags //you can show whatever you want here

答案 1 :(得分:3)

您仍然可以优化Mik378提供的查询。

事实上,在Cypher中,您可以使用size(pattern)子句重现与getDegree等效的java:

MATCH (n:User)-[:VISITED]->(url)<-[:TAGS]-(tag:Tag)
WHERE size((n)-[:VISITED]->()) > 1
RETURN n.email, collect(distinct tag.name) as tags

将导致以下查询计划:

+------------------+---------------+------+--------+------------------------------------------+----------------------------------------------------+
|         Operator | EstimatedRows | Rows | DbHits |                              Identifiers |                                              Other |
+------------------+---------------+------+--------+------------------------------------------+----------------------------------------------------+
| EagerAggregation |             3 |    5 |     90 |                            n.email, tags |                                            n.email |
|       Projection |             7 |   24 |     48 | anon[15], anon[37], n, n.email, tag, url |                                       n.email; tag |
|        Filter(0) |             7 |   24 |     24 |          anon[15], anon[37], n, tag, url |                                            tag:Tag |
|   Expand(All)(0) |             7 |   24 |     34 |          anon[15], anon[37], n, tag, url |                               (url)<-[:TAGS]-(tag) |
|        Filter(1) |             3 |   10 |     10 |                         anon[15], n, url |                                            url:Url |
|   Expand(All)(1) |             3 |   10 |     15 |                         anon[15], n, url |                              (n)-[:VISITED]->(url) |
|        Filter(2) |             2 |    5 |     10 |                                        n | GetDegree(n,Some(VISITED),OUTGOING) > {  AUTOINT0} |
|  NodeByLabelScan |             5 |    5 |      6 |                                        n |                                              :User |
+------------------+---------------+------+--------+------------------------------------------+----------------------------------------------------+

Total database accesses: 237

查询是我的测试数据库,因此对于您当前的实现,它应该是:

MATCH (n:User)-[:VISITED]->(url)-[:CONTAINS]->(tag:Tag)
WHERE size((n)-[:VISITED]->()) > 1
RETURN n.email, collect(distinct tag.name) as tags