Множественная сортировка в ArangoDB

Мое веб-приложение должно отображать несколько отсортированных списков атрибутов документа в виде графика. Это hours, cycles и age.

У меня есть запрос AQL, который красиво проходит по графику и получает все данные, необходимые моему приложению, за 2 мс. Я очень впечатлен! Но мне нужно отсортировать по каждому графику. В настоящее время запрос возвращает массив объектов json, которые содержат все три атрибута и идентификатор, для которого они применяются. Потрясающие. Запрос также очень легко сортируется по одному из атрибутов.

Моя проблема: мне нужно иметь отсортированный список из всех трех, и я бы предпочел не запрашивать базу данных три раза, поскольку все данные находятся в тех же документах, которые вернул мой обход.

Я хотел бы вернуть три отсортированных массива объектов json: один, содержащий hours и идентификатор, один, содержащий cycles и идентификатор, и один, содержащий age и идентификатор. Таким образом, мои графики могут легко отображать все три графика без сортировки на стороне клиента.

Сами HTTP-запросы отнимают много времени, хотя база данных очень быстрая, поэтому я хотел бы получить все три сразу, поскольку сами данные малы.

Мой текущий запрос - это простой обход графа:

for v, e, p in outbound startNode graph 'myGraph'
    filters & definitions...
    sort v.hours desc
    return {"hours": v.hours, "cycles": v.cycles, "age": v.age, "id": v.id}

Есть ли простой способ сказать Аранго, чтобы он вернул мне эту структуру?

{
 [
  {
   "id": 47,
   "hours": 123
  },
  {
   "id": 23,
   "hours": 105
  }...
 ],
 [
  {
   "id": 47,
   "cycles": 18
  },
  {
   "id": 23,
   "cycles": 5
  }...
 ],
 [
  {
   "id": 47,
   "age": 4.2
  },
  {
   "id": 23,
   "age": 0.9
  }
 ]
}

Хотя обход выполняется быстро, я бы предпочел, чтобы мне не приходилось повторять обход графа три раза, если это возможно.


person Nate Gardner    schedule 22.08.2016    source источник


Ответы (2)


Мое решение:

let data = (for v, e, p in outbound startNode graph 'myGraph'
                filters & definitions...
                return {"hours": v.hours, "cycles": v.cycles, "age": v.age, "id": v.id})
let byHours = (for thing in data
                   sort thing.hours desc
                   return {"hours": thing.hours, "id": thing.id})
let byCycles = (for thing in data
                    sort thing.cycles desc
                    return {"cycles": thing.cycles, "id": thing.id})
let byAge = (for thing in data
                 sort thing.age desc
                 return {"age": thing.age, "id": thing.id})
return {"hours": byHours, "cycles": byCycles, "age": byAge}
person Nate Gardner    schedule 23.08.2016
comment
Вы можете сортировать по часам для data, поэтому у вас нет обхода и 3 подзапроса для сортировки, а только один обход с сортировкой плюс 2 подзапроса для разного порядка сортировки. Хотя, полагаю, это не имеет большого значения. - person CodeManX; 23.08.2016
comment
Я думаю, что это будет быстрее, поскольку порядок сортировки по часам, циклам и возрасту очень похож. Сортировка в произвольном порядке три раза, похоже, займет больше времени. - person Nate Gardner; 24.08.2016
comment
Ладно, я тоже так пробовал. То, как я указал выше, занимает 3 мс и предварительная сортировка по часам, затем циклы сортировки и возраста на основе предварительно отсортированного списка занимают 5 мс. Я этого не ожидал, но с этой оптимизацией сортировка на самом деле происходит медленнее. - person Nate Gardner; 24.08.2016

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

LET nodes = (
  FOR v, e, p IN OUTBOUND startNode GRAPH 'myGraph'
  FILTER ...
  RETURN v
)
RETURN {
  hours: (
    FOR n IN nodes
    SORT n.hours DESC
    RETURN KEEP(n, ['hours', 'id'])
  ),
  cycles: (
    FOR n IN nodes
    SORT n.cycles DESC
    RETURN KEEP(n, ['cycles', 'id'])
  ),
  age: (
    FOR n IN nodes
    SORT n.age DESC
    RETURN KEEP(n, ['age', 'id'])
  )
}

Это приведет к обходу графика только один раз, но трижды отсортирует результат.

person Alan Plum    schedule 19.10.2016