2014-11-29 2 views
3

У меня есть база данных neo4j, заполненная словами ~ 35K на английском языке. Я хочу создать отношения между словами, которые отличаются одной буквой в данной позиции в слове. то есть (а) - (я) или (питание) - (дурак) или (кот) - (шапка)Программирующее создание связей между словами в Neo4j с использованием Cypher

Для отдельных букв слова, то высчитывать запрос довольно прост:

START n = node (), m = node () где n.name = ~ '.' и m.name = ~ '.' и NOT (n.name = m.name) создают (п) - [: single_letter_change] -> (м)

Построение отношений для multiletter слов не так просто, к сожалению. Я знаю, что можно создать коллекцию, как в:

С [ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' , 'Я', 'J', 'K', 'L', 'М', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',» U», 'V', 'W' 'X', 'Y', 'Z'] · 9 как буквы

и я знаю, можно перебирать диапазон с:

FOREACH (i IN range (0,25))

Но все, что я собрал, кажется уродливым, грязным и синтаксически недействительным. Я уверен, что есть элегантный способ сделать это в Cypher, используя функции коллекции, но я потратил пару дней, пытаясь понять это, и настало время обратиться за помощью.

Идеи, как это сделать? Я буду рад опубликовать некоторые (недопустимые) запросы cypher, которые я пробовал, но я боюсь, что они могут просто путать проблему.

EDIT: Вот пример того, что я пытался установить отношения для первых букв двух слов письма, но я думаю, что это может быть от марки, и я знаю, что это не будет работать:

WITH ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L' , 'М', 'N', 'O', 'Р', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',» Y ',' Z '] AS алфавит FOREACH (первый интервал IN (0,25) | START n = node (), m = node () где n.name = ~ (алфавит [{first}] +'. ') и m.name = ~ (алфавит [{first}] +'. ') и NOT (n.name = m.name) create (n) - [: single_letter_change] -> (m)

+0

Вероятно, проще сделать на языке программирования, было бы здорово, если бы раскол (слово, «») работал тогда вы могли бы преобразовать слово в массив и работа оттуда. Возможно, сохранение букв слова в виде массива на узле поможет упростить задачу? –

+0

Майкл, вероятно, я виноват в преждевременной оптимизации, но я надеюсь, что Cypher может выполнить это более эффективно, чем это можно сделать с помощью API языка программирования. В настоящее время я запускаю neo4j на моем Macbook Air, поэтому эффективность важна. –

+0

Майкл, не разделяется (слово, "") делает именно это? (например, split («Michael», «») дает [M, i, c, h, a, e, l] –

ответ

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 
+0

Большое спасибо Дэйву. Это огромная помощь. Комментарии приветствуются. –

+0

np - was интересная проблема: мы хотим, чтобы мой собственный 35k английский граф слов!Я думаю, что Майкл говорит, что, вероятно, многое можно будет получить, используя что-то подобное в структуре программы для оптимальной гибкости и контроля. –

Смежные вопросы