【问题标题】:Programmatically creating relationships between words in Neo4j using Cypher使用 Cypher 在 Neo4j 中以编程方式创建单词之间的关系
【发布时间】:2014-11-29 22:42:21
【问题描述】:

我有一个包含约 35K 英语单词的 neo4j 数据库。我想在单词的给定位置创建由单个字母不同的单词之间的关系。即(a)--(i) or (food)--(fool) or (cat)--(hat)

对于单字母单词,密码查询非常简单:

开始 n=node(), m=node() 其中 n.name =~ '.'和 m.name =~ '.'和 NOT (n.name = m.name) 创建 (n)-[:single_letter_change]->(m)

不幸的是,为多字母单词建立关系并不是那么简单。我知道可以创建一个集合,如下所示:

有 ['A','B','C','D','E','F','G','H','I','J','K','L',' M','N','O','P','Q','R','S','T','U','V','W','X','Y' ,'Z']· 9 个 AS 字母

我知道可以通过以下方式迭代一个范围:

FOREACH (i IN range(0,25))

但我放在一起的任何东西似乎都丑陋、凌乱且在语法上无效。我相信在 Cypher 中有一种优雅的方法可以使用集合函数来完成此任务,但我花了几天时间试图弄清楚,现在是时候寻求帮助了。

关于如何做到这一点的想法?我很乐意发布我尝试过的一些(无效)密码查询,但我担心它们可能会混淆问题。

编辑: 这是我尝试为两个字母单词的首字母设置关系的示例,但我认为它可能不正确,我知道它不会运行:

WITH ['A','B','C','D','E','F','G','H','I','J','K',' L','M','N','O','P','Q','R','S','T','U','V','W','X' ,'Y','Z'] AS 字母表 FOREACH (first IN range(0,25) | START n=node(), m=node() where n.name =~ (alphabet[ {first}] + '.') 和 m.name =~ (alphabet[{first}] + '.') 和 NOT (n.name = m.name) 创建 (n)-[:single_letter_change]->( m)

【问题讨论】:

  • 在编程语言中可能更容易完成,如果 split(word,"") 有效,那么您可以将单词转换为数组并从那里开始工作。也许将单词的字母作为数组存储在节点上有助于简化任务?
  • Michael,我可能对过早的优化感到内疚,但我希望 Cypher 能够比通过编程语言 API 更有效地完成此任务。我目前在我的 Macbook Air 上运行 neo4j,所以效率很重要。
  • 迈克尔,split(word, "") 不就是这样做的吗? (例如 split("Michael", "") 产生 [M,i,c,h,a,e,l]

标签: neo4j cypher


【解决方案1】:

这可能需要一些改进,但我认为它符合要求

// match all the words, start with ones that are three characters long
match (w:Word)
where length(w.name) = 3
// create a collection the length of the matched word
with range(0,length(w.name)-1) as w_len, w
unwind w_len as idx
// iterate through the word and replace one letter at a time
// making a regex pattern
with "(?i)" + left(w.name,idx) + '.' + right(w.name,length(w.name)-idx-1) as pattern, w, w_len
// match the pattern against 3 letter words
// that are not the word
// not already like the word
// and match the pattern
match (new_word:Word)
where not (new_word = w) 
and not((new_word)-[:LIKE]-(w))
and length(new_word.name) = length(w_len)
and new_word.name =~ pattern
// create the relationship
create (new_word)-[:LIKE]->(w)
return new_word, w

【讨论】:

  • 非常感谢戴夫。这是一个巨大的帮助。 cmets特别受欢迎。
  • np - 是一个有趣的问题;让我们想启动我自己的 35k 英文单词图!我认为就像迈克尔所说的那样,在程序结构中使用类似的东西以获得最佳的灵活性和控制可能会有很多好处。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-27
  • 1970-01-01
相关资源
最近更新 更多