GraphGists

“自描述”的 Neo4j 图数据库(第二部分)

# SmartData 元模型子图在 FactMiners 社交游戏生态系统中的应用 - 第 2 部分

作者:Jim Salmons,项目总监 - The Softalk Apple Project 和 FactMiners 生态系统

注意:我的原始元模型子图 GraphGists 的第二部分深入探讨了与图数据库设计问题相关的某些“细枝末节”,这些问题可能超出了您的兴趣范围。有关这些材料的更多面向读者和视频观众的版本,请参阅我在博物馆计算机网络 #MCN2014 大会上发表的演讲的 GraphGist 版本:事实的归宿:探索 FactMiners 事实云的元模型子图

关于 The Softalk Apple Project 和 FactMiners 生态系统

在本 GraphGist 的第一部分中,我描述了元模型子图设计模式的基础知识,并研究了一个非常基本的示例。有了这些,我们现在开始着手解决最初激发我开发 FactMiners 生态系统的有趣用例。

Softalk 杂志于 1980 年 9 月至 1984 年 8 月期间每月出版四卷。其 9,300 页提供了早期微型计算机革命的宝贵详细编年史。虽然 FactMiners 社交游戏生态系统旨在拥有自己的生命和影响力,但 FactMiners 的灵感以及要开发的第一个事实云将是本系列和未来 GraphGists 中描述的那个。我和许多Softalk 之友邀请您详细了解这份伟大的杂志以及The Softalk Apple Project。您还可以通过此链接了解更多关于我个人“传递爱心”的灵感,将 FactMiners 生态系统带入现实。

底线。创建 Softalk 杂志的权威在线数字档案是一个好主意。而且以“孕育”FactMiners 社交游戏生态系统的方式探索这个档案将既充满乐趣又充满有趣的挑战。所以让我们直接跳入…​

用例:FactMiners 事实云向导

FactMiners 背后的基本理念是利用玩家的精力和对游戏的兴趣,为博物馆和档案馆创建众包资源,这些博物馆和档案馆拥有在线数字收藏,他们希望创建一个事实云(即“自描述”的图数据库)作为其在线收藏的补充教育和研究资源。

在 FactMiners 的基于角色的玩家世界中,博物馆和档案馆的代表(通常是雇员或其他授权代理)只是 FactMiners 玩家,他们在 http://www.FactMiners.com 玩家社区的玩家帐户上启用了“事实云所有者/创建者”权限。当博物馆或档案馆准备在其收藏中添加事实云时,收藏的玩家将使用游戏应用程序或浏览器启动事实云向导。

与您以前使用过的类似向导风格的设置功能一样,事实云向导是一个基于知识的程序交互(即从 UI 设计的角度来说,是一种引导的“对话”),它通过将复杂的任务分解为更简单的决策和逐步配置活动来帮助向导用户创建复杂的东西。

我们在这个 GraphGist 系列的第二部分中看到的 Cypher 代码片段以“概念块”的形式呈现,这些代码片段将根据向导提出的增量引导式问题以片段方式生成和执行。因此,我不会在此处赘述向导交互的细微细节。我们只需认识到,我们在本 GraphGist 系列的第二部分中创建的元模型可以合理地由即将推出的事实云向导生成,该向导将成为FactMiners.org 开源开发人员社区开发的平台的一部分。(目前只是一个占位符页面…​有兴趣吗?这是这个摘要之后“待办”的下一项!:-) )

Softalk 杂志 FactMiners 元模型

83cc0630 2cfb 4a0c a4b9 4756f8cf0722 IkTgBl2EJ

本 GraphGist 系列的第 1 部分中,我介绍了一个简单的元模型子图,它看起来像第一个图。META 子图只需要节点关系子集来概念性地组织介绍性示例的元素。

我们的第一步是将 Softalk 杂志的结构粗略地纳入到我们的事实云元模型中。您将看到我们如何扩展节点标记技术的应用来处理现实世界中特定于域的示例的复杂性。

