同和创作矩阵·策划书

关于Neo4j的基础内容:Neo4j 学习手册

UniGal-Diagram:https://github.com/Uni-Gal/UniGal-Diagram/blob/main/Docs/Node.xml


一、综述

1、项目简介

该矩阵旨在将现实/网络/虚构三位一体,创建多层世界维度之间的连接&发展关系,为创作者打造全身心投入的抽象虚拟现实生态环境;其中最顶层分为三大世界:里世界(story)、表世界(web)、现实世界(reality),这三个大脉络图谱又分别对应了不同的业务逻辑与需求。

2、项目规则

关于类无向图的约定:由于neo4j中无法记录无向关联,故在此针对部分双向关系进行约定;

  • 关联信息写为双方关系(如父子、朋友、同学等),整个系统中不应存在双向关联;
  • 节点&关系指向仅创建一次,且一律设置为指向他人,由先来后到的次序进行建立(如A认识B,B认识A也认识C,若按A、B、C的顺序填写,则,A创建A→B并填写关系;B创建B→C并填写关系,C不创建也不填写关系,但三者都有修改关联信息的权限);如果为story中填写,则主作者按扩散关系逐个代入填写(由中心人物向外发散一轮,进行完毕后逐个代入角色继续增加二轮关系,以此类推)

二、里世界

里世界代表创作者内心虚拟出来的世界,比较出名的有妄想ADV、漫威宇宙、星球大战宇宙、红楼梦人物关系、斗罗大陆等等;目前有些志同道合的小伙伴创建了Uni-Gal标准委员会,根据他们的设计可以用较为复杂但清晰的数据结构(统一建模语言)描述绝大多数的虚拟世界,故此处可根据他们的标准来进行设计;该世界旨在帮助创作者更加具象地构造内心的虚拟世界,从创作本身提供协助。

1、最终设计

※其中段落节点属性根据 UniGal-Diagram Ver0.1.1 设计;

 

JSON

{

"chapterStoryId": "011",

"chapterStoryName": "示例章节",

"chapterStoryDescription": "示例配置,用来告诉开发者各字段的详细构造。",

// 没定义周目概念就默认为0

"chapterStoryTimes": 0,

// 只有确定了结局,即从此处往后再无分支时才有值,普通状态下此处为空

"chapterStoryEnding": "",

// 段落节点分为三类:1普通节点、2计算节点、3变动节点、4计算&变动节点,其中既没有计算又没有分歧/收束的节点可置为1,若包含计算使数值变动,置为2,若包含分歧/收束,置为3,若同时满足2和3的情况,置为4

"chapterStoryType": "4",

// 进入此段落需要满足的条件,其中在进入该节点前的上一个段落时,会在跳转的前一刻取出其下一段落节点对象中所有的该字段,按顺序判断后进入符合条件的分支(如包含计算,先完成计算后再判断)

"chapterStoryCondiation":

[

// 可多个条件

{

// key&value 均可自定义

"key_1": "value_1",

// op为条件运算符,可用的值为:"=", "<", ">", ">=", "<="

"op": "="

},

{

// key&value 均可自定义

"key_2": "value_2",

// op为条件运算符,可用的值为:"=", "<", ">", ">=", "<="

"op": "<"

}

],

// 此段落节点中进行的运算

"chapterStoryOperation":

[

// 可多个变更

{

// 进入段落后各数值的运算方式,可用科学运算符为:"+", "-", "*", "/", "square"(平方), "not"(取反), "set"(置为)

"op": "+",

// key为需要变更的字段名,value为该字段的值,其数据类型为int

"key_1": 1

},

{

// 进入段落后各数值的运算方式,可用科学运算符为:"+", "-", "*", "/", "square"(平方), "not"(取反), "set"(置为)

"op": "set",

// key为需要变更的字段名,value为该字段的值,其数据类型为int

"key_2": 0

}

],

// 可多个(表分歧)

"chapterStoryNext":

[

"012",

"013"

],

// 可多个(表收束)

"chapterStoryPrevious":

[

"010"

],

// 附加信息,设为对象形式即可

"addtional": {}

}

example(其实右边的两个节点可以合成一个,你们可以想想怎么设计)↓

作品与段落的关系为1对N,一部作品里有很多章节;作品属性和段落节点属性会以SQL的形式存储到关系型数据库MySQL,而人物节点属性和连接属性会以NoSQL的形式存储进非关系型数据库Neo4j中。

