问题:
创建以下MATCH
语句的最有效方式是什么?为什么?
详细的问题:
假设我们有一个Place
具有可变数量属性的节点,并且需要按其类别从潜在的数十亿个节点中查找节点。我试图把每个查询的性能都放在脑子里,事实证明这很困难。
可能的查询:
Place
使用property
查找匹配节点:
MATCH (entity:Place { category: "Food" })
匹配Place
具有以下isCategory
关系的Food
节点:
MATCH (entity:Place)-[:isCategory]->(category:Food)
匹配Place
具有以下Food
关系的Category
节点:
MATCH (entity)-[category:Food]->(:Category)
匹配Food
具有以下isCategoryFor
关系的Place
节点:
MATCH (category:Food)-[:isCategoryFor]->(entity:place)
显然,两者之间的所有变化。关系方向也朝着相反的方向发展。
更高的复杂度:
让我们增加一点复杂度,并说我们现在需要Place
使用多个类别查找所有节点。例如:查找所有Place
类别为category的节点,Food
或者Bar
我们是否仅添加另一条MATCH
语句?如果没有,在这里采取的最高效的路线是什么?
另外:
是否有工具可以帮助我描述遍历过程并告诉我最佳选择方法?
如果我正确地理解了您的域,建议您Category
将自己设置为节点。
MERGE (:Category {name:"Food"})
MERGE (:Category {name:"Bar"})
MERGE (:Category {name:"Park"})
并将每个Place
节点连接到Category
它所属的s。
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"})
然后,如果您要查找Place
属于的Category
,它可能会很快。首先匹配类别,然后分支到与该类别相关的地方。
MATCH (c:Category {name:"Bar"}), (c)<-[:IS_A]-(p:Place)
RETURN p
您的类别数量相对有限,因此与类别的匹配会很快。然后,由于Neo4j实际存储数据的方式,将很快找到与该类别相关的所有地点。
更复杂
在多个类别中查找位置也很容易。
MATCH (c:Category) WHERE c.name = "Bar" OR c.name = "Food", (c)<-[:IS_A]-(p:Place)
RETURN p
同样,您只需要首先匹配类别(快速,因为没有太多),然后分支到相连的地方。
使用索引
如果需要快速,则需要在有意义的地方使用索引。在此示例中,我将在类别的name
属性上使用索引。
CREATE INDEX ON :Category(name)
或者更好的是,对类别名称使用唯一性约束,这将为它们建立索引并防止重复。
CREATE CONSTRAINT ON (c:Category) ASSERT c.name IS UNIQUE
索引(和唯一性)对查询速度有很大的影响。
为什么这是最快的
Neo4j以非常紧凑,易于访问的格式存储节点和关系。一旦有了节点或关系,获取相邻关系或节点的速度就非常快。但是,它分别存储每个节点(和关系)的属性,这意味着浏览属性相对较慢。
目标是尽快到达起始节点。到达那里后,遍历相关实体很快。如果您只有1,000个类别,但您拥有十亿个席位,那么挑选一个个体的速度Category
将比挑选一个个体的速度更快Place
。一旦有了该起始节点,进入相关节点将非常有效。
其他选择
只是为了增强,这就是使您的其他选择变慢或变差的原因。
在第一个示例中,您正在浏览每个节点上的属性以查找匹配项。属性查找很慢,您正在执行十亿次。索引可以帮助解决此问题,但仍然需要大量工作。此外,您正在有效地在十亿个位置中的每个位置上复制类别数据,而没有利用Neo4j的优势。
在所有其他示例中,您的数据模型看起来很奇怪。“食物”,“酒吧”,“公园”等都是类别的实例,而不是单独的类型。它们每个都应该是它们自己的节点,但是它们都应该具有Category
标签,因为这就是它们的本质。另外,类别是物,因此它们应该是节点。关系描述事物之间的联系。以这种方式使用类别是没有意义的。
我希望这有帮助!
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句