我使用以下数据创建了一个简单的图表:
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"
]
}
}
简而言之,我认为像这样对结果中的数据进行非规范化会很快导致响应过大。有没有办法构造cypher或调用REST API来减少重复的结果?
答案 0 :(得分:3)
您在浏览器中运行的查询也绝对会返回笛卡尔积 - 它只是不会出现这种情况,因为视觉结果只会显示一次节点。
在浏览器中运行以下命令。你会很快看到你所得到的所有重叠。
MATCH cities = (city:City)-[]->(c:Country {Id:1}),
counties = (county:County)-[]->(c:Country {Id:1}),
kings = (king:King)-[]->(c:Country {Id:1})
RETURN EXTRACT(x IN NODES(cities) | x.Name),
EXTRACT(x IN NODES(counties) |x.Name),
EXTRACT(x IN NODES(kings) | x.Name)
正如所料,我得到了27行的笛卡尔积。