其中段落之间的关系通过桑基图表示↓

段落节点、人物节点、连接属性这三大对象之间的关系为↓

※由于里世界过于复杂,目前仅设计&开发后端,待表世界&现实世界的前端开发完成后,再结合相关开发经验来完成里世界的前端设计&开发。

2、早期设计(存档)

由于Story层不同于Web和Reality层,普通的世界仅由一维时间构成,而故事里可以存在多个平行世界,这些平行世界又可以对应不同的故事(作品与平行世界的对应关系为N对N),每个故事里出现的人物又可以同时存在于各类平行世界中……所以需要在所有关系的上层加入一个时间轴来归纳区分,将各类关系进一步低耦合,具体设计如下:

1)时间轴

时间层选用桑葚图,其节点为起点、终点、枢纽点(枢纽点又可细化为分歧点与收束点),节点属性包含节点id、基本信息(如观测者状态切片、客观背景切片)、节点种类、节点变动(分歧&收束)详情(仅枢纽点包含);边的属性为结构id、结构梗概、包含人物、结构编码(如1-1、1-2)、结构标题(俗称XX线、XX篇章);

※人与时间的关系:游离、静态、无关变量。

2)人物关系

刚刚已经通过时间轴拆分了平行世界的复杂关系,那么关系会改变为:一个故事包含多个结构(这些结构可以存在于同一或不同的平行世界上,相当于对平行世界这个概念做了解耦)、每个结构对应了不同的人物关系,而人物节点本身是不变的,可以被所有结构进行引用;

3)使用流程

此处仅讨论故事侧的使用流程,首先分为3个模块:创建角色、创建故事、创建单个故事结构图与创建各结构下的人脉关系;创建角色和创建故事比较简单,常规表格的CRUD;创建完毕后去到故事结构图,新建默认为「起点→枢纽点」+「枢纽点→终点」,默认创建的这些是不能被删除的;点击按钮可新建枢纽点和结构(点击后弹出对话框,填写完毕后提交后台新增),右击已创建的点与边可以修改;

一期:左击边可选中,点击其他边时,原先选中的边失去高光,高亮新选中的边;

二期:左击边可选中,再左击取消选中,即可以一次性选中多条边,左击点可选中与该点相连接的所有边;

选中后下方会以连接图的方式出现所选边对应的人脉关系,点击人脉关系中的点与边即可实时修改。

三、表世界

表世界代表的是当下人们的网络社交关系,比如社交平台的关注加好友、线上合作开发、虚拟资源共享等,都属于这一类;目前该世界侧重的属性有:活跃领域&沟通要旨,侧重这两点也是为了旨在帮助创作者更好地找到同盟,快速寻求资源,为某个创作主体的整体架构提供间接帮助。

四、现实世界

现实世界代表的是人们现实生活中的社交关系,俗话说「艺术来源于生活,却又高于生活」,取材是创作中必不可少的一环;该世界侧重于个体的性格与关系,为创作者厘清现实关系,为实际创作提供灵感。

五、唯一生物识别码

最后还有一层关系可以将这三个世界中的个体关联起来,这就是「唯一生物代码」;这类关系将存储于关系型数据库中,旨在进一步聚合个体之间的关系:

六、开发相关

1CRUD相关代码

1)创建节点

里世界

SQL

merge (p:PersonStory{

personStoryId:"",

personStoryName:"",

personStorySex:"",

personStoryInfo:"",

personStoryFeature:""

}) return p

表世界

 

SQL

merge (p:PersonWeb{

personWebId:"",

personWebName:"",

personWebPlatform:"",

personWebInfo:"",

personWebField:"",

personWebKey:""

}) return p

现实世界

 

SQL

merge (p:PersonReality{

personRealityId:"",

personRealityName:"",

personRealitySex:"",

personRealityBrithday:"",

personRealityInfo:"",

personRealityFeature:"",

personRealityKey:"",

personRealityAbility:""

}) return p

2)创建关系

里世界

 

SQL

match(pa:PersonStory{

personStoryId:""

}),(pb:PersonStory{

personStoryId:""

}) merge (pa)-[c:ConnectStory{

"connectStoryId": "",

"connectStoryName":"",

"connectStoryInfo":""

}]->(pb) return pa,pb,c

表世界

 

SQL

match(pa:PersonWeb{

personWebId:""

}),(pb:PersonWeb{

personWebId:""

}) merge (pa)-[c:ConnectWeb{

"connectWebId": "",

"connectWebName":"",

"connectWebInfo":""

}]->(pb) return pa,pb,c

