【发布时间】:2018-03-15 00:34:06
【问题描述】:
我对 cypher 的实现有疑问。我的问题是这样的:我有一个数据库模型,这里拍照作为概览:https://www.instpic.de/QTIhBbPgVHBHg5pKwVdk.PNG 解释的缩写。红色节点模拟恒星系统,黄色一个跳跃点。每个跳跃点都有一定的大小,它决定了哪个身体可以通过该点。大小作为属性存储在黄色节点之间的关系中。红色节点中还有代表恒星系统轨道天体的其他节点。 (行星、卫星、空间站等)现在,从太阳系中的任何一点(行星、空间站、月亮),我想找到到同一太阳系或另一个太阳系中另一个躺点的最短路径。此外,我可以使用我编写的插件计算系统内两个天体的距离。这个值现在应该包含在寻找路径中,所以我有数据库上最短的路径,也是太阳系内天体之间的最小距离。我已经有一个查询,不幸的是它失败的部分原因是它的性能。我也觉得这里的路径是非常多变的,所以对数据库模型的改变是很好考虑的。
这是我正在使用的实际查询的一部分:
MATCH (origin:Marketplace)
WHERE origin.eid = 'c816c4fa501244a48292f5d881103d7f'
OPTIONAL MATCH (marketplace:Marketplace)-[:Sell]->(currentPrice:Price)-[:Content]->(product:Product)
OPTIONAL MATCH p = shortestPath((origin)-[:HasMoon|:HasStation|:HasLandingZone|:HasPlanet|:HasJumpPoint|:CanTravel*]-(marketplace))
WHERE SIZE([rel in relationships(p) WHERE EXISTS(rel.size)]) <= 3 AND ALL(rel IN [rel in relationships(p) WHERE EXISTS(rel.size)] WHERE rel.size IN ['small', 'medium', 'large'])
WITH origin, marketplace, p, currentPrice, product
CALL srt.getRoutes(origin, marketplace, p) YIELD node, jump_sizes, jump_gates, jump_distance, hops, distance
OPTIONAL MATCH (currentPrice)-[:CompletedVotes]->(:Wrapper)-[:CompletedVote]->(voteHistory:CompletedVote)
OPTIONAL MATCH (currentPrice)-[:CurrentVote]->(vote:Vote)-[:VotedPrices]->(currentVotings)
WITH node, currentPrice, product, jump_sizes, jump_gates, jump_distance, hops, distance, voteHistory, currentVotings, vote, origin
WITH {eid: product.eid, displayName: product.displayName, name: product.name, currentPrice: {eid: currentPrice.eid, price: currentPrice.price}, currentVoting: {approved: vote.approved, count: Count(currentVotings), declined: vote.declined, users: Collect(currentVotings.userId), votes: Collect(currentVotings.price), voteAvg: round(100 * avg(currentVotings.price)) / 100}, voteHistory: Collect({votings: voteHistory.votings, users: voteHistory.users, completed: voteHistory.completed,
vote: voteHistory.votes}), marketplace: {eid: node.eid, name: node.name, type: node.type, designation: node.designation}, travel: {jumpSizes: jump_sizes, jumpGate: jump_gates, jumpDistance: jump_distance, jumps: hops, totalDistance: distance}} as sellOptions, currentPrice ORDER BY currentPrice.price
WITH Collect(sellOptions) as sellOptions
目前,此查询运行良好,但现在我想过滤(在“.... dium ',' large '] 之后)”-> 第 5 行)您需要到达的最小总距离你的目的地,我想用我写的插件来实现这一点,它计算路径中的总距离 (getTotalDistance (path AS PATH))
另外:当我从可能的跳跃大小中删除“大”时,我没有得到任何结果,但我的图表中仍然有一条路径可以引导我到达目标。
另外 2:我正在开发 neo4j 3.3.1,我已经设置了这些配置:
cypher.forbid_shortestpath_common_nodes=false
在 3.3.3 中不起作用
EIDT 1:(更详细的解释)
我有一个地方。然后我搜索销售某些产品的市场。为此,我可以指定更多过滤器。我可以例如说我只能通过“大”大小的跳跃点。另外,我只想要 4 个系统之外的市场。
现在,在数据库中查找上述限制,我搜索到我找到的市场的最短路径。 很可能我有几条满足条件的路径。如果是这种情况,我想过滤掉所有最短路径,即必须克服每个太阳系内最小距离的路径。
这足够准确吗?否则,请报告。
【问题讨论】:
-
您可以在边缘写下您使用插件计算的所有距离,然后使用或修改 apoc 程序中的最短路径算法。你已经试过了吗?或者你有理由不使用它吗?距离可变吗?
-
如果我没看错,您正在寻找性能更高的 shortestPath?除了尺寸限制之外,您能否更详细地口头描述这方面的要求?看起来您希望限制路径中的跳跃次数?另外,为什么是关系的大小而不是跳跃点节点?
-
你能不能也PROFILE这个查询并添加查询计划(扩展所有元素)?我们可能会找到一些可以优化的东西。可能至少有一个主要的基数问题正在减慢这一速度。
-
另一个观察结果...每对相邻的跳跃点之间有两个关系,每个方向都有一个关系(并且可能是同一类型)。是否需要,关系上的属性存在一些差异,或者某些对只存在一种关系而不是两种关系?如果没有,您可以考虑重构,以便每个跳转点对之间仅存在一个关系。
-
我今天把所有的cmet都过一遍,这里是提前查询计划:instpic.de/KmItH20rwZN9F01dxY8p.png
标签: neo4j cypher graph-databases