我试图使用以下Cypher在图中插入新的单词节点,更新这些节点上的属性,然后在新添加单词节点时创建与现有(字母)节点的新关系:
BEGIN MATCH (A:Letter {token:"A"}), (B:Letter {token:"B"}), (C:Letter {token:"C"}), (D:Letter {token:"D"}), (E:Letter {token:"E"}), (F:Letter {token:"F"}), (G:Letter {token:"G"}), (H:Letter {token:"H"}), (I:Letter {token:"I"}), (J:Letter {token:"J"}), (K:Letter {token:"K"}), (L:Letter {token:"L"}), (M:Letter {token:"M"}), (N:Letter {token:"N"}), (O:Letter {token:"O"}), (P:Letter {token:"P"}), (Q:Letter {token:"Q"}), (R:Letter {token:"R"}), (S:Letter {token:"S"}), (T:Letter {token:"T"}), (U:Letter {token:"U"}), (V:Letter {token:"V"}), (W:Letter {token:"W"}), (X:Letter {token:"X"}), (Y:Letter {token:"Y"}), (Z:Letter {token:"Z"}) // Create Words and link to proper letters MERGE (w1:Word {string:"WHOSE", length:5}) ON MATCH SET w1.s_enable1=TRUE ON CREATE SET w1.s_enable1=TRUE // create the letter->word relationships if necessary CREATE UNIQUE (w1) <-[:IN_WORD {position:1}]- (W) CREATE UNIQUE (w1) <-[:IN_WORD {position:2}]- (H) CREATE UNIQUE (w1) <-[:IN_WORD {position:3}]- (O) CREATE UNIQUE (w1) <-[:IN_WORD {position:4}]- (S) CREATE UNIQUE (w1) <-[:IN_WORD {position:5}]- (E) MERGE (w2:Word {string:"WHOSESOEVER", length:11}) ON MATCH SET w2.s_enable1=TRUE ON CREATE SET w2.s_enable1=TRUE CREATE UNIQUE (w2) <-[:IN_WORD {position:1}]- (W) CREATE UNIQUE (w2) <-[:IN_WORD {position:2}]- (H) CREATE UNIQUE (w2) <-[:IN_WORD {position:3}]- (O) CREATE UNIQUE (w2) <-[:IN_WORD {position:4}]- (S) CREATE UNIQUE (w2) <-[:IN_WORD {position:5}]- (E) CREATE UNIQUE (w2) <-[:IN_WORD {position:6}]- (S) CREATE UNIQUE (w2) <-[:IN_WORD {position:7}]- (O) CREATE UNIQUE (w2) <-[:IN_WORD {position:8}]- (E) CREATE UNIQUE (w2) <-[:IN_WORD {position:9}]- (V) CREATE UNIQUE (w2) <-[:IN_WORD {position:10}]- (E) CREATE UNIQUE (w2) <-[:IN_WORD {position:11}]- (R) ... N-2 more of these ...; COMMIT ... M-1 more transactions ...
我正在使用neo4j-shell来执行像这样的Cypher命令文件来添加新单词.大多数被合并的词已经存在于图中.只有一小部分是新的.
此代码通常有效,但:(a)运行速度非常慢(例如,当N = 50时,50秒/ 50字事务处理),以及(b)当需要创建新关系时(使用CREATE UNIQUE),事务处理缓慢到很多分钟偶尔会因“超出GC开销限制”错误而失败.
我也尝试使用MERGE代替CREATE UNIQUE.这通常类似地工作(非常慢),并且在运行多个事务之后最终因Java Heap内存错误而失败. (看起来像某种内存泄漏.)
任何关于我做错了什么和/或更好的方法来完成这项任务的见解将不胜感激.
更多信息
此图主要是提供一个动手原型,以帮助理解感兴趣的领域中的Neoj4特征和功能:语言结构,单词统计,对文字游戏有用的查询(填字游戏,拼字游戏,与朋友的话,刽子手……) .
所有属性都已编制索引(在neo4j.properties文件和CREATE INDEX ON命令中).
s_enable1表示要添加的单词列表的来源.在这种情况下,“enable1”字典(173,122字).初始图是使用“sowpods”字典(267,751字)创建的. s_前缀代表“source”.每次向图表添加新词典时,都会创建一个新属性,以指示哪些词(现有词和新词)与每个列表相关联. (例如,单词AA出现在sowpods和enable1字典中,因此AA字节点将s_sowpods和s_enable1属性都设置为TRUE.)
MERGE或CREATE UNIQUE似乎非常适合在添加新词典时不断更新图表.
sowpods build创建了大约250万(字母) – [:IN_WORD] – >(word)关系. enable1合并可能会创建另外500 K左右. (许多enable1单词很长,例如16 – 21个字母.)
操作系统是Windows 7.运行Java 7.51 x64. (最初运行的x32速度慢了2倍.)java -XshowSettings显示最大885.5 M堆.我相信数据库设置大多是默认设置. (哪些设置特别突出?)
您不必参数化第一部分,但需要一个索引/约束:create constraint on (l:Letter) assert l.token is unique; create constraint on (w:Word) assert l.string is unique;
要在shell上进行参数化,您可以:
export word=WHOSE MATCH (w:Word {string:{word}}) RETURN w;
不幸的是,Neo4j的拆分操作在空拆分字符串上还不起作用.
否则就会有这样的事情:将split({word},“”)作为字母
MERGE (w:Word {string:{word}, length:length({word})}) ON CREATE SET w.s_enable1=TRUE FOREACH (i in range(0,length({word})-1) | MERGE (l:Letter {token:substring({word},i,1)}) MERGE (l)-[:IN_WORD {position:i}]->(w) )
具体示例没有参数:
MERGE (w:Word {string:"STACKOVERFLOW", length:length("STACKOVERFLOW")}) ON CREATE SET w.s_enable1=TRUE FOREACH (i in range(0,length("STACKOVERFLOW")-1) | MERGE (l:Letter {token:substring("STACKOVERFLOW",i,1)}) MERGE (l)-[:IN_WORD {position:i}]->(w) )
你可以在这里试试:http://console.neo4j.org