【问题标题】:Modelling Metadata about a Mathematical Calculation in Neo4jNeo4j 中关于数学计算的元数据建模
【发布时间】:2017-02-03 10:53:29
【问题描述】:

我是论坛的新手,刚刚开始使用 Neo4J。为我冗长的问题和背景信息道歉,但我认为这有助于解释我试图理解的内容。

我经常为公司从事商业智能和数据仓库项目。当我们创建商业智能需求时,我们通常需要创建一个我们感兴趣的业务指标列表(例如销售收入、利润率、总费用),并记录如何使用来自我们底层系统的数据属性计算这些业务指标。 通常,我们以数据需求电子表格的形式在 excel 中记录大部分此类工作。我们创建了一个业务指标列表,然后是一堆带有描述、源数据属性、计算等的列。我想做的(作为个人项目)是开发一个应用程序,我们可以用它来记录这种类型的而是元数据信息。我已经阅读了一些 Neo4j 书籍和在线文章,我认为 Neo4j 非常适合这个用例,现在我正在尝试记录一个基本数据模型来帮助我入门。

起初我想出了一些相当简单的东西,如下图左图所示:

销售收入 = Unit_Price * Count_Units_Sold

但是,我很快意识到计算本身对我来说非常重要,并且我以后可能想要获取有关它的更多信息,例如添加不同版本的计算或添加注释以进一步描述它。我修改了模型,使“计算本身”成为一个单独的节点,如左上图所示。

但是,当我开始查看更复杂的指标时,我仍然不确定如何最好地表示计算的细节。如果我采用以下示例,我将对其建模如下。

薪水 = Salary_Amount + Overtime_Amount - 税额

现在这清楚地表示了计算中使用的数据属性(3 或它们),但我不知道如何表示计算本身。例如。定义通过首先将 Salary_Amount 添加到 Overtime_Amount 然后减去 Tax_Amount 来完成计算。当我有更复杂的计算涉及需要以特定顺序执行的除法和乘法时,这将变得更加复杂。 本质上我希望能够从模型中推断出计算如下:

薪水 = Salary_Amount + Overtime_Amount - 税额

相对于:

薪水 = Salary_Amount * 税额/加班费

或者:

工资=税额*加班费-工资额

我正在寻找某种方式来定义计算节点,借此我可以将排序应用于数据属性的使用方式。可能我应该将计算作为文本字符串存储在计算的属性中,但我不禁认为这可能会导致我在路上痛苦并限制我从图表中获取有用信息的能力。数据属性用于不同的计算。

注意:我确实在论坛上看到了类似主题的this question,但没有收到很多回复,所以即使我的问题相似,但提供更多背景信息可能会带来一些进一步的见解。

非常感谢, 迈克尔


在查看@ChristopheWillemsen 和@stdob-- 的答案后,我正在编辑这个问题。

首先非常感谢两位贡献者。答案和参考资料真的很有帮助,都涵盖了我的要求。最初,根据@stdob 的回答,我倾向于使用逆波兰表示法——因为它提供了一种处理分组运算的简洁方法(例如,我的数学公式中的括号)。然而,在尝试以两种方式对我的数据进行建模后,我发现我还有一些我在第一篇文章中没有涵盖的额外要求,即捕获逻辑表达式,例如“如果、在哪里、有”。基本上我希望能够捕获超出纯数学表达式的 ETL 类型转换规则,我认为@ChristopheWillemsen 的解决方案将支持这一点。

以下是我使用这种方法对基本公式进行建模的方式:

但是,我还想建模更复杂的逻辑。这些是 ETL 类型规则,在定义数据仓库或 BI 项目的业务需求时,通常会以伪代码或 SQL 的形式捕获。下面是一个示例,其中我定义了 ETL 如何计算保险公司的新索赔计数指标的逻辑。

这就是我如何根据@ChristopheWillemsen 在下面的第一个答案中提供的解决方案对这种扩展进行建模。

你能看看这个,看看这是否是一个合适的建模方法。从需求的角度来看,我希望能够:

  • 重构逻辑,以便我可以将其呈现给最终用户
  • 回答问题,例如哪些指标需要此属性。
  • 进行假设分析(例如,如果属性值发生变化,对使用该属性的指标有何影响。

这看起来像是对此类信息建模的合适方法吗?欢迎提出任何建议或改进?

【问题讨论】:

标签: neo4j graph-databases


【解决方案1】:

这是一个非常有趣的用例,对我来说它接近于我们所说的规则引擎。

我在 neo4j 博客上发布了一个关于它的用例:https://neo4j.com/blog/uncommon-use-cases-graph-databases/

当然,有多种方法可以实现您想要的,我将分享我想到的一种方法。

我会将计算视为Operations 的有序列表,它们的标签定义了不同的性质。例如,您将有一个带有附加标签 AdditionOperation 节点,其下一个操作可以是带有标签 SubstractionOperation 节点。

一个简单的模型可以这样表示:

然后,您的 Operation 节点将引用它们正在使用的传入值。

在更复杂的情况下,您希望表示可以在括号之间定义数学分组的操作组,同样可以这样完成模型:

可能性几乎是无限的。

请注意,在计算机科学中,这种技术也称为规范模式:https://www.martinfowler.com/apsupp/spec.pdf

【讨论】:

  • 非常感谢@ChristopheWillemsen 的解决方案。我以这种方式对我的数据进行了建模,但后来发现我有额外的要求来捕获更多关于计算的逻辑。我已经编辑了我的问题,以展示我建议如何扩展您的解决方案以涵盖此问题。你能看一下,看看你是否认为这是一个合适的方法?谢谢。
  • @n4nite 听起来不错。现在我在 neo4j 上为客户端构建了这样一个规则引擎,使用完整的密码解决方案绝对不是正确的方法,所以我们构建了一个处理“评估”类型的应用层规则引擎,这非常强大。此外,我在答案中采用了简单的方法,其缺点是规则对数据很严格,因此您可以在节点内添加解析器属性。你可以给我发邮件到 christophe@graphaware.com,我可以分享一个关于这种实现的小解释
【解决方案2】:

第一种选择是将表达式写入Reverse Polish Notation,并将其存储在有序树中:

Salary_Amount * Tax_Amount / Overtime_Amount
=>
Salary_Amount Tax_Amount * Overtime_Amount /


想到的第二个选项:将公式保留为文本形式,并以任何脚本语言发送公式和参数值以运行。例如 - 在 javascript eval.


我也推荐阅读这篇文章:Spreadsheets Are Graphs Too


更新:如何使用密码和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

【讨论】:

  • 用@stob-- 玩逆波兰表示法看起来很有趣,谢谢分享。
  • 非常感谢您花时间回答。使用逆波兰表示法是一种处理分组操作的独特方法,我永远不会想到。我在上面编辑了我的问题以包括一些额外的要求。我认为这些额外的要求意味着上面的第一个提案可能更合适。如果您有时间阅读我上面更新的问题,我很想知道您的想法?
猜你喜欢
  • 1970-01-01
  • 2018-03-08
  • 2017-09-18
  • 1970-01-01
  • 1970-01-01
  • 2012-10-10
  • 1970-01-01
  • 2014-06-06
  • 1970-01-01
相关资源
最近更新 更多