получить вершины без связанных ребер в arangodb

Как лучше всего получить все вершины, у которых нет ребра в связанной коллекции edge_collection

Я пытался использовать следующий код, но он стал невероятно медленным, начиная с arangodb 2.8 (он был не очень быстрым в предыдущих версиях, но примерно в 10 раз быстрее, чем сейчас). Для размеров коллекции около 1000 ребер и около 3000 вершин требуется более 30 секунд.

FOR v IN vertex_collection  
    FILTER LENGTH( EDGES(edge_collection, v._id, "outbound"))==0
RETURN v._id

...

Обновить

...

Немного поигравшись, я пришел к следующему запросу

LET vIDs = (FOR v IN vertex_collection
            RETURN v._id)
LET vEdgesFrom = (FOR e IN edge_collection
                  FILTER e._from IN vIDs
                  RETURN e._from)
FOR v IN vertex_collection
    FILTER v._id IN MINUS(vIDs, vEdgesFrom)
RETURN v._id

Этот намного быстрее (около 0,05 с), но по-прежнему выглядит как некоторая работа (просто подумайте о нескольких коллекциях краев, которые нам нужно запросить).

Поэтому я все еще ищу лучший способ найти вершины, не имеющие ребер, в определенных коллекциях ребер.


person smurf    schedule 28.03.2016    source источник


Ответы (1)


Мое предложение будет аналогичным - лучше использовать объединения, чем особенности графика.

FOR oneEdge IN edges
LET vertices=(FOR oneVertex IN vertices
        FILTER oneEdge._from == oneVertex._id OR
               oneEdge._to == oneVertex._id
        RETURN 1)
FILTER LENGTH(vertices) < 2
RETURN {v: vertices, e: oneEdge}

найти все ребра, на которых один из _from и _to будет указывать на ноль, а затем удалить его.

Обратите внимание на RETURN 1, который уменьшит объем данных, передаваемых из внутреннего запроса.

person dothebart    schedule 29.03.2016
comment
Я предполагаю, что это должен быть oneEdge._to == oneVertex._id, верно? не всегда ли вершина равна 1 для этого запроса? - person smurf; 29.03.2016
comment
Да, конечно. фиксированный. - person dothebart; 29.03.2016