为了将 Softalk 杂志的结构包含在我们的事实云元模型中,我采用了标签命名约定,为我们的元模型组织提供子集包含语义。元模型子图中的每个节点都有两个标签

  • META - 由于元模型中的每个节点都具有 META 标签,因此我们可以快速专注于元模型数据,或者完全忽略自描述数据库中的元模型数据。

  • CamelCasedPathSubsetLabel - 此标签命名约定在概念上表示嵌套子集语义,该语义具有重要的元模型访问、解释和组织意图。

注意:当前的 Neo4j 实现将节点上的多个标签视为一组独立的集合成员“标记”。我可以同样轻松地使用多个标准 Neo4j 标签,并将这些标签以“包含概念”顺序编写。CamelCase 方法更安全,可以避免意外问题,同时还允许我探索在 Cypher 标签匹配子句中使用正则表达式,从而获得路径包含语义中的大部分功能,而无需等待它添加到 Neo4j 功能集中。在版本 0.1 中,使用了 `反引号.点.路径.字符串\` 语义。在这个版本 0.2 中,我采用了 CamelCase 约定,以便 https://structr.com 的出色代码大师 Axel 和 Christian 可以使用 structr 的强大功能,帮助使 FactMiners 事实云向导和 FactMiners.org 网站尽快实现!我们在可读性方面做出了一些牺牲,我们在实现的强大功能方面获得了回报。这是一个非常好的交易。:-) 也许此约定最不幸的影响是需要调用 PropertyMaps Propertymaps。这是一个正在进行的工作。

Softalk 事实云元模型中的节点至少具有两个“原生”属性

  • type - 元模型中具有 type 属性为“PERSON”的节点(:META:Nodes {type: "PERSON"}),意味着数据库中将有一个具有“PERSON”标签(:PERSON)的节点子集

  • name - 从技术上讲是可选的。此属性用作方便的可读显示名称。

我所说的“原生”属性是指在节点上显式输入的属性。正如您将在本摘要的后面部分看到,我们将使用“分而治之”策略来处理节点和关系属性,这些属性可以作为属性映射自动关联(通过节点类型匹配),也可以通过附加关联语义手动关联。

描述基本杂志结构

Softalk 杂志的 48 期提供了微型计算机革命早期详细的时间胶囊快照;从 1980 年 9 月到 1984 年 8 月。这 48 期被分成四个年度卷,构成了杂志的完整出版运行。每期都包含多个页面。

f273b65a c335 42e0 9a1c 0297f3389bf9 0UrdBI BJ

以下是关于杂志经典结构的快速回顾(其中一些是 Softalk 特定的例子,说明了在典型杂志的前后部分找到的非特色元素)

  • 书的前部

    • 封面

    • 刊头

    • 目录

    • 编辑信

    • 等等

  • 特色“井”

    • 特色

  • 书的后面

    • 专栏

    • 操作指南

    • 畅销书榜单

    • 封底

我们首先创建描述基本杂志结构的元模型元素。

对于我们的 Softalk 杂志事实云,我们的档案库播放器使用事实云向导来响应一系列关于数字集合的基本单元和组成的问题,这些问题需要进行事实挖掘。

CREATE
	(magazine:META:SourceStructureNodes {type: "MAGAZINE", name: "Magazine"}),
	(volume:META:SourceStructureNodes {type: "VOLUME", name: "Volume"}),
	(issue:META:SourceStructureNodes {type: "ISSUE", name: "Issue"}),
	(page:META:SourceStructureNodes {type: "PAGE", name: "Page"})
// And hook them up to reflect their part-subpart relationship...
CREATE volume - [:FROM_NODE] ->
		(:META:SourceStructureRelationships {type: "PART_OF", name: "Part of"})
		- [:TO_NODE] -> magazine
CREATE issue - [:FROM_NODE] ->
		(:META:SourceStructureRelationships {type: "PART_OF", name: "Part of"})
		- [:TO_NODE] -> volume
CREATE page - [:FROM_NODE] ->
		(:META:SourceStructureRelationships {type: "PART_OF", name: "Part of"})
		- [:TO_NODE] -> issue

在上面的 Cypher 查询中,我们的播放器使用事实云向导来描述源材料结构的分解,从而导致向导生成特定于元模型中元素的**SourceStructure**子集的结构节点和PART_OF关系节点。当然,没有任何播放器——即使是创建和维护事实云元模型的播放器——需要了解元模型、它们的解释或任何东西。是向导编写了我们在这里探索的代码。

根据您的浏览器或设备呈现这些新节点的图形可视化的方式,可能无法明显地看到向导创建了一条蛇形路径,这条路径交替排列着结构元素节点和PART_OF关系节点,这些节点模拟了实际数据库中的PART_OF关系。如果向导在配置交互的后期发现PART_OF关系在上下文中是复杂的,那么关于该关系的_元模型节点将作为元模型中子图的“根”,该子图将描述非元数据库中的该关系。

在与事实云向导进行类似于 ELIZA 的对话中,我们的事实云创建者播放器继续深入研究要进行事实挖掘的集合项的结构。我们的播放器接下来告诉向导关于所有可能出现在任何给定页面的各种杂志结构元素的信息——从事实挖掘的角度来看,杂志是一种复杂的文档结构。以下是向导为了进一步描述事实云元模型中的 Softalk 杂志存档而添加的几个最明显的“页面部分”。

CREATE
	(fcov:META:SourceStructureNodes {type: "FCOV", name: "Front cover"}),
	(ifcov:META:SourceStructureNodes {type: "IFCOV", name: "Inside front cover"}),
	(bcov:META:SourceStructureNodes {type: "BCOV", name: "Back cover"}),
	(ibcov:META:SourceStructureNodes {type: "IBCOV", name: "Inside back cover"}),
	(masthead:META:SourceStructureNodes {type: "MASTHEAD", name: "Masthead"}),
	(toc:META:SourceStructureNodes {type: "TOC", name: "Table of Contents"}),
	(loa:META:SourceStructureNodes {type: "LOA", name: "List of Advertisers"}),
	(column:META:SourceStructureNodes {type: "COLUMN", name: "Column"}),
	(feature:META:SourceStructureNodes {type: "FEATURE", name: "Feature"}),
	(review:META:SourceStructureNodes {type: "REVIEW", name: "Review"}),
	(top30:META:SourceStructureNodes {type: "TOP30", name: "Top 30 List"}),
	(top10biz:META:SourceStructureNodes {type: "TOP10BIZ", name: "Top 10 Business List"}),
	(top10gam:META:SourceStructureNodes {type: "TOP10GAM", name: "Top 10 Games List"}),
	(ad:META:SourceStructureNodes {type: "AD", name: "Advertisement"})
WITH [fcov, ifcov, bcov, ibcov, masthead, toc, loa, column, feature, review, top30, top10biz, top10gam, ad] as pg_parts
MATCH (page:META:SourceStructureNodes)
WHERE page.type = "PAGE"
FOREACH (pg_part IN pg_parts |
	CREATE pg_part - [:FROM_NODE] ->
		(r:META:SourceStructureRelationships {type: "PART_OF", name: "Part of"})
		- [:TO_NODE] -> page)
1180a03e 456e 422e a036 876898b6207c XeQPgauO1

GraphGist“弹跳球”图形可视化的相当活跃且不可预测的渲染行为可能会使这个新出现的杂志源集合结构难以看到。但是,如果您伸手进去,必要时拉动节点,您将看到一种我称为“精子”的图形形式,其中“尾巴”是将杂志分解到页面周围的页面部分(精子“头部”)的PART_OF路径元模型节点。

在下一节中,我们的播放器将使用向导将这个精子变成哑铃。

描述基本杂志内容

在最基本的层面上,Softalk 内容是关于人物、产品、公司、技术、地点和事件的——以及其他许多东西。但我们将使这个 GraphGist 专注于我们在这个 GraphGist 系列的第三部分中使用的“事实发现和输入”游戏用例场景所需的必要内容。

以下 Cypher 查询创建代表 Softalk 杂志中发现的五种类型的编辑内容的元模型节点。

CREATE
	(person:META:SourceContentNodes {type: "PERSON", name: "Person"}),
	(company:META:SourceContentNodes {type: "COMPANY", name: "Company"}),
	(product:META:SourceContentNodes {type: "PRODUCT", name: "Product"}),
	(location:META:SourceContentNodes {type: "LOCATION", name: "Location"}),
	(event:META:SourceContentNodes {type: "EVENT", name: "Event"})
WITH [person, company, product, location, event] as content_elements
MATCH (magazine:META:SourceStructureNodes)
WHERE magazine.type = "MAGAZINE"
FOREACH (content_element IN content_elements |
	CREATE magazine - [:FROM_NODE] ->
		(r:META:SourceContentRelationships {type: "IS_ABOUT", name: "is about"})
		- [:TO_NODE] -> content_element)

这些内容元素用作事实挖掘器事实云“事实”中的“事物”节点“相关”,事实——在其最简单的形式——是图形数据库的基本语义表达,即,(事物_A) - :IS_RELATED →(事物_B)。

随着我们为 Softalk 杂志事实云发展元模型,您可以开始看到这些内容元素与杂志结构的特定细粒度元素相关的某些结构化方式。例如,在这个 GraphGist 的第三部分中,我们将逐步介绍一个关于输入在著名的 Softalk 前 30 名畅销书榜单中找到的信息的“事实发现和输入”游戏场景。在我们快速了解了元模型如何处理节点和关系属性之后,我们通过完成畅销书榜单文档结构的元模型覆盖来结束本系列的这一部分。

对属性的第一次尝试

属性元建模在事实挖掘器设计中将很重要。这很可能是我们想要保存“提示包”运行时信息的地方,以便元模型感知的瘦客户端应用程序——例如,事实挖掘器社交游戏应用程序——可以获取细粒度的有用信息来执行符合数据访问、编辑和可视化任务。

虽然我可以想到一些不同的方式来元建模属性,但有两个考虑因素导致了我最初的方法。

  • 在事实云向导中创建和编辑属性的复杂程度足以使向导的这方面很可能成为向导框架中的一个单独的完整功能组件。该组件可以创建和维护其 Propertymaps 并将它们放置在方便的位置,以便由代表可能具有属性的非元节点和关系的元模型元素找到和使用。

  • Cypher 具有强大的参数化属性映射语义,这在编写 Property-Builder 时非常有用。

了解这些要点,并且为了避免随着越来越多的元模型元素具有越来越多的互连而出现爆炸性的视觉复杂性,我已经采用了以下机制来在 Softalk 事实云元模型中提供基本属性建模。

  • 任何具有“类型”属性的元模型节点或关系都可以有一个可选的关联 Propertymap 来描述由该元模型元素建模的元素实例的属性。

  • Propertymap 将具有与其关联的节点或关系相同的“类型”。(注意:我还在考虑在 Propertymap 元素上的类型属性的集合,作为处理不同类型元素之间共享属性集的一种方式;例如,Softalk 杂志中页面元素的许多页面部分的共享属性。)

  • 所有 Propertymaps 与它们各自的**Source…​Propertymaps**子集中“根”节点具有“IS_A”关系。这是 Property-Builder 将“挂起”其生成输出以方便访问和维护的地方。

对属性存储的预期使用,用于为动态配置编辑和可视化任务的“小部件级提示”,足以假设元建模属性的整个领域将成为其自身的有趣且具有挑战性的领域。假设“关注点分离”以帮助简化我们的事实云向导开发需求也是合理的。因此,以这种方式处理 Propertymaps 在我们开发事实云向导的 Property-Builder 组件时可能会在长期内有用。

以下是元建模 Propertymaps 如何工作以向 PERSON 和 COMPANY **SourceContentNodes** 提供一些基本属性的示例。我们首先在元模型的**SourceContentPropertymaps**子集中创建“根”节点。然后,我们为需要对 Neo4j 数据库中的数据属性进行建模的任何类型的**SourceContentNodes** 元素创建并链接 Propertymap 节点。最后,我们创建示例属性节点并将它们组织在**SourceContentNodesPropertymaps** 子集中(因为这是事实云向导的 Property-Builder 的“工作区”)。

// Create a root node where the Fact Cloud Property-Builder of the Wizard will hang its generated contributions
// to be picked up by a type-matching naming convention.
CREATE (propertyMapRoot:META:SourceContentPropertymaps {name: "Content Propertymaps"} )
// Again applying the type-->label mapping idea, (:PERSON) nodes in the non-meta data will have a set of properties described by the subgraph anchored in the metamodel at (:META:SourceContentPropertymaps {type: "PERSON"}). Same for (:COMPANY) nodes.
CREATE propertyMapRoot - [:IS_A] -> (personPropertymap:META:SourceContentPropertymaps {type: "PERSON", name: "Person properties"} )
CREATE propertyMapRoot - [:IS_A] -> (companyPropertymap:META:SourceContentPropertymaps {type: "COMPANY", name: "Company properties"} )
CREATE
	personPropertymap - [:HAS_PROPERTY] -> (:META:SourceContentNodeProperties {property: "name", name: "Full name", valueType: "text"}),
	personPropertymap - [:HAS_PROPERTY] -> (:META:SourceContentNodeProperties {property: "age", name: "Age", valueType: "number"}),
	personPropertymap - [:HAS_PROPERTY] -> (phoneNum:META:SourceContentNodeProperties {property: "phone", name: "Phone", valueType: "phoneNumber"}),
	companyPropertymap - [:HAS_PROPERTY] -> (:META:SourceContentNodeProperties {property: "name", name: "Name", valueType: "text"}),
	companyPropertymap - [:HAS_PROPERTY] -> phoneNum

CREATE (propertyMapRoot2:META:SourceStructureNodePropertymaps {name: "Structure Node Propertymaps"} )
CREATE propertyMapRoot2 - [:IS_A] -> (pgPartCommonProperties:META:SourceStructureNodePropertymaps {name: "Page part common properties"})
// If the type property of a Propertymap is a collection, it contains the type values to which the shared map applies.
// NOTE: The wizard will likely generate individual Propertymap nodes pointing to shared/reusable Property nodes. I just
// did not want to bulk this gist with too much code or too many elements drawn in the graph visualizations.
SET pgPartCommonProperties.type = ["FCOV", "IFCOV", "BCOV", "IBCOV", "MASTHEAD", "TOC", "LOA", "COLUMN", "FEATURE", "REVIEW", "TOP30", "TOP10BIZ", "TOP10GAM", "AD"]
CREATE
	pgPartCommonProperties - [:FROM_NODE] ->
		(:META:MetaRelationships {type: "HAS_PROPERTY", name: "Has property"})
		- [:TO_NODE] -> (:META:SourceStructureNodeProperties {property: "origin", name: "Origin (x,y)", valueType: "point"}),
	pgPartCommonProperties - [:FROM_NODE] ->
		(:META:MetaRelationships {type: "HAS_PROPERTY", name: "Has property"})
		- [:TO_NODE] -> (:META:SourceStructureNodeProperties {property: "extent", name: "Extent (w,h)", valueType: "point"}),
	pgPartCommonProperties - [:FROM_NODE] ->
		(:META:MetaRelationships {type: "HAS_PROPERTY", name: "Has property"})
		- [:TO_NODE] -> (:META:SourceStructureNodeProperties {property: "raw_text", name: "Raw text", valueType: "string"}),
	pgPartCommonProperties - [:FROM_NODE] ->
		(:META:MetaRelationships {type: "HAS_PROPERTY", name: "Has property"})
		- [:TO_NODE] -> (:META:SourceStructureNodeProperties {property: "raw_image", name: "Raw image", valueType: "sourcecollection:url"})

为了支持这个 GraphGist 系列第三部分中用例场景的游戏交互,我需要介绍的关于属性的内容大约就是这些。

不幸的是,我们也开始进入这样一个阶段,即对 GraphGist 图形可视化的控制变得难以控制。您开始看到 Propertymap 集群的“岛屿”,因为元模型元素需要描述非元数据中节点和关系的属性。但是,和以前一样,如果您“伸手进去,拉动周围的东西”,您可以很好地了解我们的 Softalk 事实云元模型正在进行。

当然,在事实云向导的受控用户环境中,良好的 UI 设计将使元模型的创建、维护和扩展——如果不是有趣的话,至少是井井有条和可行的。与此同时,抓住一个节点并将其拉来拉去还是有点乐趣的。

添加一个结构性子部分

到目前为止,我们已经将杂志的页面分割成(目前是矩形的)区域,这些区域映射到文档结构元素,例如刊头、广告商列表、专栏、特色、评论、畅销书榜单、广告等。这些页面部分区域也可能具有结构。Softalk 杂志中这种子部分结构元素的一个非常数据丰富的例子是其各种畅销书榜单。每个月都会有一个前 30 名榜单,无论类别如何,都会对苹果电脑软件的受欢迎程度进行评级。前 10 名榜单对商业应用、游戏和教育软件等进行了评级,随着行业和消费者市场的演变。这些榜单由 Softalk 严格且独立地研究和报告,因此,是 Softalk 杂志存档页面中锁定的一些有趣且具有历史价值的数据。

每个畅销书榜单都有其规定的榜单项条目数量。这些畅销书榜单项节点成为模拟杂志结构的元素的“PART_OF”路径中的一个新叶子。我已经在这里模拟了三个示例榜单。由于它们都具有相同的行项目结构,因此这三个页面部分都是新添加的PART_OF关系的端节点,这些关系将畅销书榜单项链接到杂志结构中。

CREATE (topXlist_item:META:SourceStructureNodes {type: "TOPX_LIST_ITEM", name: "A Bestseller List Line Item"})
WITH topXlist_item
MATCH (topXlist:META:SourceStructureNodes)
WHERE topXlist.type IN ["TOP30", "TOP10BIZ", "TOP10GAM"]
CREATE topXlist_item - [:FROM_NODE] ->
		(:META:SourceStructureRelationships {type: "PART_OF", name: "Part of"})
		- [:TO_NODE] -> topXlist
5b7948ed 5792 4c7d af6b e4824d0a0242  8efAWk0t

当我们检查畅销书榜单行项列表时,我们可以开始了解 Softalk 事实云中“事实”的“结构”(或“编织”)如何捕获与杂志结构“关联”的信息(即,在上下文中具有意义)杂志——榜单项在畅销书榜单中的序数位置,以及榜单研究人员计算的每月统计索引——以及将榜单与杂志在其编辑内容中涵盖的现实世界中的“领域对象”相关联的信息——人物是(软件)产品的开发者,公司是(软件)产品的发布者。由于我们正在逐步探索这个元模型,因此我们可以将此内容/结构映射添加到元模型中。

正如“充满事实”的拼贴图像特写所示,畅销书榜单项具有(序数)位置和(每月评级)索引属性。由于我们的向导尚未在 *SourceStructureRelationshipsPropertymaps* 子集中创建任何 propertyMaps,因此它首先创建“根”,向导的 Property-Builder 组件在其中维护其对元模型的贡献,然后创建所需的 Propertymap 元素。

CREATE (propertyMapRoot:META:SourceStructureRelationshipsPropertymaps {name: "Structure Relationship Propertymaps"} )
CREATE propertyMapRoot - [:IS_A] -> (:META:SourceStructureRelationshipsPropertymaps {type: "PART_OF", property: "position", name: "Position", valueType: "number"})
CREATE propertyMapRoot - [:IS_A] -> (:META:SourceStructureRelationshipsPropertymaps {type: "PART_OF", property: "rating", name: "Rating", valueType: "number"})

现在我们来到了一个有趣的地方……我们将创建第一个将杂志编辑内容中的某些东西(即 **SourceContentNode** 节点)与杂志结构元素(**SourceStructureNode**)相关联的元模型构造。

前 X 名榜单项与软件:PRODUCT 相关联。榜单项包括产品开发人员和发布产品的公司的名称。因此,榜单项“通过”ON_LIST 关系“延伸”以确认或创建产品与其开发人员:PERSON 和发布者:COMPANY 之间的关联,因此我们创建了相应的关联。

MATCH (item:META:SourceStructureNodes), (product:META:SourceContentNodes),
		(developer:META:SourceContentNodes), (publisher:META:SourceContentNodes)
WHERE item.type = 'TOPX_LIST_ITEM' AND product.type = 'PRODUCT' AND developer.type = 'PERSON' AND publisher.type = 'COMPANY'
CREATE
	// The listing's primary identity is the software:PRODUCT that has earned a place on a bestseller list
	p3 = ((item) - [:FROM_NODE] ->
				(:META:SourceStructureRelationships {type: "ON_LIST", name: "on list"})
				- [:TO_NODE] -> (product)),
	// 'Fact bits' in a standard Softalk bestseller listing include the name of the primary developer:PERSON
	// and the name of the publishing company. These 'fact bits' confirm/create relationships accordingly...
	p4 = ((product) - [:FROM_NODE] ->
				(:META:SourceStructureRelationships {type: "DEVELOPER", name: "developer"})
				- [:TO_NODE] -> (developer)),
	p5 = ((product) - [:FROM_NODE] ->
				(:META:SourceStructureRelationships {type: "PUBLISHER", name: "publisher"})
				- [:TO_NODE] -> (publisher))
RETURN p3, p4, p5

我敢肯定,您将需要“连续节点拖动”才能定位到我们刚刚对元模型进行的这些最后的有趣添加。这些最后添加内容的“内容满足结构”方面在畅销书榜单项结构元素和产品内容元素之间的 ON_LIST 关系中非常明显。但实际上,“延伸”方面是最有趣的,它最好地展示了“自描述”图形数据库的力量。我认为,**元模型子图**设计模式对于具有松散耦合但语义丰富的数据的应用程序特别有用。

总结思考:关于松散耦合的语义丰富的 信息空间

是的,我们已经深入到细粒度的层面上,看到了杂志内容和结构在结构化意义上的交织方式——例如,广告商列表、购买指南目录等等。但实际上,从杂志中挖掘事实的更大挑战在于,任何给定的“事实”可以以多种不同的方式体现。在最后创建的 Cypher 代码片段中,我们创建了 DEVELOPER 和 PUBLISHER 关系,因为我们发现这种关系在畅销书排行榜项目中有所体现。但是,从这里“充满事实”的图片中可以看出,在 Softalk 杂志中,我们会发现许多地方(实例)出现了“Dan Gorlin 是 Choplifter 的开发者”和“Choplifter 由 Broderbund Software 出版”这两个事实。事实上,这些事实实例的数量和分布是创建事实云的过程中将产生的有趣的新数据。

这个项目真正让我兴奋的一件事是我希望看到我们完整地挖掘了 Softalk 杂志 48 期月刊后的结果。当这本非凡且历史悠久的杂志中的所有“事实”都以“自描述”的 Neo4j 图数据库形式存在时,我相信我们将对技术史中最非凡的时期拥有一个迷人和有价值的新“视角”。

如果您对方法——设计和开发 FactMiners 生态系统——或目标——帮助创建 Softalk 杂志事实云——感兴趣,请随时与我联系。(推特:@Jim_Salmons)

感谢您坚持看完本 GraphGist 系列的前两部分。

让我们继续本 GraphGist 系列的第 3 部分,我们将探讨一个双人游戏场景,它将运用我们在这里构建的元模型。(实际上,第 3 部分还需要一段时间才能发布,因为它目前还处于早期草稿阶段,第 4 部分排在后面。但首先……我要开始制作 FactMiners.org 网站…)