2013-09-06 2 views
1

Я хотел бы знать, когда я смогу использовать свои собственные функции для создания вычисленного поля внутри Cypher.Расчетное поле с двумя коллекциями

Позвольте мне дать вам пример того, что я хочу:

START a=node(0) 
MATCH path=a-[rel*1..3]->b 
WITH path,b,extract(r in RELATIONSHIPS(path) : r.property1) as Collection1,extract(r in RELATIONSHIPS(path) : r.property2) as Collection2 
RETURN b,Collection1,Collection2 

Это даст мне что-то вроде:

Collection1 :    | Collection2 : 
[property1.1,property1.2] | [property2.1,property2.2] 
[property1.1]    | [property2.1] 
etc. 

Я хотел бы добавить поле с property1.1 * свойство2. 1 + свойство1.2 * property2.2 и некоторые другие функции (например, exp() и ln(), они правы в cypher2.0?). Можно ли сделать это сегодня с помощью cypher? Я знаю, что есть функция Reduce(), но как я могу сделать, чтобы пройти 2 коллекции одновременно?

Если бы я мог назвать свою собственную функцию, это помогло бы мне: что-то вроде «myFunction ([collection1], [collection2]) как myResult».

Заранее спасибо.

ответ

1

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

Например, следующий запрос возвращает сумму умножений свойств отношений p1 и p2,

START a=node(0) 
MATCH path=a-[rel*1..3]->b 
with last(relationships(path)) as r 
With r.p1 * r.p2 as mul 
Return sum(mul) 

Для этой конкретной задачи, так как свойства p1 и p2 из тех же отношений, есть на самом деле очень простой способ сделать это, как вы уже это сделали,

START a=node(0) 
MATCH path=a-[rel*1..3]->b 
With b, extract(r IN RELATIONSHIPS(path):r.p1 * r.p2) AS mulCol 
Return b, reduce((sum = 0, mul in mulCol: sum + mul) 
+0

Спасибо за ваш ответ. Я хочу это сделать, но для каждого отношения пути, а не только для последнего. – user2754635

+0

Например, если в пути есть 2 отношения, я хочу R.p11 * R.p12 + R.p21 * R.p22. Если есть 3 отношения, я хочу: R.p11 * R.p12 + R.p21 * R.p22 + R.p31 * R.p32 (с pab, a как число отношений и b как число имущество). Вы предлагаете следующее: R.p21 * R.p22 или R.p31 * R.p32. Как я отношусь к предыдущим отношениям? Они нужны мне. – user2754635

+0

Он извлекает последние отношения каждого возвращаемого пути.Поскольку каждый возвращаемый путь является последним возвращенным путем и новым отношением, он фактически извлекает все отношения между начальным узлом и конечным узлом. Например, для пути между a-> b-> c-> d запрос для «Match path = a- [rel: * 1..3] -> d" вернет пути, a-> b , a-> b-> c, a-> b-> c-> d. поэтому, получив последнюю связь каждого возвращаемого пути, вы фактически получаете все отношения от a до d, а не последние отношения a от d. –

0

Хорошо, я вижу. Давайте попробуем на консоли Neo4j:

CREATE (a { name:'a' }),(b { name:'b' }),(c { name:'c' }),(d { name:'d' }),(e { name:'e' }),(f { name:'f' }), a-[:RELATION { p1:1,p2:10 }]->b, a-[:RELATION { p1:2,p2:2 }]->d, b-[:RELATION { p1: 3,p2:5 }]->c, c-[:RELATION { p1: 2,p2:5 }]->e,d-[:RELATION { p1: 1,p2:6 }]->e, d-[:RELATION { p1: 4,p2:5 }]->f 

Давайте попробуем мой запрос:

START a=node:node_auto_index(name='a') 
MATCH path = a-[R*1..3]->b 
WITH b,extract(r IN RELATIONSHIPS(path):r.p1) AS collection_p1,extract(r IN RELATIONSHIPS(path):r.p2) AS collection_p2 
RETURN b,collection_p1,collection_p2 

Мне нужно это, но с еще одним полем: если есть 2 отношения в пути, мне нужно (collection_p1 [1 ] * collection_p2 [1] + collection_p1 [2] * collection_p2 [2]) как результат (конечно, для каждой строки).

Если я попробую ваш запрос, я не могу иметь сумму с предыдущими отношениями для каждого узла b.

START a=node:node_auto_index(name='a') 
MATCH path = a-[R*1..3]->b 
WITH last(relationships(path)) AS r ,b 
WITH r.p1 * r.p2 AS mul,b 
RETURN sum(mul),b 

Очевидно, что мне нужно иметь все узлы b с суммой умножения предыдущих соотношений. Идея? Еще раз спасибо.

+0

Что касается вашего следующего сообщения, я добавил еще один запрос, чтобы удовлетворить ваше требование о сумме каждого возвращаемого пути (или каждого конечного узла каждого пути). Кажется, мы передумали, на самом деле это намного проще, чем я думал. –

+0

О, я вижу. Я не думал делать p1 * p2 в «extract()». Я был очень близок. Конечно, то, что я хочу сделать, намного сложнее, чем умножение. Мне нужно будет установить Neo4j2.0 для некоторых математических функций. Мой последний вопрос: если я хочу разделить (p1 * p2) на позицию в коллекции (вы следуете за мной?) Например, если есть два отношения в пути, есть ли способ сделать ((collection_p1 [1] * collection_p2 [1])/1 + (collection_p1 [2] * collection_p2 [2])/2)? – user2754635

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