У меня есть база данных диаграммы OrientDB с узлами, соединенными последовательно со ссылкой типа NEXT
. (В моих данных несколько отдельных рядов, и ни один узел не имеет более одной входящей и одной исходящей ссылки «NEXT»). Все узлы имеют свойство «имя». Я хотел бы найти все последовательности имени, которые происходят при прохождении путей от начала до конца.агрегирование данных пути в orientdb
I.e. чтобы получить одну последовательность имен, начните с узла, у которого нет входящей NEXT-ссылки, следуйте по ссылкам NEXT, пока не достигнете узла без исходящих «NEXT» ссылок и соберите в списке все имена узлов, которые у вас есть прошло.
например. суб-граф формы (Bob)-[NEXT]->(Sharon)-[NEXT]->(Carl)
должен дать список ["Bob", "Sharon", "Carl"]
Для уточнения, здесь Cypher (Neo4j) запрос, который получает мне все возможные списки.
match (start) -[:NEXT*]-> (end),
p = shortestPath(start-[:NEXT*]-> end)
where not()-[:NEXT]->(start) and not (end)-[:NEXT]->()
return extract(s in nodes(p) | s.name) as path
Однако, мне нужно сделать это в OrientDB, который не использует Cypher.
Я хотел бы знать, возможно ли это в OrientDB, и если да, то проще ли это на языке SQL или Gremlin.
Как второстепенный вопрос, в идеале я бы не хотел возвращать все списки имен, потому что меня действительно волнует, как часто происходит каждый список. Поэтому вместо этого я хочу вернуть уникальные списки с тем, как часто этот конкретный список был найден. Можно ли это сделать в OrientDB, или мне нужно будет восстановить все данные пути из OrientDB, как указано выше, и выполнить агрегацию в другом месте?
UPDATE
Я создал некоторые данные примера здесь, чтобы соответствовать заявление моего первоначального вопроса.
create database plocal:people
create class Person extends V
create property Person.name string
create property Person.age float
create property Person.ident integer
insert into Person(name,age,ident) VALUES ("Bob", 30.5, 1)
insert into Person(name,age,ident) VALUES ("Bob", 30.5, 2)
insert into Person(name,age,ident) VALUES ("Carol", 20.3, 3)
insert into Person(name,age,ident) VALUES ("Carol", 19, 4)
insert into Person(name,age,ident) VALUES ("Laura", 75, 5)
insert into Person(name,age,ident) VALUES ("Laura", 60.5, 6)
insert into Person(name,age,ident) VALUES ("Laura", 46, 7)
insert into Person(name,age,ident) VALUES ("Mike", 16.3, 8)
insert into Person(name,age,ident) VALUES ("David", 86, 9)
insert into Person(name,age,ident) VALUES ("Alice", 5, 10)
insert into Person(name,age,ident) VALUES ("Nigel", 69, 11)
insert into Person(name,age,ident) VALUES ("Carol", 60, 12)
insert into Person(name,age,ident) VALUES ("Mike", 16.3, 13)
insert into Person(name,age,ident) VALUES ("Alice", 5, 14)
insert into Person(name,age,ident) VALUES ("Mike", 16.3, 15)
create class NEXT extends E
create edge NEXT from (select from Person where ident = 1) to (select from Person where ident = 3)
create edge NEXT from (select from Person where ident = 2) to (select from Person where ident = 4)
create edge NEXT from (select from Person where ident = 8) to (select from Person where ident = 12)
create edge NEXT from (select from Person where ident = 5) to (select from Person where ident = 15)
create edge NEXT from (select from Person where ident = 15) to (select from Person where ident = 14)
create edge NEXT from (select from Person where ident = 7) to (select from Person where ident = 13)
create edge NEXT from (select from Person where ident = 13) to (select from Person where ident = 10)
Это должно дать мне следующий окончательный результат
- 2 из
["Bob", "Carol"]
- 2 из
["Laura", "Mike", "Alice"]
- 1 из
["Laura"]
- 1 из
["Mike", "Carol"]
- 1 из
["David"]
- 1 из
["Nigel"]
Вот что я получаю, используя предложения neRok
Во-первых, выбрать все начальные узлы - это работает, как ожидалось
orientdb {db=people}> select from Person where in_NEXT is null
----+------+------+-----+----+-----+--------
# |@RID |@CLASS|name |age |ident|out_NEXT
----+------+------+-----+----+-----+--------
0 |#11:0 |Person|Bob |30.5|1 |[#12:0]
1 |#11:1 |Person|Bob |30.5|2 |[#12:1]
2 |#11:4 |Person|Laura|75.0|5 |[#12:3]
3 |#11:5 |Person|Laura|60.5|6 |null
4 |#11:6 |Person|Laura|46.0|7 |[#12:5]
5 |#11:7 |Person|Mike |16.3|8 |[#12:2]
6 |#11:8 |Person|David|86.0|9 |null
7 |#11:10|Person|Nigel|69.0|11 |null
----+------+------+-----+----+-----+--------
Теперь, если я пытаюсь получить массивы имен, полученные путем прохождения от этих узлов
select $series.name from (select from Person where in_NEXT is null) let $series = (traverse out('NEXT') from $current)
----+------+-------
# |@CLASS|$series
----+------+-------
0 |null |[0]
1 |null |[0]
2 |null |[0]
3 |null |[0]
4 |null |[0]
5 |null |[0]
6 |null |[0]
7 |null |[0]
----+------+-------
Я думаю, это означает, что он не получает результатов от обхода или не может создать массив имен?
Заключительный шаг агрегации обрабатывает все эти строки, как то же самое:
orientdb {db=people}> select series, sum(1) as number from (select $series.name as series from (select from Person where in_NEXT is null) let $series = (traverse out('NEXT') from $current)) group by series
----+------+------+------
# |@CLASS|series|number
----+------+------+------
0 |null |[0] |8
----+------+------+------
, так что я не получаю результат я хотел.
Я думаю, что проблема заключается в извлечении массива имен из обхода? Единственный запрос обхода находит ожидаемый обход, но я не могу понять, как манипулировать данными, чтобы предоставить массив имен из этого обхода.
Вот пример обхода с одного узла: orientdb {дб = человек}> траверсировать из ('Вперед') из (выберите из Person, где идент = 7)
----+------+------+-----+----+-----+--------+-------
# |@RID |@CLASS|name |age |ident|out_NEXT|in_NEXT
----+------+------+-----+----+-----+--------+-------
0 |#11:6 |Person|Laura|46.0|7 |[#12:5] |null
1 |#11:12|Person|Mike |16.3|13 |[#12:6] |[#12:5]
2 |#11:9 |Person|Alice|5.0 |10 |null |[#12:6]
----+------+------+-----+----+-----+--------+-------
глупый вопрос: Почему бы просто не использовать Neo4j, если вы уже решили проблему там? –
Не глупый вопрос, всегда стоит проверить :) По причинам, которые я не хочу здесь описывать, я не могу использовать Neo4j для этого проекта, но вместо этого должен использовать OrientDB. Очевидно, для меня в этом конкретном случае Neo4j будет более удобным, но он недоступен. – arbie
@arbie сообщите мне, могу ли я вообще помочь (возможно, это проблема лицензирования, которую можно смягчить и т. Д.). -орький мальчик. e-mail:. на neotechnology.com –