我正在玩一个neo4j数据库,该数据库包含〜275,000个与其包含的字母相关联的英文单词。我在Windows上运行Neo4j 2.0.1社区版。
尝试使用以下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),事务处理缓慢到很多分钟,偶尔会因错误而失败&#34;超出GC开销限制&#34;。
我也尝试使用MERGE代替CREATE UNIQUE。这通常类似地工作(非常慢),并且在运行多个事务之后最终因Java Heap内存错误而失败。 (看起来像某种内存泄漏。)
对于我做错了什么和/或更好的方法来完成这项任务的任何见解将不胜感激。
更多信息
此图主要是提供一个动手原型,以帮助理解感兴趣的领域中的Neoj4特征和功能:语言结构,单词统计,对文字游戏有用的查询(填字游戏,拼字游戏,与朋友的话,刽子手,。 ..)。
所有属性都已编入索引(在neo4j.properties文件和CREATE INDEX ON命令中)。
s_enable1表示要添加的单词列表的来源。在这种情况下,&#34; enable1&#34;字典(173,122字)。初始图表是使用&#34; sowpods&#34;字典(267,751字)。 s_前缀代表&#34; source。&#34;每次向图表添加新词典时,都会创建一个新属性,以指示哪些词(现有词和新词)与每个列表相关联。 (例如,单词AA出现在sowpods和enable1字典中,因此AA字节点将s_sowpods和s_enable1属性都设置为TRUE。)
MERGE或CREATE UNIQUE似乎非常适合在添加新词典时不断更新图表。
sowpods build创建了大约250万(字母) - [:IN_WORD] - &gt;(word)关系。 enable1合并可能会创建另外500 K左右。 (许多enable1单词很长,例如16 - 21个字母。)
操作系统是Windows 7.运行Java 7.51 x64。 (最初运行的x32速度慢了2倍。)java -XshowSettings显示最大885.5 M堆。我相信数据库设置大多是默认设置。 (哪些设置特别突出?)
答案 0 :(得分:4)
您不必参与第一部分的参数化,但您需要一个索引/约束:
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},&#34;&#34;)作为字母
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
答案 1 :(得分:2)
以下是我的经验和提示:
tmpfs
性能也比HDD + Linux缓冲区/缓存好得多。MERGE
。超过50 MERGE
秒,它会变慢。在Cypher查询中大约500-1000 MERGE
s,Neo4j抛出StackOverflowError
。number_of_CPUs - 2
个线程来运行Neo4j事务,为主线程留下1个线程,为Neo4j自己的事务写入留下另一个线程。这导致i7-3770K上所有8个逻辑核心的CPU利用率达到约95%。ConcurrentHashMap
,但ImmutableMap
更好),但请确保相应地调整堆大小。即使你的堆进入虚拟内存,它仍然比Neo4j的事务性刷新更快。MATCH
代替MERGE
。对于内存中索引,这意味着即使无法使用ImmutableMap
,即使使用多线程,也可以使用HashMap
而不是ConcurrentHashMap
。类似帖子: