密码:嵌套的FOREACH构建一个"实数树"。问题是使更深的循环有条件,因此较小的数字具有更高的精度



我正在尝试构建一棵介于 0 和 6000 之间的实数树,树的精度变化如下:从 0-100 树深度将继续到小数点后 3 位,即 0 到 99.999,从 100 到 500 将是 2 位小数,500 到 1000 只有 1 位小数,从那里到 6000, 没有小数。 这个想法是,然后我可以用这棵树来表示毫米,升,公斤 - 任何需要实数来定义它的属性。然后我可以将属性单位描述为与实数节点关系中的属性,而不是为 mm、kg 等提供单独的节点集(或者更糟糕的是:长度、宽度、高度 - 所有数千个节点(

我的问题是我无法使条件 FOREACH 循环工作。 生成低至单元级别的节点是一种享受。我在编码方面根本没有经验,我可能错过了一些简单的东西,但我尝试了很多方法,包括首先生成单位精度节点,然后尝试稍后添加更高精度的节点,以及尝试一次性完成所有操作,这似乎更整洁。

MERGE (hub:RealNumber {name:'Real Numbers', mag: 'hub'})
MERGE (zero:RealNumber {name: 0.000, mag: ['eplus3', 'eplus2','eplus1', 'eplus0', 'eminus1', 'eminus2', 'eminus3']})
WITH hub, range(1000,6000,1000) AS thousands, range(100,900,100) AS hundreds,range(10,90,10) AS tens, range(1,9,1) AS units,
range(1,9,1) AS tenths
FOREACH (thousand IN thousands|
FOREACH (hundred IN hundreds |
FOREACH (ten IN tens |
FOREACH (unit IN units |
//FOREACH (tenth in tenths |
MERGE (a1:RealNumber {thousand:thousand, name:toFloat(thousand), mag: 'eplus3'})<-[:TENTHS]-(hub) // creates thousand nodes and connects to hub
MERGE (b1:RealNumber {hundred:hundred, name:toFloat(hundred+a1.name), mag: 'eplus2)'})<-[:TENTHS]-(a1) // creates hunded nodes chid to thousands
MERGE (b2:RealNumber {hundred:hundred, name:toFloat(hundred), mag: 'eplus2'})<-[:TENTHS]-(hub) //creates hundred nodes child to hub
MERGE (c1:RealNumber {ten:ten, name:toFloat(ten+a1.name), mag: 'eplus1'})<-[:TENTHS]-(a1) //creates ten nodes child to thousand >hundreds
MERGE (c2:RealNumber {ten:ten, name:toFloat(ten+b1.name), mag: 'eplus1'})<-[:TENTHS]-(b1)//creates ten nodes child to hundreds
MERGE (c3:RealNumber {ten:ten, name:toFloat(ten+b2.name), mag: 'eplus1'})<-[:TENTHS]-(b2)
MERGE (c4:RealNumber {ten:ten, name:toFloat(ten), mag: 'eplus1'})-[:TENTHS]-(hub) //creates ten nodes child to hub 
MERGE (d1:RealNumber {unit:unit, name:toFloat(unit+a1.name), mag: 'eplus0'})<-[:TENTHS]-(a1)
MERGE (d2:RealNumber {unit:unit, name:toFloat(unit+b1.name), mag: 'eplus0'})<-[:TENTHS]-(b1)
MERGE (d3:RealNumber {unit:unit, name:toFloat(unit+b2.name), mag: 'eplus0'})<-[:TENTHS]-(b2)
MERGE (d4:RealNumber {unit:unit, name:toFloat(unit+c1.name), mag: 'eplus0'})<-[:TENTHS]-(c1)
MERGE (d5:RealNumber {unit:unit, name:toFloat(unit+c2.name), mag: 'eplus0'})<-[:TENTHS]-(c2)
MERGE (d6:RealNumber {unit:unit, name:toFloat(unit+c3.name), mag: 'eplus0'})<-[:TENTHS]-(c3)
MERGE (d7:RealNumber {unit:unit, name:toFloat(unit+c4.name), mag: 'eplus0'})<-[:TENTHS]-(c4)
MERGE (d8:RealNumber {unit:unit, name:toFloat(unit), mag: 'eplus0'})<-[:TENTHS]-(hub)   
FOREACH (tenth IN tenths IN CASE WHEN a1.thousand<1001 THEN [1] ELSE [] END |
MERGE (e1:RealNumber {tenth:tenth, name:toFloat(tenth)*0.1+a1.name, mag: 'eminus1'})<-[:TENTHS]-(a1) //WHERE e1.name<500
MERGE (e2:RealNumber {tenth:tenth, name:toFloat(tenth)*0.1+b1.name, mag: 'eminus1'})<-[:TENTHS]-(b1)
MERGE (e3:RealNumber {tenth:tenth, name:toFloat(tenth)*0.1+b2.name, mag: 'eminus1'})<-[:TENTHS]-(b2)
MERGE (e4:RealNumber {tenth:tenth, name:toFloat(tenth)*0.1+c1.name, mag: 'eminus1'})<-[:TENTHS]-(c1)
MERGE (e5:RealNumber {tenth:tenth, name:toFloat(tenth)*0.1+c2.name, mag: 'eminus1'})<-[:TENTHS]-(c2)
MERGE (e6:RealNumber {tenth:tenth, name:toFloat(tenth)*0.1+c3.name, mag: 'eminus1'})<-[:TENTHS]-(c3)
MERGE (e7:RealNumber {tenth:tenth, name:toFloat(tenth)*0.1+c4.name, mag: 'eminus1'})<-[:TENTHS]-(c4)
MERGE (e8:RealNumber {tenth:tenth, name:toFloat(tenth)*0.1, mag: 'eminus1'})<-[:TENTHS]-(hub)   
)))))

在一个相关的主题上 - 如果我沿着"NEXT_THOUSAND"、"NEXT_HUNDRED"行链接节点,或者只是简单地将它们全部排序并在批次中使用"NEXT",是否会提高效率?

非常感谢!

可以使用索引快速查找具有一定范围内属性值的节点。不应为一组有限的值创建节点。

使用您评论中提到的引擎示例,假设数据模型如下(每个属性的单位由您固定,不需要存储(:

(:Engine {id: 123, bore: 85.75, stroke: 80, powerDensity: 77.789})

:Engine(bore):Engine(stroke):Engine(powerDensity)上创建索引后,可以有效地执行涉及任何索引属性(或所有索引属性(的查询。

例如:

PROFILE MATCH (e:Engine)
WHERE (80 <= e.bore <= 95.2) AND e.stroke < 85 and e.powerDensity > 75
RETURN e

当在同一MATCH中使用多个索引属性时,只能使用其中一个索引(但密码规划器将尝试选择最有可能获得最快结果的索引(。

最新更新