2017-08-12 99 views
0

以下是我的Neo4j DB模型的简化模式。 我尝试了几个基于一些帖子的Cypher查询,但没有任何工作。我需要Neo4j查询帮助

My Neo4j Model Example

我想找到所有的部件和所有的供应商,为自行车数量。

复杂性在于某些组件与供应商相关联,在这种情况下,只有在上层组件具有正确版本时才会遵循分支。

实例:

  • 自行车数6具有分量ID = 3与供应商ID = 3和组件ID = 1与供应商ID = 1
  • 自行车数1具有部件ID = 1与供应商ID = 2
  • 自行车数3具有成分ID = 1与供应商ID = 2,部件ID = 2与供应商ID = 3

我想获得的节点和的关系。

有人可以帮助我吗?

+2

那么每个自行车有一个节点,给它一个数字。 (b:自行车) - [:COMPOSED_OF] - >(c:Component {reference:internalRefAtBi​​keMaker}) - [:SUPPLIED_BY {supplierPartReference:azertyui}] - >(s:Supplier {name:“SuperSupplier”}) 类似的东西 –

+0

我会知道如何查询这样的图表,如果我可以创建它:)。但我不知道如何重组整个图,因为它由1百万个可能的组件组成。如果你可以帮助我创建图表,你可以从我发布的图表中提出,它可能是一个解决方案... – lug

+0

看起来你对同一供应商使用多个节点,因为图形中的供应商节点确实象征着供应商的一部分,而不是自己的供应商。这在你的'(:Supplier) - [:IsIn] - >(:Component)'关系中也很明显,因为它通常没有意义,除非节点是特定部件的供应商。说'(:Component) - [:IsIn] - >(:Component)''会更有意义。你有没有灵活性来修复这个数据模型?由于它存在,您也无法利用索引查找,因此在大图上查询速度会很慢。 – InverseFalcon

回答

0

基本上,你想要的是把所有子图的项目,但过滤掉失败的过滤器关系的路径。您可以使用ALL/NONE/ANY来确保拾取的路径不违反任何约束。

下面是一个假设from和to可以单独定义的例子,但我认为它足够清晰以适应您的需求。(注意:您可以使用TYPE(r)检查关系类型名称太)

WITH 11 as num 
MATCH p=(s:Bike)-[*..25]-(n) 
WHERE 
ALL(r IN RELATIONSHIPS(p) WHERE 
    (NOT EXISTS(r.RANGEFROM) OR toInteger(r.RANGEFROM) <= num) AND 
    (NOT EXISTS(r.RANGETO) OR num <= toInteger(r.RANGETO))) 
AND TYPE(RELATIONSHIPS(p)[-1]) = "LO" 
WITH NODES(p) as ns, RELATIONSHIPS(p) as rs 
UNWIND ns as n UNWIND rs as r 
RETURN COLLECT(DISTINCT n), COLLECT(DISTINCT r) 

或者这应该是更有效的。

WITH 11 as num 
MATCH (ci)-[lo:LO]->(ds) 
WHERE toInteger(lo.RANGEFROM) <= num <= toInteger(lo.RANGETO) 
WITH ds, COLLECT(lo) as lo 
MATCH p=shortestpath((b:Bike)-[*..25]->(ds)) 
WHERE ALL(r IN RELATIONSHIPS(p) WHERE TYPE(r) <> "LO" OR r in lo) 
WITH NODES(p) as ns, RELATIONSHIPS(p) as rs 
UNWIND ns as n UNWIND rs as r 
RETURN COLLECT(DISTINCT n), COLLECT(DISTINCT r) 

注意:如果你需要更好的性能,你可能要考虑使用的Neo4j Traversal API

+0

此查询不考虑组件是否具有来自供应商的“Isin”关系,它不回答我的需求:( – lug

+0

@lug“IsIn”如何影响结果?问题(如当前写入十)只关心一个未命名的关系中的“FROMBIKE”和“TOBIKE”。由于“IsIn”没有这些属性中的任何一个,所以这个查询应该很好地遍历它。 (基本上,如果该属性已定义,它只检查关系的一部分,否则默认为true) – Tezra

+0

好的。我明白。当我运行查询时,我只检索Bike节点和第一级组件。我需要将Bike + Components + Supplier + Components链接到供应商(如果存在),并且如果FROM和TO在搜索范围内...... – lug

3

这是一个简单的数据模型。除了Bike,ComponentSupplier节点标签之外,该型号还添加了一个Part节点标签。

(b:Bike)-[HAS_COMPONENT]->(c:Component)-[:IS_PART]->(p:Part) 
(c)-[:SUPPLIED_BY]->(s:Supplier) 

在该模型:

  • Part是由特定制造商生产的特定项目,并且它可以通过任何数量的Supplier s内出售。
  • A Bike由多个Component组成,其中每个是从特定Supplier购买的Part

在这种模式下,这里是一个简单的查询返回,特定的自行车,每个组成部分,它的供应商:

MATCH 
    (:Bike {id: 1})-[HAS_COMPONENT]->(c)-[:IS_PART]->(part), 
    (c)-[:SUPPLIED_BY]->(supplier) 
RETURN part, supplier; 
+0

谢谢你的例子。不幸的是,它并没有帮助我。自行车的“有效性”不是自行车的属性,而是关系。我无法更改数据模型;它被强加给我。 – lug

1

不知道如果我理解正确的,但将这项工作?

MATCH p=(b:Bike {bnumber = 6})-[hc:HAS_COMPONENT]-(c:Component)-[hs:HAS_SUPPLIER]-(s:Supplier) 
WHERE hs.frombike >= bnumber 
    AND hs.tobike <= bnumber 
RETURN p; 

我同意@cybersam,你可以做一个简化的模型。提出这个问题。

希望这会有所帮助。

问候, 汤姆

+0

我很惊讶这两个建议认为,自行车号码是自行车的属性,而不是关系的属性。我认为neo4j是解析产品结构和计算产品配置的正确数据库。也许neo4j不如我的强大。与neo4j没有办法? – lug

+0

所以,启发我们,你从哪里得到自行车号码?因为它没有在你的图表中找到的地方。那么假设它是什么标识一辆自行车(并因此是自行车的属性)是如此奇怪,并且来自自行车和自行车(一种关系的属性,而不是属性btw)表示这些相同数字的范围?所以请解释你如何走你的图来获得结果! –

+0

在图中,自行车可以由3个组件组成:ID = 1,2和3. 每个组件都由供应商引以为豪。 要知道哪个组件是由什么组成的,以及谁为每个自行车编号提供的,自行车编号的范围由FROMBIKE和TOBIKE给出:FROMBIKE = 1表示从自行车编号1和TOBIKE = 5表示编号为5的自行车。例如,自行车1只有组件1由供应商1提供。组件3仅用于自行车4(FROMBIKE = 4,TOBIKE = 20)。 问题是组件2.它的范围从3到5,但它与供应商1相关联。我必须考虑组件1的范围及其范围, – lug