Как в ArangoDB AQL обновить поля каждого пройденного объекта, независимо от коллекции?

Для оператора UPDATE требуется имя коллекции. В графе я хочу пройти по ребру и обновить каждую посещенную вершину.

Примерно так: FOR v IN 1..50 INBOUND 'pmconfig / 6376876' pm_content OPTIONS {uniqueVertices: "global"} [обновить v.contentsChanged = true]

Поскольку вершины могут находиться в разных коллекциях, нужно ли мне разбивать объекты на списки для каждой коллекции?


person ggendel    schedule 09.11.2016    source источник


Ответы (1)


Обновление документов с использованием динамического (динамического) имени коллекции невозможно. Например, следующий запрос AQL не будет компилироваться:

FOR v IN 1..50 INBOUND 'pmconfig/6376876' pm_content
  UPDATE v WITH { contentsChanged : true } IN PARSE_IDENTIFIER(v._id).collection

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

Один из способов обхода - выполнить обход несколько раз, каждый раз с жестко запрограммированной коллекцией для обновления. Это по-прежнему требует знания названий коллекций заранее. Также могут возникнуть проблемы с согласованностью, если график меняется между ними:

FOR v IN 1..50 INBOUND 'pmconfig/6376876' pm_content
  FILTER PARSE_IDENTIFIER(v._id).collection == 'vertexCollection1'
  UPDATE v WITH { contentsChanged : true } IN vertexCollection1

FOR v IN 1..50 INBOUND 'pmconfig/6376876' pm_content
  FILTER PARSE_IDENTIFIER(v._id).collection == 'vertexCollection2'
  UPDATE v WITH { contentsChanged : true } IN vertexCollection2

...

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

FOR v IN 1..50 INBOUND 'pmconfig/6376876' pm_content
  LET parts = PARSE_IDENTIFIER(v._id) 
  COLLECT collection = parts.collection INTO keys = parts. key 
  RETURN { collection, keys }

Пример результата:

[    
  { 
     "collection" : "vertexCollection1", 
     "keys" : [ 
       "abc" 
     ]    
  },    
  { 
    "collection" : "vertexCollection2", 
    "keys" : [ 
      "xyz", 
      "ddd" 
    ]    
  }  
]

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

person stj    schedule 10.11.2016
comment
Спасибо. Я просто хотел получить второе мнение о том, что мне сначала нужно составить список для каждой коллекции. - person ggendel; 10.11.2016