[英]Neo4j Cypher has ultra-restrictive pattern comprehension - or am I using it wrong?
I recently picked up Neo4j as it seemed the best type of database to store data I'm currently scraping off a number of online discussion forums.我最近选择了 Neo4j,因为它似乎是存储数据的最佳数据库类型,我目前正在从一些在线讨论论坛中删除。 The primary structure of the graph is Community -> Forum -> Thread -> Post -> Author图的主要结构是 Community -> Forum -> Thread -> Post -> Author
I'm trying to write the Cypher queries to resolve GraphQL queries, and would like to paginate (for example) the Forum -> Thread connection.我正在尝试编写 Cypher 查询来解决 GraphQL 查询,并且想对论坛-> 线程连接进行分页(例如)。 The relationship is CONTAINS which holds an order
property ie (f:Forum)-[:CONTAINS]->(t:Thread)
关系是包含一个order
属性,即(f:Forum)-[:CONTAINS]->(t:Thread)
From the neo4j-graphql-js library I picked up on their usage of pattern comprehension to run an "inner query" on the child nodes.从 neo4j-graphql-js 库中,我了解到他们使用模式理解在子节点上运行“内部查询”。 For example:例如:
MATCH (f:Forum { id: $id })
RETURN f { .id, .name, .url, threads: [(f)-[:CONTAINS]->(t:Thread) | t { .id, .title, .url }] }
I'd really like to use ORDER BY, LIMIT and SKIP on the inner pattern comprehension, but unfortunately this is not supported: https://github.com/opencypher/openCypher/issues/202 - the neo4j-graphql-js library gets around this by using apoc.coll.sortMulti
but I've noticed performance is not great & a lot slower than if I were to use the ORDER BY clause on a top-level pattern equivalent.我真的很想在内部模式理解上使用 ORDER BY、LIMIT 和 SKIP,但不幸的是,这不受支持: https://github.com/opencypher/openCypher/issues/202 - neo4j-graphql-js 库得到通过使用apoc.coll.sortMulti
来解决这个问题,但我注意到性能不是很好,而且比在顶级模式等效项上使用 ORDER BY 子句要慢很多。
Since I'm new to graph DBMS, this has got me wondering if I may have misunderstood how a graph DB is supposed to be used.由于我是图形 DBMS 的新手,这让我想知道我是否误解了应该如何使用图形 DB。 From a "frontender" perspective, the ability to implement paginating in the lowest-level query language seems like a critical piece, but again, maybe I've not understood things correctly.从“前端”的角度来看,以最低级别的查询语言实现分页的能力似乎是一个关键部分,但同样,也许我没有正确理解事情。 Square peg, round hole, and all that!方钉、圆孔等等!
Is this a fair evaluation?这是一个公平的评价吗? Is there another option in Cypher that will solve this? Cypher 中是否有另一个选项可以解决这个问题? Or, should I just go back to use an SQL database for this use case?或者,我应该只使用 go 来为这个用例使用 SQL 数据库吗?
[EDITED] [编辑]
If you moved the order
property into the Thread
nodes (which should be valid if each Thread
node is connected to only a single Forum
), then you can create an index (or uniqueness constraint ) on :Thread(order)
to speed up your query.如果您将order
属性移动到Thread
节点(如果每个Thread
节点仅连接到一个Forum
应该是有效的),那么您可以在:Thread(order)
上创建一个索引(或唯一性约束)以加快您的查询.
For example, this query should leverage the index to paginate forward faster (assuming that the f.id
, the order
value to use for pagination purposes, and limit
value are passed as theparameters id
, order
, and limit
):例如,此查询应利用索引更快地向前分页(假设f.id
、用于分页目的的order
值和limit
值作为参数id
、 order
和limit
传递):
MATCH (f:Forum)-[:CONTAINS]->(t:Thread)
WHERE f.id = $id AND t.order > $order
WITH f, t
ORDER BY t.order
LIMIT $limit
RETURN f{.id, .name, .URL,
firstOrder: MIN(t.order),
lastOrder: MAX(t.order),
threads: [x IN COLLECT(t) | x{.id, .title, .URL}]}
And here is a (slightly more complex, but also fast) query for backwards pagination:这是一个(稍微复杂一点,但也很快)的反向分页查询:
MATCH (f:Forum)-[:CONTAINS]->(t:Thread)
WHERE f.id = $id AND t.order < $order
WITH f, t
ORDER BY t.order DESC
LIMIT $limit
WITH f, t
ORDER BY t.order
RETURN f{.id, .name, .URL,
firstOrder: MIN(t.order),
lastOrder: MAX(t.order),
threads: [x IN COLLECT(t) | x{.id, .title, .URL}]}
If you analyze the PROFILE of the above queries with various $limit
values, you should see that the db-hit complexity is O(F*L)
, where F
is the number of Forum
nodes (which is probably relatively constant) and L
is the $limit
value.如果您使用各种$limit
值分析上述查询的PROFILE ,您应该看到 db-hit 复杂度为O(F*L)
,其中F
是Forum
节点的数量(可能相对恒定), L
是$limit
值。 So, these queries should be significantly faster -- with the index -- as long as:因此,这些查询应该明显更快——使用索引——只要:
F*L << (average number of `Threads` per `Forum`).
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.