如何构建图形数据库以支持三向关系? [英] How to structure a graph database to support 3-way relationships?

查看:226
本文介绍了如何构建图形数据库以支持三向关系?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试找出我一直在从事的个人Web应用程序的数据库后端.由于我在数据中需要灵活性,因此关系数据库不可行,并且可能以某种形式存储文档.当我了解图数据库时,我觉得这将是完美的.

I've been trying to figure out a database backend for a personal webapp I've been working on. Due to the flexibility that I require in the data, a relational database isn't feasible and some form of document storage is likely. When I learned about graph databases, I felt that this would be perfect.

但是,我遇到了一个问题:我需要能够以某种方式定义三向关系.我还没有决定要使用哪个数据库,但是我一直在修改Neo4j,所以我将使用Cypher来描述问题.

However, I've run into someone of an issue: I need to be able to define a 3-way relationship in some way. I haven't decided on a database yet, but I've been tinkering with Neo4j, so I'll use Cypher to describe the problem.

从本质上讲,我从以下内容开始:

Essentially, I start out with this:

(a:N)-[r:E]->(b:N)

我需要的是一种不仅将多个节点关联到a和b,还关联到r的方法.这些其他节点将存储有关所有3个节点的不同信息.我认为可能只有两种方法可以处理此问题:将关系存储在其自己的节点中或存储对包含该信息的节点的引用并创建伪边缘.我认为前者可能是一个更好的主意,为我们提供更多类似的信息:

What I need is a way to relate multiple nodes to not only a and b, but also r. These other nodes are going to be storing different pieces of information about all 3. I decided that there are probably only two ways to handle this: store the relationship in its own node or store references to the nodes containing the information and create pseudo-edges. I figure that the former is probably a better idea giving us something more like this:

(a:N)<-[:E]-(r:R)->[:E](b:N)
(s:S)->(a)
(s)->(r)
(s)->(b)

因此,现在,这导致查询数据时出现问题.使用图形数据库的全部目的是能够遍历图形.如果我这样做,是否可以在N型节点之间递归遍历?处理此问题的正确方法是什么?我想到了几种不同的处理方法,但是它们都有缺点.是否有特定的图形数据库本身支持这种类型的功能?

So, now, this leads to an issue with querying the data. The whole point of using a graph database is being able to traverse the graph. If I do something like this, is there a way to recursively traverse between nodes of type N? What is the proper way of handling this? I've thought of several different ways of handling this, but all of them have their faults. Is there a specific graph database that supports this type of functionality natively?

更新

使用原始代码,我能够使用以下代码递归遍历节点:

With the original code, I was able to recursively traverse the nodes with this code:

MATCH (a:N)-[:E*]->(b:N)
RETURN a,b

但是,一旦我将边缘拉到一个超边缘中,我就无法确定是否有一种方法可以递归地遍历图形到不确定的深度,因为我会交替使用节点类型.我正在寻找一些类似的东西

However, once I pull the edge out into a hyperedge, I can't figure out if there is a way to be able to traverse the graph recursively to an undetermined depth because I would be alternating node types. I'm looking for something along the lines of

MATCH chain=((a:N)-[]->(r:R)-[]->(b:N))*
RETURN [nodes of type N along the chain]

如果答案是在创建超级边缘时也要在a和b之间创建一条边缘,那么我的问题就变成了:是否有一种确保将边缘和超级边缘一起去除的好方法?基本上,两者都感觉像是一种解决方法,而不是实际的解决方案.

If the answer is just to also create an edge between a and b while creating the hyper edge, then my question becomes: is there a good way to ensure that the edge and hyper edge are removed together? Basically, having both feels like a work-around rather than an actual solution.

推荐答案

您所描述的场景在属性图模型中由提到的hyperedge模式@Pangea处理.本质上,您需要将边缘(需要边缘进/出)转换为顶点.对于图,我将其更多地看作是非规范化,而更多地是不同的建模抽象.

The scenario you describe is handled in property graph model by the hyperedge pattern @Pangea mentioned. You essentially convert the edge (that needs edges in/out of it) to a vertex. With graphs I would think of it less as a denormalization and more of a different modelling abstraction.

就本机对边缘的支持而言,您标记问题的所有图表都没有直接支持这种功能.当您确实包括Titan和OrientDB时,我假设您也将TinkerPop评估为解决方案的可能部分,并且我可以进一步说,由于蓝图"不支持边缘上的边缘,因此蓝图"图也不会.

As far as native support for edges on edges go, none of the graphs you tagged your question with directly support such a feature. As you did include Titan and OrientDB I assume you are evaluating TinkerPop as a possible part of your solution as well and I can further say that as Blueprints doesn't support edges on edges, none of the Blueprints graphs will either.

就遍历而言,我不能说我完全遵循递归遍历"的意思.如果您可以详细说明,我可以尝试修改我的答案.我将添加一个简单的示例,说明您如何从"a"顶点遍历以找到Gremlin中的所有其他相关顶点(对不起,我不了解Cypher):

As far as traversal goes, I can't say I fully follow what you mean by "recursively traverse". If you could elaborate a bit, I could try to amend my answer. I'll add this simple example of how you would traverse from the "a" vertex to find all other related vertices in Gremlin (sorry, I don't know Cypher):

gremlin> g = new TinkerGraph()
==>tinkergraph[vertices:0 edges:0]
gremlin> va = g.addVertex([type:'N',name:'a'])
==>v[0]
gremlin> er = g.addVertex([type:'R',name:'r'])
==>v[1]
gremlin> vb = g.addVertex([type:'N',name:'b'])
==>v[2]
gremlin> vc = g.addVertex([type:'N',name:'c'])
==>v[5]
gremlin> va.addEdge('e',er)
==>e[3][0-e->1]
gremlin> vb.addEdge('e',er)
==>e[4][2-e->1]
gremlin> vc.addEdge('e',er)                   
==>e[6][5-e->1]
gremlin> va.out.in.except([va]).name
==>c
==>b
gremlin> vd = g.addVertex([type:'N',name:'d'])
==>v[7]
gremlin> es = g.addVertex([type:'R',name:'s'])
==>v[8]
gremlin> vb.addEdge('e',es)
==>e[9][2-e->8]
gremlin> vd.addEdge('e',es)
==>e[10][7-e->8]
gremlin> x=[];va.aggregate(x).out.in.except(x).loop(4){it.loops<2}.name
==>c
==>b
gremlin> x=[];va.aggregate(x).out.in.except(x).loop(4){it.loops<3}.name
==>d

关于:

如果答案仅仅是在a和b之间创建一条边,而 创建超级边缘,然后我的问题变成:有没有好的方法 确保将边缘和超边缘一起去除?

If the answer is just to also create an edge between a and b while creating the hyper edge, then my question becomes: is there a good way to ensure that the edge and hyper edge are removed together?

删除"hyperedge"顶点时,将自动删除与之相连的边,因此可以有效地将它们一起删除.

When you remove the "hyperedge" vertex, you will automatically remove the edges connected to it, so you effectively remove them together.

这篇关于如何构建图形数据库以支持三向关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