如何优化Neo4J Cypher查询?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何优化Neo4J Cypher查询?相关的知识,希望对你有一定的参考价值。
我有一个将文本转换为网络的应用程序,因此当添加一个句子时,每个单词都是一个节点,并且每个单词的共同出现就是它们之间的连接。此信息对于更好地理解以下问题非常重要。
为了将每个句子添加到Neo4J数据库中,我在Neo4J中有以下Cypher查询,根据我的数据结构,首先匹配添加节点的user
,然后匹配发表声明的context
(或列表) ,将其链接到用户,将语句链接到用户和上下文,然后在添加的每个节点(具有属性),语句,创建它们的位置以及创建它们的上下文(列表)之间创建连接。
问题是这个查询比句子本身长约100,所以如果文本是400Bytes,查询大约是40K。当我想添加一个长文本时,Neo4J开始变得很慢。
因此 - 我的问题:我将如何以最佳方式优化此查询?你建议做一组交易吗?
例如,我可以将每个长查询切成多个部分,然后同时发送一些事务以节省时间吗?
我说的是一个大约100K长,可能更长的文本。这意味着总请求大约为10Mb。
MATCH (u:User {uid: "6e228580-1cb3-11e8-8271-891867c15336"})
MERGE (c_list:Context {name:"list",by:"6e228580-1cb3-11e8-8271-891867c15336",
uid:"0b4fa320-1dfd-11e8-802e-b5cbdf950c47"})
ON CREATE SET c_list.timestamp="15199833288930000"
MERGE (c_list)-[:BY{timestamp:"15199833288930000"}]->(u)
CREATE (s:Statement {name:"#apple #orange #fruit",
text:"apples and oranges are fruits",
uid:"0b56a800-1dfd-11e8-802e-b5cbdf950c47", timestamp:"15199833288930000"})
CREATE (s)-[:BY {context:"0b4fa320-1dfd-11e8-802e-b5cbdf950c47",
timestamp:"15199833288930000"}]->(u)
CREATE (s)-[:IN {user:"6e228580-1cb3-11e8-8271-891867c15336",
timestamp:"15199833288930000"}]->(c_list)
MERGE (cc_apple:Concept {name:"apple"})
ON CREATE SET cc_apple.timestamp="15199833288930000", cc_apple.uid="0b56a801-1dfd-11e8-802e-b5cbdf950c47"
MERGE (cc_orange:Concept {name:"orange"})
ON CREATE SET cc_orange.timestamp="15199833288930000", cc_orange.uid="0b56cf10-1dfd-11e8-802e-b5cbdf950c47"
MERGE (cc_fruit:Concept {name:"fruit"})
ON CREATE SET cc_fruit.timestamp="15199833288930002", cc_fruit.uid="0b56cf13-1dfd-11e8-802e-b5cbdf950c47"
CREATE (cc_apple)-[:BY {context:"0b4fa320-1dfd-11e8-802e-b5cbdf950c47",timestamp:"15199833288930000",
statement:"0b56a800-1dfd-11e8-802e-b5cbdf950c47"}]->(u)
CREATE (cc_apple)-[:OF {context:"0b4fa320-1dfd-11e8-802e-b5cbdf950c47",user:"6e228580-1cb3-11e8-8271-891867c15336",timestamp:"15199833288930000"}]->(s)
CREATE (cc_apple)-[:AT {user:"6e228580-1cb3-11e8-8271-891867c15336",timestamp:"15199833288930000",
context:"0b4fa320-1dfd-11e8-802e-b5cbdf950c47",statement:"0b56a800-1dfd-11e8-802e-b5cbdf950c47"}]->(c_list)
CREATE (cc_apple)-[:TO {context:"0b4fa320-1dfd-11e8-802e-b5cbdf950c47",
statement:"0b56a800-1dfd-11e8-802e-b5cbdf950c47",user:"6e228580-1cb3-11e8-8271-891867c15336",
timestamp:"15199833288930000",uid:"0b56cf11-1dfd-11e8-802e-b5cbdf950c47",gapscan:"2",weight:"3"}]->(cc_orange)
CREATE (cc_orange)-[:BY {context:"0b4fa320-1dfd-11e8-802e-b5cbdf950c47",timestamp:"15199833288930000",statement:"0b56a800-1dfd-11e8-802e-b5cbdf950c47"}]->(u)
CREATE (cc_orange)-[:OF {context:"0b4fa320-1dfd-11e8-802e-b5cbdf950c47",user:"6e228580-1cb3-11e8-8271-891867c15336",timestamp:"15199833288930000"}]->(s)
CREATE (cc_orange)-[:AT {user:"6e228580-1cb3-11e8-8271-891867c15336",timestamp:"15199833288930000",
context:"0b4fa320-1dfd-11e8-802e-b5cbdf950c47",statement:"0b56a800-1dfd-11e8-802e-b5cbdf950c47"}]->(c_list)
CREATE (cc_orange)-[:TO {context:"0b4fa320-1dfd-11e8-802e-b5cbdf950c47",
statement:"0b56a800-1dfd-11e8-802e-b5cbdf950c47",user:"6e228580-1cb3-11e8-8271-891867c15336",
timestamp:"15199833288930002",uid:"0b56cf14-1dfd-11e8-802e-b5cbdf950c47",gapscan:"2",weight:"3"}]->(cc_fruit)
CREATE (cc_apple)-[:TO {context:"0b4fa320-1dfd-11e8-802e-b5cbdf950c47",
statement:"0b56a800-1dfd-11e8-802e-b5cbdf950c47",user:"6e228580-1cb3-11e8-8271-891867c15336",
timestamp:"15199833288930002",uid:"0b56cf16-1dfd-11e8-802e-b5cbdf950c47",gapscan:"4",weight:"2"}]->(cc_fruit)
CREATE (cc_fruit)-[:BY {context:"0b4fa320-1dfd-11e8-802e-b5cbdf950c47",
timestamp:"15199833288930002",statement:"0b56a800-1dfd-11e8-802e-b5cbdf950c47"}]->(u)
CREATE (cc_fruit)-[:OF {context:"0b4fa320-1dfd-11e8-802e-b5cbdf950c47",user:"6e228580-1cb3-11e8-8271-891867c15336",timestamp:"15199833288930002"}]->(s)
CREATE (cc_fruit)-[:AT {user:"6e228580-1cb3-11e8-8271-891867c15336",
timestamp:"15199833288930002",context:"0b4fa320-1dfd-11e8-802e-b5cbdf950c47",
statement:"0b56a800-1dfd-11e8-802e-b5cbdf950c47"}]->(c_list)
RETURN s.uid;
答案
1)使用输入parameters
:
var params = {
userId: "6e228580-1cb3-11e8-8271-891867c15336",
contextName: "list",
time: "15199833288930000",
statementName: "#apple #orange #fruit",
statementText: "apples and oranges are fruits",
concepts: ["apple", "orange", "fruit"],
conceptsRelations: [
{from: "apple", to: "orange", gapscan: 2, weight: 3},
{from: "orange", to: "fruit", gapscan: 2, weight: 3},
{from: "apple", to: "fruit", gapscan: 4, weight: 2}
]
}
session.run(cypherQuery, params).then...
2)使用APOC library
在数据库端生成唯一标识符:apoc.create.uuid()
3)使用循环(foreach和unwind)进行重复操作:
MATCH (u:User {uid: $userId})
MERGE (c_list:Context {name: $contextName, by: $userId})
ON CREATE SET c_list.timestamp = $time,
c_list.uid = apoc.create.uuid()
MERGE (c_list)-[:BY{timestamp: $time}]->(u)
CREATE (s:Statement {name: $statementName,
text: $statementText, uid:apoc.create.uuid(), timestamp: $time})
CREATE (s)-[:BY {context: c_list.uid, timestamp: $time}]->(u)
CREATE (s)-[:IN {user: u.uid, timestamp: $time}]->(c_list)
FOREACH (conceptName in $concepts|
MERGE (concept:Concept {name: conceptName})
ON CREATE SET concept.timestamp = $time,
concept.uid = apoc.create.uuid()
CREATE (concept)-[:BY {context: c_list.uid, timestamp: $time, statement: s.uid}]->(u)
CREATE (concept)-[:OF {context: c_list.uid, user: u.uid, timestamp: $time}]->(s)
CREATE (concept)-[:AT {user: u.uid, timestamp: $time,
context: c_list.uid, statement: s.uid}]->(c_list)
)
WITH u, c_list, s
UNWIND $conceptsRelations as conceptsRelation
MATCH (c_from:Concept {name: conceptsRelation.from})
MATCH (c_to:Concept {name: conceptsRelation.to})
CREATE (c_from)-[:TO {context: c_list.uid, statement: s.uid, user: u.uid,
timestamp: $time, uid: apoc.create.uuid(),
gapscan: conceptsRelation.gapscan,
weight: conceptsRelation.weight}]->(c_to)
RETURN distinct s.uid;
以上是关于如何优化Neo4J Cypher查询?的主要内容,如果未能解决你的问题,请参考以下文章