【问题标题】:neo4j rest api cypher appears to return cartesian product of nodesneo4j rest api cypher 似乎返回节点的笛卡尔积
【发布时间】: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 表示多层次数据存在一些问题,但我的第二个建议(返回节点列表和关系列表)将是一种方法,还有更多比笛卡尔积更有效。

标签: neo4j cypher


【解决方案1】:

您在浏览器中运行的查询也绝对返回了笛卡尔积 - 它只是不会以这种方式显示,因为视觉结果只会显示一次节点。

在浏览器中运行以下命令。您会很快看到所有重叠。

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 行的笛卡尔积。

【讨论】:

  • 谢谢。并不是说我认为是 REST API(而不是 cypher)在进行非规范化。我只是想知道我是否可以以某种方式诱使查询更有效地塑造响应数据。
  • 我想我指的是“......我得到了一个以英格兰国家为中心的漂亮图表。没有重复节点。”我的观点是,视觉结果在冗余数据/笛卡尔积方面可能会产生误导。
  • 但是我在 REST 中使用“图表”结果的经验很少,所以我不确定在编辑您的 Cypher 以获得您想要的结果方面是否有很大帮助。
猜你喜欢
  • 2014-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多