【发布时间】:2014-10-16 21:50:07
【问题描述】:
我使用以下数据创建了一个简单的图表:
CREATE (england:Country {Name:"England",Id:1})
CREATE CONSTRAINT ON (c:Country) ASSERT c.ID IS UNIQUE
CREATE (john:King {Name:"John",Id:1})
CREATE (henry3:King {Name:"Henry III",Id:2})
CREATE (edward1:King {Name:"Edward I",Id:3})
CREATE CONSTRAINT ON (k:King) ASSERT k.ID IS UNIQUE
MATCH (country:Country),(king:King) WHERE country.Id = 1 AND king.Id = 1 CREATE (country)<-[r:KING_OF]-(king)
MATCH (country:Country),(king:King) WHERE country.Id = 1 AND king.Id = 2 CREATE (country)<-[r:KING_OF]-(king)
MATCH (country:Country),(king:King) WHERE country.Id = 1 AND king.Id = 3 CREATE (country)<-[r:KING_OF]-(king)
CREATE (cornwall:County {Name:"Cornwall",Id:1})
CREATE (devon:County {Name:"Devon",Id:2})
CREATE (somerset:County {Name:"Somerset",Id:3})
CREATE CONSTRAINT ON (c:County) ASSERT c.ID IS UNIQUE
MATCH (country:Country),(county:County) WHERE country.Id = 1 AND county.Id = 1 CREATE (country)<-[r:COUNTY_IN]-(county)
MATCH (country:Country),(county:County) WHERE country.Id = 1 AND county.Id = 2 CREATE (country)<-[r:COUNTY_IN]-(county)
MATCH (country:Country),(county:County) WHERE country.Id = 1 AND county.Id = 3 CREATE (country)<-[r:COUNTY_IN]-(county)
CREATE (bristol:City {Name:"Bristol",Id:1})
CREATE (london:City {Name:"London",Id:2})
CREATE (york:City {Name:"York",Id:3})
CREATE CONSTRAINT ON (c:City) ASSERT c.ID IS UNIQUE
MATCH (country:Country),(city:City) WHERE country.Id = 1 AND city.Id = 1 CREATE (country)<-[r:CITY_IN]-(city)
MATCH (country:Country),(city:City) WHERE country.Id = 1 AND city.Id = 2 CREATE (country)<-[r:CITY_IN]-(city)
MATCH (country:Country),(city:City) WHERE country.Id = 1 AND city.Id = 3 CREATE (country)<-[r:CITY_IN]-(city)
(请注意,我使用 'thiscomputer.mydomain.com' 作为 'localhost' 的别名,这可笑地禁止我使用)...
如果我去http://thiscomputer.mydomain.com:7474/browser/ 并执行密码
MATCH cities = (city:City)-[]->(c:Country {Id:1}), counties = (county:County)-[]->(c:Country {Id:1}), kings = (king:King)-[]->(c:Country {Id:1}) RETURN cities, counties, kings
...我得到一个以英格兰国家为中心的漂亮图表。没有节点重复。
如果我启动一个 REST 客户端并执行以下操作:
网址:http://thiscomputer.mydomain.com:7474/db/data/transaction/commit
动词:POST
正文:
{
"statements" : [{
"statement": "MATCH cities = (city:City)-[]->(c:Country {Id:1}), counties = (county:County)-[]->(c:Country {Id:1}), kings = (king:King)-[]->(c:Country {Id:1}) RETURN cities, counties, kings",
"resultDataContents" : [ "graph" ]
}]
}
(注意密码查询是相同的)
我最终得到了一组太大而无法在此处粘贴的结果。
基本上,我似乎得到了结果的笛卡尔积。由于有3个王,3个县,3个市,所以有27个结果。
这是一个相当简单的图表。在我工作的域中,我想要的图将包含一个聚合根(在本例中为英格兰),以及许多不同类型的关联节点。如果 REST API 返回笛卡尔积,我可能会得到数千个结果。
所以我的问题是:为什么 REST API 返回所有返回节点的笛卡尔积?是我的密码不正确,还是我使用的 REST API 不正确?
如果我能得到这样的结果(伪 JSON)会简单得多:
{
Country:{
Name: "England",
Id: 1,
Cities:[
...etc
],
Counties:[
...etc
],
Kings:[
...etc
]
}
}
甚至可能是这样:
{
data:{
nodes:[
{
Name:"England",
Id: 1,
uniqueIdInResults:1
},
...etc
],
relationships:[
uniqueIdInResults1: 1,
uniqueIdInResults2: 2,
type: "KING_OF"
]
}
}
简而言之,我认为像这样对结果中的数据进行非规范化会很快导致响应过大。有什么方法可以构造密码或调用 REST API 以减少重复的结果?
【问题讨论】:
-
关于改进“graph”变体的响应格式的好点,因为它不需要分成行,但可能这甚至是一个单独的用例。每行一个,一个返回全局图。
-
我感兴趣的是通过一次调用加载整个聚合(在 DDD 意义上)。虽然我认为这应该是可能的(单个索引查找以获取聚合根,然后是纯图遍历),但我认为非规范化使得返回的数据量不切实际。
-
我了解您如何使用(例如)JSON 表示多层次数据存在一些问题,但我的第二个建议(返回节点列表和关系列表)将是一种方法,还有更多比笛卡尔积更有效。