javascript - 如何对 Neo4J : optimize Cypher or improve the Javascript/Node. Js 构造函数进行高效快速的长查询?

标签 javascript node.js neo4j cypher

我有一个 Node.Js 应用程序的任务,该应用程序将文本转换为网络(单词是 Node ,它们的同时出现 - 具有多个权重 - 是网络图中的连接),我需要在其中保存所有数据存入 Neo4J 数据库。

正如你可以想象的,虽然它适用于简短的语句,但一旦它们变得更长,例如 5000 个单词,其中词汇量约为 500 个唯一单词,我就需要保存大量 Node 和大量连接到数据库。

目前,我有一个这样的请求:

MATCH (u:User {uid: "15229100-b20e-11e3-80d3-6150cb20a1b9"}) 
MERGE (c_0:Context {name:"st",by:u.uid,uid:"d0342000-1c4c-11e9-b9f6-e1addb3b0fa7"}) 
ON CREATE SET c_0.timestamp="15479451847980000" MERGE (c_0)-[:BY{timestamp:"15479451847980000"}]->(u) 
CREATE (s:Statement {name:"#apple #orange #fruit", text:"apples and oranges are fruits", uid:"d0390200-1c4c-11e9-b9f6-e1addb3b0fa7", timestamp:"15479451847980000"}) 
CREATE (s)-[:BY {context:c_0.uid,timestamp:s.timestamp}]->(u) 
CREATE (s)-[:IN {user:u.id,timestamp:s.timestamp}]->(c_0) 
MERGE (cc_0:Concept {name:"apple"}) 
ON CREATE SET cc_0.uid="d0390201-1c4c-11e9-b9f6-e1addb3b0fa7" 
MERGE (cc_1:Concept {name:"orange"}) 
ON CREATE SET cc_1.uid="d0390204-1c4c-11e9-b9f6-e1addb3b0fa7" 
MERGE (cc_2:Concept {name:"fruit"}) 
ON CREATE SET cc_2.uid="d0390207-1c4c-11e9-b9f6-e1addb3b0fa7" 
CREATE (cc_0)-[:BY {context:c_0.uid,timestamp:s.timestamp,statement:s.uid}]->(u) 
CREATE (cc_0)-[:OF {context:c_0.uid,user:u.uid,timestamp:s.timestamp}]->(s)  
CREATE (cc_0)-[:AT {user:u.uid,timestamp:s.timestamp,context:c_0.uid,statement:s.uid}]->(c_0) 
CREATE (cc_0)-[:TO {context:c_0.uid,statement:s.uid,user:u.uid,timestamp:"15479451847980000",uid:"d0390205-1c4c-11e9-b9f6-e1addb3b0fa7",gapscan:"2",weight:"3"}]->(cc_1) 
CREATE (cc_1)-[:BY {context:c_0.uid,timestamp:"15479451847980000",statement:s.uid}]->(u) CREATE (cc_1)-[:OF {context:c_0.uid,user:u.uid,timestamp:"15479451847980000"}]->(s) 
CREATE (cc_1)-[:AT {user:u.uid,timestamp:"15479451847980000",context:c_0.uid,statement:s.uid}]->(c_0) 
CREATE (cc_1)-[:TO {context:c_0.uid,statement:s.uid,user:u.uid,timestamp:"15479451847980002",uid:"d0390208-1c4c-11e9-b9f6-e1addb3b0fa7",gapscan:"2",weight:"3"}]->(cc_2) 
CREATE (cc_0)-[:TO {context:c_0.uid,statement:s.uid,user:u.uid,timestamp:"15479451847980002",uid:"d039020a-1c4c-11e9-b9f6-e1addb3b0fa7",gapscan:"4",weight:"2"}]->(cc_2) 
CREATE (cc_2)-[:BY {context:c_0.uid,timestamp:"15479451847980002",statement:s.uid}]->(u) 
CREATE (cc_2)-[:OF {context:c_0.uid,user:u.uid,timestamp:"15479451847980002"}]->(s) 
CREATE (cc_2)-[:AT {user:u.uid,timestamp:"15479451847980002",context:c_0.uid,statement:s.uid}]->(c_0)  
RETURN s.uid;

对于这一段文字:

apples and oranges are fruits

如您所见,结果比必要的要长得多。

目前,对于较长的文本,我只是将 Cypher 请求分成较小的 block ,然后将它们在事务中提供给数据库。

但是,这仍然相当慢 - 每 KB 文本大约需要一秒。

我的查询是用 Javascript/Node.Js 构建的:https://github.com/noduslabs/infranodus/blob/master/lib/db/neo4j.js#L116

基本逻辑是:

如果有一句话苹果和橙子是水果

  1. 我需要为每个 Node 创建一个 Node ,将它们链接到创建它们的用户以及语句本身和 graph(一个图可以有多个语句)。

  2. 然后我需要在这些具有不同权重的单词之间创建连接:

    [苹果 - 橙子]

    [橙子 - 水果]

    [苹果 - 水果]

...

对于 300 个单词的序列,什么是有效的方法?

我知道我可以使用 FOREACH 循环和 params 以及 apoc 来生成 UID,但这真的会让查询更高效吗与使用 JavaScript 构建相比?我不太明白如何在我的集合上执行此操作,以及它是否有助于解决对于 300 多个单词序列来说太重的问题。

这些做法有帮助吗?我如何将它们实现到此 Cypher 查询中?

最佳答案

我认为问题更多的是庞大的语句,必须对其进行解析、编译和计划。

最好使用批量参数作为输入,并让 cypher 进行迭代, 参见

https://medium.com/neo4j/5-tips-tricks-for-fast-batched-updates-of-graph-structures-with-neo4j-and-cypher-73c7f693c8cc

您需要所有 UUID 做什么?

您是否为 MERGE 操作设置了索引和约束?

关于javascript - 如何对 Neo4J : optimize Cypher or improve the Javascript/Node. Js 构造函数进行高效快速的长查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54272622/

相关文章:

javascript - onload 添加类 animate.css

javascript - Node.js 中 ES6 模块的内联导入

database - CYPHER 2.3 在 Neo4j 查询中的性能

javascript - jQuery 点击向下滑动特定的 div

javascript - 如何获得具有特定属性的嵌套对象的计数?

javascript - node.js:如何在 forEach 循环中使用异步调用实现路由方法?

java - 在 java 中创建 Neo4j 关系

neo4j - Cypher 查询以查找具有 3 个关系的节点

javascript - 需要帮助来优化单选按钮的代码

node.js - 无法在 Postman 中发送 POST 请求 "/api/user/cart/addtocart%0A"