Запрос данных с помощью AQL
В этой главе мы обсудим, как запрашивать данные с помощью AQL. Мы уже обсуждали в наших предыдущих главах, что ArangoDB разработал свой собственный язык запросов и что он называется AQL.
Давайте теперь начнем взаимодействовать с AQL. Как показано на изображении ниже, в веб-интерфейсе нажмите кнопкуAQL Editorвкладка находится в верхней части панели навигации. Появится пустой редактор запросов.
При необходимости вы можете переключиться в редактор из представления результатов и наоборот, щелкнув вкладку «Запрос» или «Результат» в верхнем правом углу, как показано на изображении ниже -
Помимо прочего, в редакторе есть подсветка синтаксиса, функция отмены / повтора и сохранение запроса. Более подробную информацию можно найти в официальной документации. Мы выделим несколько основных и часто используемых функций редактора запросов AQL.
Основы AQL
В AQL запрос представляет конечный результат, который должен быть достигнут, но не процесс, посредством которого должен быть достигнут конечный результат. Эта функция обычно известна как декларативное свойство языка. Более того, AQL может запрашивать, а также изменять данные, и, таким образом, сложные запросы могут быть созданы путем объединения обоих процессов.
Обратите внимание, что AQL полностью соответствует требованиям ACID. Чтение или изменение запросов либо завершатся полностью, либо не завершатся вовсе. Даже чтение данных документа завершится последовательной единицей данных.
Добавляем два новых songsв уже созданный сборник песен. Вместо того, чтобы печатать, вы можете скопировать следующий запрос и вставить его в редактор AQL -
FOR song IN [
{
title: "Air-Minded Executive", lyricist: "Johnny Mercer",
composer: "Bernie Hanighen", Year: 1940, _key: "Air-Minded"
},
{
title: "All Mucked Up", lyricist: "Johnny Mercer", composer:
"Andre Previn", Year: 1974, _key: "All_Mucked"
}
]
INSERT song IN songs
Нажмите кнопку «Выполнить» в левом нижнем углу.
Он запишет два новых документа в songs коллекция.
Этот запрос описывает, как цикл FOR работает в AQL; он перебирает список закодированных документов JSON, выполняя закодированные операции с каждым из документов в коллекции. Различные операции могут включать создание новых структур, фильтрацию, выбор документов, изменение или вставку документов в базу данных (см. Мгновенный пример). По сути, AQL может эффективно выполнять операции CRUD.
Чтобы найти все песни в нашей базе данных, давайте еще раз выполним следующий запрос, эквивалентный SELECT * FROM songs базы данных типа SQL (поскольку редактор запоминает последний запрос, нажмите *New* кнопка очистки редактора) -
FOR song IN songs
RETURN song
В наборе результатов отобразится список песен, сохраненных в songs коллекция, как показано на скриншоте ниже.
Операции вроде FILTER, SORT а также LIMIT можно добавить в For loop тело, чтобы сузить и упорядочить результат.
FOR song IN songs
FILTER song.Year > 1940
RETURN song
Вышеупомянутый запрос предоставит песни, созданные после 1940 года, на вкладке «Результат» (см. Изображение ниже).
В этом примере используется ключ документа, но любой другой атрибут также может использоваться как эквивалент для фильтрации. Поскольку ключ документа гарантированно уникален, этому фильтру будет соответствовать не более одного документа. Для других атрибутов это может быть не так. Чтобы вернуть подмножество активных пользователей (определяемое атрибутом, называемым статусом), отсортированное по имени в порядке возрастания, мы используем следующий синтаксис:
FOR song IN songs
FILTER song.Year > 1940
SORT song.composer
RETURN song
LIMIT 2
Мы сознательно включили этот пример. Здесь мы видим сообщение об ошибке синтаксиса запроса, выделенное красным цветом с помощью AQL. Этот синтаксис выделяет ошибки и помогает при отладке запросов, как показано на снимке экрана ниже.
Давайте теперь запустим правильный запрос (обратите внимание на исправление) -
FOR song IN songs
FILTER song.Year > 1940
SORT song.composer
LIMIT 2
RETURN song
Сложный запрос в AQL
AQL снабжен множеством функций для всех поддерживаемых типов данных. Назначение переменной в запросе позволяет создавать очень сложные вложенные конструкции. Таким образом, операции с интенсивным использованием данных перемещаются ближе к данным на сервере, чем к клиенту (например, браузеру). Чтобы понять это, давайте сначала добавим произвольную продолжительность (длину) к песням.
Начнем с первой функции, то есть с функции обновления -
UPDATE { _key: "All_Mucked" }
WITH { length: 180 }
IN songs
Мы видим, что один документ был написан, как показано на скриншоте выше.
Давайте теперь обновим и другие документы (песни).
UPDATE { _key: "Affable_Balding" }
WITH { length: 200 }
IN songs
Теперь мы можем проверить, что все наши песни имеют новый атрибут length -
FOR song IN songs
RETURN song
Выход
[
{
"_key": "Air-Minded",
"_id": "songs/Air-Minded",
"_rev": "_VkC5lbS---",
"title": "Air-Minded Executive",
"lyricist": "Johnny Mercer",
"composer": "Bernie Hanighen",
"Year": 1940,
"length": 210
},
{
"_key": "Affable_Balding",
"_id": "songs/Affable_Balding",
"_rev": "_VkC4eM2---",
"title": "Affable Balding Me",
"lyricist": "Johnny Mercer",
"composer": "Robert Emmett Dolan",
"Year": 1950,
"length": 200
},
{
"_key": "All_Mucked",
"_id": "songs/All_Mucked",
"_rev": "_Vjah9Pu---",
"title": "All Mucked Up",
"lyricist": "Johnny Mercer",
"composer": "Andre Previn",
"Year": 1974,
"length": 180
},
{
"_key": "Accentchuate_The",
"_id": "songs/Accentchuate_The",
"_rev": "_VkC3WzW---",
"title": "Accentchuate The Politics",
"lyricist": "Johnny Mercer",
"composer": "Harold Arlen",
"Year": 1944,
"length": 190
}
]
Чтобы проиллюстрировать использование других ключевых слов AQL, таких как LET, FILTER, SORT и т. Д., Теперь мы форматируем продолжительность песни в mm:ss формат.
Запрос
FOR song IN songs
FILTER song.length > 150
LET seconds = song.length % 60
LET minutes = FLOOR(song.length / 60)
SORT song.composer
RETURN
{
Title: song.title,
Composer: song.composer,
Duration: CONCAT_SEPARATOR(':',minutes, seconds)
}
На этот раз мы вернем название песни вместе с продолжительностью. ВReturn Функция позволяет вам создать новый объект JSON, который будет возвращаться для каждого входного документа.
Теперь мы поговорим о функции «Объединения» в базе данных AQL.
Начнем с создания коллекции composer_dob. Далее мы создадим четыре документа с гипотетической датой рождения композиторов, выполнив следующий запрос в поле запроса -
FOR dob IN [
{composer: "Bernie Hanighen", Year: 1909}
,
{composer: "Robert Emmett Dolan", Year: 1922}
,
{composer: "Andre Previn", Year: 1943}
,
{composer: "Harold Arlen", Year: 1910}
]
INSERT dob in composer_dob
Чтобы подчеркнуть сходство с SQL, мы представляем вложенный запрос цикла FOR в AQL, ведущий к операции REPLACE, итерации сначала во внутреннем цикле, по всем dob композиторов, а затем по всем связанным песням, создавая новый документ, содержащий атрибут song_with_composer_key вместо song атрибут.
Вот вопрос -
FOR s IN songs
FOR c IN composer_dob
FILTER s.composer == c.composer
LET song_with_composer_key = MERGE(
UNSET(s, 'composer'),
{composer_key:c._key}
)
REPLACE s with song_with_composer_key IN songs
Давайте теперь запустим запрос FOR song IN songs RETURN song еще раз, чтобы увидеть, как изменилась коллекция песен.
Выход
[
{
"_key": "Air-Minded",
"_id": "songs/Air-Minded",
"_rev": "_Vk8kFoK---",
"Year": 1940,
"composer_key": "5501",
"length": 210,
"lyricist": "Johnny Mercer",
"title": "Air-Minded Executive"
},
{
"_key": "Affable_Balding",
"_id": "songs/Affable_Balding",
"_rev": "_Vk8kFoK--_",
"Year": 1950,
"composer_key": "5505",
"length": 200,
"lyricist": "Johnny Mercer",
"title": "Affable Balding Me"
},
{
"_key": "All_Mucked",
"_id": "songs/All_Mucked",
"_rev": "_Vk8kFoK--A",
"Year": 1974,
"composer_key": "5507",
"length": 180,
"lyricist": "Johnny Mercer",
"title": "All Mucked Up"
},
{
"_key": "Accentchuate_The",
"_id": "songs/Accentchuate_The",
"_rev": "_Vk8kFoK--B",
"Year": 1944,
"composer_key": "5509",
"length": 190,
"lyricist": "Johnny Mercer",
"title": "Accentchuate The Politics"
}
]
Вышеупомянутый запрос завершает процесс миграции данных, добавляя composer_key к каждой песне.
Теперь следующий запрос снова является вложенным запросом цикла FOR, но на этот раз он ведет к операции соединения, добавляя имя связанного композитора (выбор с помощью composer_key) к каждой песне -
FOR s IN songs
FOR c IN composer_dob
FILTER c._key == s.composer_key
RETURN MERGE(s,
{ composer: c.composer }
)
Выход
[
{
"Year": 1940,
"_id": "songs/Air-Minded",
"_key": "Air-Minded",
"_rev": "_Vk8kFoK---",
"composer_key": "5501",
"length": 210,
"lyricist": "Johnny Mercer",
"title": "Air-Minded Executive",
"composer": "Bernie Hanighen"
},
{
"Year": 1950,
"_id": "songs/Affable_Balding",
"_key": "Affable_Balding",
"_rev": "_Vk8kFoK--_",
"composer_key": "5505",
"length": 200,
"lyricist": "Johnny Mercer",
"title": "Affable Balding Me",
"composer": "Robert Emmett Dolan"
},
{
"Year": 1974,
"_id": "songs/All_Mucked",
"_key": "All_Mucked",
"_rev": "_Vk8kFoK--A",
"composer_key": "5507",
"length": 180,
"lyricist": "Johnny Mercer",
"title": "All Mucked Up",
"composer": "Andre Previn"
},
{
"Year": 1944,
"_id": "songs/Accentchuate_The",
"_key": "Accentchuate_The",
"_rev": "_Vk8kFoK--B",
"composer_key": "5509",
"length": 190,
"lyricist": "Johnny Mercer",
"title": "Accentchuate The Politics",
"composer": "Harold Arlen"
}
]