我有一个neo4j数据库,填充了~35K英语单词。我想在单词中给定位置的单个字母之间创建单词之间的关系。即(a) - (i)或(食物) - (傻瓜)或(猫) - (帽子)
对于单字母单词,cypher查询非常简单:
START n = node(),m = node(),其中n.name =〜'。'和m.name =〜'。'和 NOT(n.name = m.name)create(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范围(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(第一个IN范围(0,25)| START n =节点(),m =节点(),其中n.name =〜(字母[ {first}] +'。')和m.name =〜(alphabet [{first}] +'。')和NOT(n.name = m.name)create(n) - [:single_letter_change] - > (M)
答案 0 :(得分:3)
这可能会使用一些改进,但我认为它符合法案
// 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