Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Neo4j 创建以下匹配语句最有效的方法是什么?为什么?_Neo4j_Cypher - Fatal编程技术网

Neo4j 创建以下匹配语句最有效的方法是什么?为什么?

Neo4j 创建以下匹配语句最有效的方法是什么?为什么?,neo4j,cypher,Neo4j,Cypher,问题: 创建以下MATCH语句最有效的方法是什么?为什么 详细问题: 假设我们有一个Place节点,该节点具有可变数量的属性,并且需要根据其类别从潜在的数十亿个节点中查找节点。我正试图了解每个查询的性能,结果证明这是相当困难的 可能的查询: 使用属性查找匹配放置节点: 匹配(实体:地点{category:“Food”}) 将Place节点与isCategory关系与Food节点匹配: 匹配(实体:地点)-[:isCategory]->(类别:食品) 将位置节点与食品关系匹配到类别节点: 匹配(

问题:
创建以下
MATCH
语句最有效的方法是什么?为什么

详细问题:
假设我们有一个
Place
节点,该节点具有可变数量的属性,并且需要根据其类别从潜在的数十亿个节点中查找节点。我正试图了解每个查询的性能,结果证明这是相当困难的

可能的查询:

  • 使用
    属性
    查找匹配
    放置
    节点:
    匹配(实体:地点{category:“Food”})

  • Place
    节点与
    isCategory
    关系与
    Food
    节点匹配:
    匹配(实体:地点)-[:isCategory]->(类别:食品)

  • 位置
    节点与
    食品
    关系匹配到
    类别
    节点:
    匹配(实体)-[类别:食品]->(:类别)

  • Food
    节点与
    iscategorifFor
    Place
    节点的关系匹配:
    MATCH(类别:食品)-[:isCategoryFor]->(实体:地点)

很明显,这两者之间的所有变化。关系的方向也在向相反的方向发展

MATCH (c:Category) WHERE c.name = "Bar" OR c.name = "Food", (c)<-[:IS_A]-(p:Place)
RETURN p
更复杂:
让我们稍微复杂一点,假设我们现在需要使用多个类别查找所有
Place
节点。例如:查找具有类别
食品
条形图的所有
Place
节点 我们能不能再加上一个
MATCH
语句?如果没有,在这里最有效的路线是什么

额外:

是否有工具可以帮助我描述遍历过程并告诉我选择的最佳方法?

如果我正确理解您的域,我建议将您的
类别
设置为节点本身

MERGE (:Category {name:"Food"})
MERGE (:Category {name:"Bar"})
MERGE (:Category {name:"Park"})
并将每个
位置
节点连接到它所属的
类别

MERGE (:Place {name:"Central Park"})-[:IS_A]->(:Category {name:"Park"})
MERGE (:Place {name:"Joe's Diner"})-[:IS_A]->(:Category {name:"Food"})
MERGE (:Place {name:"Joe's Diner"})-[:IS_A]->(:Category {name:"Bar"})
然后,如果您想查找属于
类别的
位置
,它可以非常快速。首先匹配类别,然后扩展到与该类别相关的位置

MATCH (c:Category {name:"Bar"}), (c)<-[:IS_A]-(p:Place)
RETURN p
或者更好的是,对类别名称使用唯一性约束,这将索引它们并防止重复

CREATE CONSTRAINT ON (c:Category) ASSERT c.name IS UNIQUE
索引(和唯一性)对查询速度有很大影响

为什么这是最快的

Neo4j以非常紧凑、快速访问的格式存储节点和关系。一旦你有了一个节点或关系,获得相邻的关系或节点是非常快的。但是,它分别存储每个节点(和关系)的属性,这意味着查看属性的速度相对较慢

目标是尽快到达起始节点。一旦到达那里,遍历相关实体就很快了。如果你只有1000个类别,但你有10亿个位置,那么挑选一个
类别
比挑选一个
位置
更快。一旦有了起始节点,就可以非常高效地访问相关节点

其他选项

只是想强调一下,这是让你的其他选择变得更慢或更糟的原因

在第一个示例中,您正在查看每个节点上的属性以查找匹配项。属性查找速度很慢,而且您正在执行十亿次。索引可以帮助实现这一点,但仍然需要大量的工作。此外,您在每个十亿个地点有效地复制了类别数据,而没有利用Neo4j的优势

在所有其他示例中,您的数据模型似乎都很奇怪。“食品”、“酒吧”、“公园”等都是类别的实例,而不是单独的类型。它们都应该是自己的节点,但它们都应该有
类别
标签,因为它们就是这样。此外,类别是事物,因此它们应该是节点。关系描述事物之间的联系。以这种方式使用类别是没有意义的


我希望这有帮助

如果我正确理解您的域,我建议将您的
类别
设置为节点本身

MERGE (:Category {name:"Food"})
MERGE (:Category {name:"Bar"})
MERGE (:Category {name:"Park"})
并将每个
位置
节点连接到它所属的
类别

MERGE (:Place {name:"Central Park"})-[:IS_A]->(:Category {name:"Park"})
MERGE (:Place {name:"Joe's Diner"})-[:IS_A]->(:Category {name:"Food"})
MERGE (:Place {name:"Joe's Diner"})-[:IS_A]->(:Category {name:"Bar"})
然后,如果您想查找属于
类别的
位置
,它可以非常快速。首先匹配类别,然后扩展到与该类别相关的位置

MATCH (c:Category {name:"Bar"}), (c)<-[:IS_A]-(p:Place)
RETURN p
或者更好的是,对类别名称使用唯一性约束,这将索引它们并防止重复

CREATE CONSTRAINT ON (c:Category) ASSERT c.name IS UNIQUE
索引(和唯一性)对查询速度有很大影响

为什么这是最快的

Neo4j以非常紧凑、快速访问的格式存储节点和关系。一旦你有了一个节点或关系,获得相邻的关系或节点是非常快的。但是,它分别存储每个节点(和关系)的属性,这意味着查看属性的速度相对较慢

目标是尽快到达起始节点。一旦到达那里,遍历相关实体就很快了。如果你只有1000个类别,但你有10亿个位置,那么挑选一个
类别
比挑选一个
位置
更快。一旦有了起始节点,就可以非常高效地访问相关节点

其他选项

只是想强调一下,这是让你的其他选择变得更慢或更糟的原因

在第一个示例中,您正在查看每个节点上的属性以查找匹配项。属性查找速度很慢,而且您正在执行十亿次。索引可以帮助实现这一点,但仍然需要大量的工作。此外,您还可以有效地复制