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
Graph 如何使用多节点匹配优化Neo4j Cypher查询(笛卡尔积)_Graph_Neo4j_Query Optimization_Cypher_Cartesian Product - Fatal编程技术网

Graph 如何使用多节点匹配优化Neo4j Cypher查询(笛卡尔积)

Graph 如何使用多节点匹配优化Neo4j Cypher查询(笛卡尔积),graph,neo4j,query-optimization,cypher,cartesian-product,Graph,Neo4j,Query Optimization,Cypher,Cartesian Product,我目前正在尝试合并三个数据集以进行分析。我使用某些公共字段来建立数据集之间的连接。为了创建连接,我尝试使用以下类型的查询: MATCH (p1:Person),(p2:Person) WHERE p1.email = p2.email AND p1.name = p2.name AND p1 <> p2 CREATE UNIQUE (p1)-[IS]-(p2); 匹配(p1:个人),(p2:个人) 其中p1.email=p2.email和p1.name=p2.name和p1.p2

我目前正在尝试合并三个数据集以进行分析。我使用某些公共字段来建立数据集之间的连接。为了创建连接,我尝试使用以下类型的查询:

MATCH (p1:Person),(p2:Person)
WHERE p1.email = p2.email AND p1.name = p2.name AND p1 <> p2 
CREATE UNIQUE (p1)-[IS]-(p2);
匹配(p1:个人),(p2:个人)
其中p1.email=p2.email和p1.name=p2.name和p1.p2
创建唯一的(p1)-[IS]-(p2);
可以类似地写为:

MATCH (p1:Person),(p2:Person {name:p1.name, email:p1.email})
WHERE p1 <> p2 
CREATE UNIQUE (p1)-[IS]-(p2);
MATCH(p1:Person),(p2:Person{name:p1.name,email:p1.email})
其中p1p2
创建唯一的(p1)-[IS]-(p2);
不用说,对于一个拥有大约100000个节点的数据库来说,这是一个非常慢的查询,特别是考虑到Neo4j不能并行处理单个查询

现在,我的问题是是否有更好的方法在Neo4j中运行此类查询。我至少有八个CPU内核专门用于Neo4j,只要不同的线程不会因锁定彼此所需的资源而相互占用

问题是我不知道Neo4j是如何构建其Cypher执行计划的。例如,假设我运行以下测试查询:

MATCH (p1:Person),(p2:Person {name:p1.name, email:p1.email})
WHERE p1 <> p2 
RETURN p1, p2
LIMIT 100;
MATCH(p1:Person),(p2:Person{name:p1.name,email:p1.email})
其中p1p2
返回p1,p2
上限为100;
尽管有LIMIT子句,Neo4j仍然需要相当长的时间才能提交结果,这让我想知道,即使对于这样一个有限的查询,Neo4j在考虑LIMIT语句之前是否会生成整个笛卡尔乘积表


我感谢任何帮助,无论是它解决了这个具体问题,还是让我了解了Neo4j通常如何构建Cypher执行计划(以及如何优化查询)。传统Lucene索引在这里有什么帮助吗?

您可以对
p1
进行标签扫描,然后对
p2
进行索引查找+比较:

请看这里:

cypher 2.1 
foreach (i in range(1,100000) | 
  create (:Person {name:"John Doe"+str(i % 10000),
                   email:"john"+str(i % 10000)+"@doe.com"}));
+-------------------+
| No data returned. |
+-------------------+
Nodes created: 100000
Properties set: 200000
Labels added: 100000
6543 ms
neo4j-sh (?)$ CREATE INDEX ON :Person(name);
+-------------------+
| No data returned. |
+-------------------+
Indexes added: 1
28 ms

neo4j-sh (?)$ schema
Indexes
  ON :Person(name)  ONLINE

neo4j-sh (?)$ 
match (p1:Person) with p1 
match (p2:Person {name:p1.name}) using index p2:Person(name) 
where p1<>p2 AND p2.email = p1.email 
return count(*);
+----------+
| count(*) |
+----------+
| 900000   |
+----------+
1 row
8206 ms

neo4j-sh (?)$ 
match (p1:Person) with p1 
match (p2:Person {name:p1.name}) using index p2:Person(name) 
where p1<>p2 AND p2.email = p1.email
merge (p1)-[:IS]-(p2) 
return count(*);

+----------+
| count(*) |
+----------+
| 900000   |
+----------+
1 row
Relationships created: 450000
40256 ms
cypher 2.1
foreach(i)范围为(1100000)|
创建(:Person{name:“johndoe”+str(i%10000),
电子邮件:“john”+str(i%10000)+“@doe.com”});
+-------------------+
|没有返回任何数据|
+-------------------+
创建的节点数:100000
物业数目:20万
新增标签:100000
6543毫秒
neo4j sh(?)$CREATE索引关于:个人(姓名);
+-------------------+
|没有返回任何数据|
+-------------------+
新增索引:1
28毫秒
neo4j-sh(?)$schema
索引
ON:联机人员(姓名)
neo4j上海(?)美元
将(p1:个人)与p1匹配
使用索引p2:Person(name)匹配(p2:Person{name:p1.name})
其中p1p2和p2.email=p1.email
返回计数(*);
+----------+
|计数(*)|
+----------+
| 900000   |
+----------+
一排
8206毫秒
neo4j上海(?)美元
将(p1:个人)与p1匹配
使用索引p2:Person(name)匹配(p2:Person{name:p1.name})
其中p1p2和p2.email=p1.email
合并(p1)-[:IS]-(p2)
返回计数(*);
+----------+
|计数(*)|
+----------+
| 900000   |
+----------+
一排
建立的关系:45万
40256毫秒

也许隐藏的未记录的特殊单词
profile
将为您提供有关性能的更多信息。假设它相当于pSQLs
explain analyze
。哇!如果你有时间,你会考虑详细介绍一下吗?这看起来非常重要和有用。