我是论坛的新手,刚刚开始使用Neo4J。为我冗长的问题和背景信息道歉,但我认为这有助于解释我想要解决的问题。
我经常为公司从事商业智能和数据仓库项目。当我们创建商业智能需求时,我们通常需要创建一个我们感兴趣的业务指标列表(销售收入,利润率,总费用),并记录如何使用我们的底层系统的数据属性计算这些业务指标。 通常,我们以数据要求电子表格的形式记录excel中的大部分工作。我们创建一个业务指标列表,然后创建一堆列,其中包含描述,源数据属性,计算等。我正在尝试做的事情(作为个人方项目)是开发一个应用程序,我们可以用它来记录这种类型的而是元数据信息。我已经阅读了一些Neo4j书籍和在线文章,我认为Neo4j非常适合这个用例,现在我正在尝试记录基本数据模型以帮助我入门。
起初我想出了一些相当直接的东西,如左下图所示,从以下几点开始:
销售收入= Unit_Price * Count_Units_Sold
然而,我很快意识到计算本身对我来说非常重要,我可能稍后想要获取更多关于它的信息,例如添加不同版本的计算或添加注释以进一步描述它。我根据左上方的图像修改了模型,使“计算本身”成为一个单独的节点。
然而,当我开始研究更复杂的指标时,我仍然不确定如何最好地表示计算的细节。如果我采用以下示例,我将按如下方式对其进行建模。
Salary = Salary_Amount + Overtime_Amount - Tax Amount
现在这清楚地表示了计算中使用的数据属性(3或它们),但我不知道如何表示计算本身。例如。通过首先将Salary_Amount添加到Overtime_Amount然后减去Tax_Amount来定义计算。当我有更复杂的计算涉及除法和乘法时需要按特定顺序执行时,这将变得更加复杂。 基本上我希望能够从模型推断出计算如下:
Salary = Salary_Amount + Overtime_Amount - Tax Amount
相反:
Salary = Salary_Amount * Tax amount / Overtime Amount
或者:
薪资=税额*加班金额 - 薪金金额
我正在寻找一些定义计算节点的方法,我可以对数据属性的使用方式进行排序。可能我应该将计算存储为计算属性中的文本字符串,但我不禁认为这可能会让我感到痛苦,并限制我在多个时候从图中获取有用信息的能力数据属性用于不同的计算。
注意:我确实在论坛上看到了this question类似主题,但没有收到很多回复,所以尽管我的问题很相似,但我提供更多背景信息可能会带来更多的见解。
非常感谢, 迈克尔
我在回顾@ChristopheWillemsen和@ stdob--的答案后正在编辑这个问题。
首先感谢两位贡献者。答案和参考资料非常有用,都满足了我的要求。最初我按照@ stdob的答案倾向于使用反向波兰表示法 - 因为它提供了一种处理分组操作的简洁方法(例如我的数学公式中的括号)。但是,在尝试以两种方式对我的数据进行建模之后,我发现在第一篇文章中我没有涉及额外的要求,即捕获逻辑表达式,如“If,Where,Having”。基本上我希望能够捕获超出纯数学表达式的ETL类型转换规则,我认为@ChristopheWillemsen的解决方案将支持这一点。
以下是我使用这种方法建模基本公式的方法:
但是,我也有更复杂的逻辑,我想建模。这些是ETL类型规则,通常在定义数据仓库或BI项目的业务需求时将其捕获为伪代码或SQL形式。下面是一个示例,我将定义ETL如何计算保险公司的新索赔计数度量的逻辑。
这就是我对@ChristopheWillemsen在下面第一个答案中提供的解决方案进行建模的方法。
你能否看看这个,看看这是否是一种合适的模型。从需求的角度来看,我希望能够:
这看起来像是对此类信息进行建模的合适方法吗?欢迎任何建议或改进?
答案 0 :(得分:6)
这是一个非常有趣的用例,对我来说它接近我们称之为规则引擎。
我在neo4j博客上发布了一个关于它的用例:https://neo4j.com/blog/uncommon-use-cases-graph-databases/
当然,有多种方法可以达到你想要的效果,我会分享一种我想到的方式。
我会将计算视为Operations
的有序列表,其中不同的性质由其标签定义。例如,您将有一个Operation
节点具有附加标签Addition
,其下一个操作可以是带有标签Operation
的{{1}}节点。
一个简单的模型可以这样表示:
您的Substraction
节点将引用他们正在使用的传入值。
在更复杂的情况下,您希望表示可以在括号之间定义数学分组的操作组,同样可以像这样完成模型:
可能性几乎是无限的。
请注意,在计算机科学中,这种技术也称为规范模式:https://www.martinfowler.com/apsupp/spec.pdf
答案 1 :(得分:4)
第一个选项是在Reverse Polish Notation中编写表达式,并将其存储在有序树中:
Salary_Amount * Tax_Amount / Overtime_Amount
=>
Salary_Amount Tax_Amount * Overtime_Amount /
第二个想法是:将公式保留为文本形式,并以任何脚本语言发送参数的公式和值以运行。例如 - 在javascript eval
。
我还建议您阅读这篇文章:Spreadsheets Are Graphs Too
Upd。:如何使用密码和apoc-library计算公式的想法:
WITH "{Salary_Amount} * {Tax_Amount} / {Overtime_Amount}" as Formula
CALL apoc.cypher.run("return " + Formula + " as value", {
Salary_Amount: 1000,
Tax_Amount: 0.49,
Overtime_Amount: 100
}) yield value as result
RETURN result.value