如何在Cypher中改进多个JOIN查询

时间:2014-08-12 22:07:10

标签: join neo4j cypher

我正在寻找在我的密码查询中进行某种多重JOIN的最佳方法。我找到了解决方案,但对我来说似乎有点太复杂了。 此查询的目标是从第一个节点开始,检索ID和名称'来自与第一个节点相关的许多其他节点的属性,通过多种类型的关系(参见下文)

START c=node(72)
OPTIONAL MATCH (c)<-[:MANAGEMENT_TEAM]-(from_board)
OPTIONAL MATCH (c)<-[:SHAREHOLDER]-(shareholder)
OPTIONAL MATCH (c)-[:PRODUCT_OFFERED]->(product)
OPTIONAL MATCH (c)<-[:CUSTOMER]-(customer)-[:CORE_BUSINESS]->(industry_sector)
OPTIONAL MATCH (c)-[:ASSIGNEE]->(patent)
RETURN [x IN collect(DISTINCT(from_board))| {id:id(x), name:x.name}] AS Management,
       [x IN collect(DISTINCT(shareholder))| {id:id(x), name:x.name}] AS Shareholders,
       [x IN collect(DISTINCT(product))| {id:id(x), name:x.name}] AS Products,
       [x IN collect(DISTINCT(customer))| {id:id(x), name:x.name}] AS Customers,
       [x IN collect(DISTINCT(industry_sector))| {id:id(x), name:x.name}] AS Industry_sectors,
       [x IN collect(DISTINCT(patent))| {id:id(x), name:x.name}] AS Patent

此查询返回6列,每列包含元组列表(id&amp; name)。 你看到它有多改进吗? (尤其是丑陋的部分&#34;提取/收集/分离&#34;) 或者,你知道另一种方式吗? 感谢

3 个答案:

答案 0 :(得分:1)

一个选项:

MATCH (c)
WHERE id(c) = 72
OPTIONAL MATCH (c)<-[:MANAGEMENT_TEAM]-(from_board)
WITH c, collect(distinct {id:id(from_board), name:from_board.name}) as Management
OPTIONAL MATCH (c)<-[:SHAREHOLDER]-(shareholder)
WITH c, Management, collect(distinct {id:id(shareholder), name:shareholder.name}) as Shareholders
....
RETURN c, Management, Shareholders, ...

另一个选项

MATCH (c)
WHERE id(c) = 72
OPTIONAL MATCH (c)-[r]-(x)
RETURN c,type(r) as type, collect(distinct {id:id(x), name:x.name}) as connected

答案 1 :(得分:0)

尝试使用schema indexes进行搜索查询。

它被称为INDEXING

索引使数据库搜索效率提高。用于创建INDEX

CREATE INDEX属性(属性应该是唯一的)

答案 2 :(得分:0)

感谢@Micheal,你的第二个选项让cypher查询变得更加清晰,现在它看起来像是:

START c=node({companyId})
      OPTIONAL MATCH (c)<-[management_rel:MANAGEMENT_TEAM]-(management)
      OPTIONAL MATCH (c)<-[shareholder_rel:SHAREHOLDER]-(shareholder)
      OPTIONAL MATCH (c)-[:PRODUCT_OFFERED]->(product)
      OPTIONAL MATCH (c)<-[:CUSTOMER]-(customer)-[:CORE_BUSINESS]->(industry_sector)
      OPTIONAL MATCH (c)-[:ASSIGNEE]->(patent)
    RETURN
      c AS company,
      collect(distinct({id:id(management), name:management.name, role:management_rel.role})) AS managements,
      collect(distinct({id:id(shareholder), name:shareholder.name, percentage:shareholder_rel.percentage  })) AS shareholders,
      collect(distinct({id:id(product), name:product.name, description:product.description})) AS products,
      collect(distinct({id:id(customer), name:customer.name, sector_id:id(industry_sector), sector:industry_sector.name}))  AS customers,
      collect(distinct({id:id(patent), name:patent.name, title:patent.title, website:patent.website, description:patent.description})) AS patents

如您所见,请求有更多加入,例如'managaments'元组中添加的管理关系。此请求需要183 ms才能由EC2小实例上的REST API执行。 地图创建,独特和收集的组合非常强大:)。