特定于领域的语言

我们今天要谈论的是JCypher:它从哪里来,今天是什么,以及我们将来要去哪里:

大约两年前,我第一次接触到Neo4j图形数据库和Cypher图形查询语言。 我很快就被吸引住了,想开始使用它,所以我决定写一个本地的Java DSL一种针对Cypher的特定领域的语言。

特定于领域的语言

这个深散射层基本上是一个流畅的爪哇岛应用编程接口,它允许连接方法调用,以便在尽可能避免方法嵌套的同时形成语言表达式。 我们试图确保方法调用只有一个参数,以确保深散射层读写直观,最重要的是,最大限度地利用现代爪哇岛标识提供的完成方案。

在后台,这个深散射层创建了密码表达式。 我还引入了一个数据库抽象层,这样我们就可以以统一的方式对一个图形数据库执行这些表达式—不管数据库是远程的、嵌入式的还是在内存中的。

下一个问题是,这样的查询应该返回什么样的爪哇岛结果? 这个决定是建立一个由节点、关系、标签、类型和属性组成的通用图形数据模型。 因为模型非常简单,所以很容易阅读、导航和修改。 您可以获取一个修改过的模型—甚至是一个空模型—并通过简单地调用模型上的存储,以一种直接的方式将其存储回数据库。 您不必为实际更新编写查询表达式,因为这是在后台完成的。

在我们模型的这一点上,我们可以在不同的抽象层次上访问图形数据库:在较低的层次上使用查询DSL,在稍高的层次上使用通用图形模型。

下一个自然出现的问题是:有更多有意义的抽象层数据库异构同步 次吗? 答案是肯定的。

下一个抽象层次,我们称之为域映射,是获取一个任意复杂的爪哇岛对象图PoJos——普通的旧爪哇岛对象,或者我们称之为域对象—并将其存储到图形数据库中,以便以后检索。 您不必修改您的对象或它们的类,添加注释或编写一行映射代码或配置,因为JCypher提供了默认映射。

在相同的抽象层次上,您需要能够查询您的域对象图,JCypher通过提供另一个名为域查询语言的Java数字用户线路做到了这一点。 使用领域查询语言,您可以基于您的领域模型的概念而不是底层图模型的概念来制定查询。

JCypher还提供了一些非功能性的特性,例如事务和并发支持,这为多个客户端提供了访问单个数据库的能力,以及从一个客户端进行多线程访问的能力。

考虑以下数据模型:

特定于领域的语言

在本例中,公司和人员是主体,它们通过联系点与联系点相关联,联系点可以是电子地址或邮政地址。 接触点可以在某些区域,例如城市,它可以是其他区域的一部分:州、国家、大陆等。 这是一个简单但有用的模型。

现在让我们来看看一些爪哇岛代码:

特定于领域的语言

首先,我们实例化一些域对象并填充这个方法后面的图,它返回一个作为域对象图的根对象的列表。

接下来,为了访问图形数据库,我们通过工厂实例化一个对象。 我们将数据库连接指定为远程,并添加了一些属性,最重要的是我们拥有Neo4j服务器的网址。 因为我们正在使用域模型和域,所以我们也需要域访问—这也是我们通过工厂的方式创建的。

在数据库中,一个业务域必须有一个唯一的名称,在我们的例子中,这个名称是。 现在有了域访问权限,我们只需给定域对象就可以调用商店,并且”输入域对象的图形”会存储到数据库中。

为了制定和执行域查询,我们从域访问创建一个查询对象:

特定于领域的语言

接下来,我们创建一个或多个域对象匹配,它在域查询中起着核心作用,因为它服务于特定类型的地图域对象。 在我们的例子中,我们匹配类型的对象。

接下来,我们使用子句指定一些域对象匹配的约束。 我们指定此人姓”史密斯“,名”约翰” .”连续条款默认结束。 如果您想要包含”或“,您需要插入一个子句以及括号来任意嵌套这些表达式。

通过这个查询,我们试图确定还有谁住在约翰 史密斯的地址,这是通过使用一个图遍历子句来实现的。 我们开始通过接触点从约翰 史密斯向前遍历—这将我们带到约翰 史密斯的地址—然后继续通过接触点向后遍历类型的对象。 那样的话,我们就得在约翰 史密斯的地址再找一个。 就这么简单!

接下来,我们需要执行查询,我们可以检索查询中指定的每个域对象匹配的实际结果。 在我们的案例中,我们检索了一份住在约翰 史密斯地址的人的名单。 然后我们输入对我们的领域模型的查询。

在下一个查询中,我们想知道住在约翰 史密斯地址的人,他们中有多少人住在欧洲? 在下一个查询中,我们只需要为对象键入一个”区域”和名称”欧洲”:

特定于领域的语言

在这个查询的下一步,我们收集史密斯所有地址的所有区域,这也是通过一个图遍历子句来完成的。 因此,我们开始从史密斯通过接触点向前穿越,这将我们带到史密斯的地址。

然后我们继续向前通过区域,这将我们带到地址的直接区域,然后我们递归地收集所有通过”属性的一部分”可到达的区域。”这导致了另一个。

现在我们已经收集了史密斯所有地址的所有区域。 为了完成查询,我们使用了一个子句来选择所有史密斯的收集区域包含欧洲。 接下来,我们执行查询并检索实际结果,这是一个姓氏为史密斯、在欧洲有地址的人的列表。

您可以使用域查询做更多有趣和强大的事情,这些都在项目文档和不同的示例项目中进行了描述。 对于所有这些域查询,您不必担心优化数据库结构或映射来提高查询性能。

此外,因为领域对象的图形由图形数据库支持,所以导航数据库非常便宜。 与关系数据库相反,您需要几乎在每个查询的基础上优化数据库结构,尤其是在导航高度连接的数据时。

定期添加新的JCypher特性。 例如,在下一个版本中,您将能够存储域查询供以后使用,即使您不能访问最初创建它的爪哇岛代码。

另一个新特性叫做服务器,它是JCypher的服务器端实现,提供了一个安静的应用编程接口和一个网络用户界面。 这将允许用户试验领域模型和领域查询。 它还处于非常早期的阶段,但在接下来的几个月里,它将在功能上有所增长。