现实世界

 

SQL

match(pa:PersonReality{

personRealityId:""

}),(pb:PersonReality{

personRealityId:""

}) merge (pa)-[c:ConnectReality{

"connectRealityId": "",

"connectRealityName":"",

"connectRealityInfo":""

}]->(pb) return pa,pb,c

3)呈现脉络

(*创建后将中心移动至新节点或新连接)

里世界

 

SQL

MATCH (p:PersonStory) RETURN p

表世界

 

SQL

MATCH (p:PersonWeb) RETURN p

现实世界

 

SQL

MATCH (p:PersonReality) RETURN p

4)修改节点

里世界

第一步:返回节点详情

 

SQL

MATCH (p:PersonStory{

personStoryId:""

}) RETURN p

第二步:更新节点详情

 

SQL

MATCH (p:PersonStory{

personStoryId: ""

})

SET p.personStoryName = "", p.personStorySex = "",

p.personStoryInfo = "", p.personStoryFeature = ""

RETURN p

表世界

第一步:返回节点详情

 

SQL

MATCH (p:PersonWeb{

personWebId:""

}) RETURN p

第二步:更新节点详情

 

SQL

MATCH (p:PersonWeb{

personWebId:""

})

SET p.personWebName = "", p.personWebPlatform = "",

p.personWebField = "", p.personWebInfo = "", p.personWebKey = ""

RETURN p

现实世界

第一步:返回节点详情

 

SQL

MATCH (p:PersonReality{

personRealityId:""

}) RETURN p

第二步:更新节点详情

 

SQL

MATCH (p:PersonReality{

personRealityId:""

})

SET p.personRealityName = "", p.personRealitySex = "",

p.personRealityBrithday = "", p.personRealityInfo = "",

p.personRealityFeature = "", p.personRealityKey = "",

p.personRealityAbility = ""

RETURN p

5)修改关系

里世界

第一步:返回连接详情

 

SQL

MATCH ()-[c:ConnectStory{

connectStoryId:""

}]-()

RETURN c

第二步:更新连接详情

 

SQL

MATCH ()-[c:ConnectStory{

connectStoryId:""

}]-()

set c.connectStoryName = "", c.connectStoryInfo = ""

RETURN c

表世界

第一步:返回连接详情

 

SQL

MATCH ()-[c:ConnectWeb{

connectWebId:""

}]-()

RETURN c

第二步:更新连接详情

 

SQL

MATCH ()-[c:ConnectWeb{

connectWebId:""

}]-()

set c.connectWebName = "", c.connectWebInfo = ""

RETURN c

现实世界

第一步:返回连接详情

 

SQL

MATCH ()-[c:ConnectReality{

connectRealityId:""

}]-()

RETURN c

第二步:更新连接详情

 

SQL

MATCH ()-[c:ConnectReality{

connectRealityId:""

}]-()

set c.connectRealityName = "", c.connectRealityInfo = ""

RETURN c

6)删除节点

里世界

 

SQL

MATCH (p:PersonStory{

personStoryId:""

})

DELETE p

表世界

 

SQL

MATCH (p:PersonWeb{

personWebId:""

})

DELETE p

现实世界

 

SQL

MATCH (p:PersonReality{

personRealityId:""

})

DELETE p

7)删除关系

里世界

 

SQL

MATCH ()-[c:ConnectStory{

connectStoryId:""

}]-()

DELETE c

表世界

 

SQL

MATCH ()-[c:ConnectWeb{

connectWebId:""

}]-()

DELETE c

现实世界

 

SQL

MATCH ()-[c:ConnectReality{

connectRealityId:""

}]-()

DELETE c

2、后端代码

SpringBoot(框架)+Mybatis(持久层组件)+org.neo4j.driver.v1(数据库插件)

3、前端代码

vue.js(框架)+Echarts(渲染插件)

4、参考资料

https://blog.csdn.net/qq_34661106/article/details/103540826

https://blog.csdn.net/uniquewonderq/article/details/80924347

https://github.com/whl6785968/BackstageWaterForG

https://github.com/AntMxs/MyNeo4j

https://github.com/neo4j-contrib/neo4j-jdbc

 

 


人生有無數種可能,人生有無限的精彩,人生沒有盡頭。一個人只要足夠的愛自己,尊重自己內心的聲音,就算是真正的活著。