Cypher查询性能和结构

时间:2014-09-04 12:41:36

标签: neo4j cypher

我刚刚开始使用图形数据库和Neo4j。我创建了具有以下标签的节点:Person,Company,City,Skill,它们之间有一个或多个关系。

我正在尝试进行一个cypher查询,找到一个Person节点(按节点ID),然后我想找到与此Person相关的所有技能,公司等。这是我到目前为止的查询:

MATCH (person:Person)
WHERE ID (person) = 123
WITH person LIMIT 1
OPTIONAL MATCH (p:Person) - [:HAS_SKILL] -> (skill:Skill)
WHERE ID (p) = 123
WITH person, skill ORDER BY skill.name ASC
OPTIONAL MATCH (p:Person) - [:WORKED_AT] -> (company:Company)
WHERE ID (p) = 123
WITH person, skill, company ORDER BY company.name ASC
OPTIONAL MATCH (p:Person) - [:LIVES_IN] -> (city:City)
WHERE ID (p) = 123
WITH person
, collect(DISTINCT skill) as skills
, collect(DISTINCT company) as companies
, city LIMIT 1
RETURN person, skills, companies, city

我担心这不是一个真正的最佳查询,如果/当我们得到几百万个节点时它看起来会非常慢。有人能告诉我构建这种查询的更好方法吗?我应该把它分成几个较小的查询吗?

1 个答案:

答案 0 :(得分:2)

我认为第一件事是你不需要继续查询person对象,虽然我不确定这会影响性能,因为person变量已经绑定了。这会将您的查询减少到:

MATCH (person:Person)
WHERE ID (person) = 123
WITH person
OPTIONAL MATCH (person) - [:HAS_SKILL] -> (skill:Skill)
WITH person, skill ORDER BY skill.name ASC
OPTIONAL MATCH (person) - [:WORKED_AT] -> (company:Company)
WITH person, skill, company ORDER BY company.name ASC
OPTIONAL MATCH (person) - [:LIVES_IN] -> (city:City)
WITH person
, collect(DISTINCT skill) as skills
, collect(DISTINCT company) as companies
, city LIMIT 1
RETURN person, skills, companies, city

您也不需要继续使用WITH,因为您可以拥有多个MATCH语句,但现在我已删除了您的订单声明:

MATCH (person:Person)
WHERE ID (person) = 123
OPTIONAL MATCH (person) - [:HAS_SKILL] -> (skill:Skill)
OPTIONAL MATCH (person) - [:WORKED_AT] -> (company:Company)
OPTIONAL MATCH (person) - [:LIVES_IN] -> (city:City)
RETURN  person
, collect(DISTINCT skill) as skills
, collect(DISTINCT company) as companies
, city LIMIT 1

我相信你可以订购更多这样的订单,但是你最终会得到一个奇怪的排序!:

MATCH (person:Person)
WHERE ID (person) = 123
OPTIONAL MATCH (person) - [:HAS_SKILL] -> (skill:Skill)
OPTIONAL MATCH (person) - [:WORKED_AT] -> (company:Company)
OPTIONAL MATCH (person) - [:LIVES_IN] -> (city:City)
WITH DISTINCT person, skill, company, city
ORDER BY skill.name, company.name
RETURN  person
, collect(DISTINCT skill) as skills
, collect(DISTINCT company) as companies
, city LIMIT 1

无论性能是否更高,您都必须进行测试。如果你想强加限制或聚合,你需要像原来那样使用你的WITH语句。

记得马克·李约瑟关于优化的blog post,并非直接相关,但包含一些值得参考的规则:

  1. 尽可能使用参数。
  2. 如果不需要笛卡尔产品,则无需获取所需数据。
  3. 避免WHERE子句中的模式
  4. 以最低基数标识符(理想情况为1)开始您的MATCH模式,并向外展开。
  5. 分离您的MATCH模式,为每个模式进行最小量的扩展。为每个模式添加1个新标识符。
  6. 征服Wes!