简体   繁体   English

Neo4j Cypher 具有超限制性模式理解 - 还是我用错了?

[英]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值作为参数idorderlimit传递):

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) ,其中FForum节点的数量(可能相对恒定), 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM