我在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
目前,此查询效果非常好,但现在我想过滤(在&#34; .... dium&#39;,&#39; large&#39;之后)&#34; - &GT; 5)你到达目的地所需的最小总距离,我想通过我的书面插件来实现这一点,该插件计算路径中的总距离(getTotalDistance(path AS PATH))
另外一点:当我切断“大&#39;从可能的跳跃大小来看,我没有得到任何结果,但我的图表中仍然有一条路径引导我进入目标。
另外2:iam正在使用neo4j 3.3.1,我设置了这些配置:
cypher.forbid_shortestpath_common_nodes=false
在3.3.3中不起作用
EIDT 1 :(更详细的解释)
我有一个地方。然后我搜索销售某些产品的市场。为此,我可以指定更多过滤器。我可以,例如说我只能通过大小的跳跃点来旅行#34;此外,我只想要4系统的市场。
现在,在数据库中查看上述限制,我搜索到找到的市场最短路径。 很可能我有几条路径符合条件。如果是这种情况,我想过滤掉所有最短路径,即每个路径必须克服每个太阳系内最小距离的路径。
这够准确吗?否则,请报告。
答案 0 :(得分:0)
最新的APOC版本可能会在这里提供帮助,尽管APOC路径扩展器在标签和关系类型方面效果最佳,因此可能需要对模型进行细微更改。
特别是你跳跃点的大小。现在这是它们之间关系的属性,但是为了让APOC以最佳方式工作,可以使用大小作为标签更好地建模这些:JumpPoint节点本身,所以你可能有:JumpPoint:Small,:JumpPoint:Medium ,和:JumpPoint:Large(如果您愿意,可以在rel属性之外添加它)。
请记住,这种方法比shortestPath()更复杂,因为我们的想法是尝试在一定数量的跳转中找到系统,然后找到:在这些星系统可以到达的市场,然后基于过滤器关于他们是否销售我们想要的产品,我们会在找到这些产品时将这条路拼接在一起。
MATCH localSystemPath = (origin:Marketplace)-[*]-(s:Solarsystem)
WHERE origin.eid = $originId
WITH origin, localSystemPath, s
LIMIT 1
WITH origin, localSystemPath, s,
CASE WHEN coalesce($maxJumps, -1) = -1
THEN -1,
ELSE 3*$maxJumps
END as maxJumps,
CASE $shipSize
WHEN 'small' THEN ''
WHEN 'medium' THEN '|-Small'
ELSE '|-Small|-Medium'
END as sizeBlacklist
CALL apoc.path.spanningTree(s,
{relationshipFilter:'HasJumpPoint|CanTravel>', maxLevel:maxJumps,
labelFilter:'>Solarsystem' + sizeBlacklist, filterStartNode:true}) YIELD path as jumpSystemPath
WITH origin, localSystemPath, jumpSystemPath, length(jumpSystemPath) / 3 as jumps, last(nodes(jumpSystemPath)) as destSystem
MATCH destSystemPath = (destSystem)-[*]-(marketplace:Market)
WHERE none(rel in relationships(destSystemPath) WHERE type(rel) = 'HasJumpPoint')
AND <insert predicate for filtering which :Markets you want>
WITH origin, apoc.path.combine(apoc.path.combine(localSystemPath, jumpSystemPath), destSystemPath) as fullPath, jumps, destSystem, marketplace
CALL srt.getRoutes(origin, marketplace, fullPath) YIELD node, jump_sizes, jump_gates, jump_distance, hops, distance
...
这假定$ shipSize的参数输入为所有跳转门的最小尺寸,$ originId作为原点的id:市场(加上你肯定需要:Marketplace(eid)
上的索引或唯一约束来快速查找此处)和$ maxJumps,以获得到达目标系统的最大跳转次数。
请记住,使用的扩展程序spanningTree()
只能找到到另一个系统的最短路径。如果您需要所有可能的路径,包括指向同一系统的多条路径,请将过程更改为expandConfig()
。