В этой главе мы обсудим, как запрашивать данные с помощью AQL. Мы уже обсуждали в наших предыдущих главах, что ArangoDB разработал свой собственный язык запросов и называется он AQL.
Давайте теперь начнем взаимодействовать с AQL. Как показано на рисунке ниже, в веб-интерфейсе нажмите вкладку AQL Editor, расположенную в верхней части панели навигации. Появится пустой редактор запросов.
При необходимости вы можете переключиться на редактор из представления результатов и наоборот, щелкнув вкладки «Запрос» или «Результат» в верхнем правом углу, как показано на рисунке ниже —
Среди прочего, редактор имеет подсветку синтаксиса, функции отмены и повтора и сохранение запросов. Подробную справку можно найти в официальной документации. Мы выделим несколько основных и часто используемых функций редактора запросов AQL.
Основы AQL
В AQL запрос представляет конечный результат, который должен быть достигнут, но не процесс, посредством которого должен быть достигнут конечный результат. Эта функция широко известна как декларативное свойство языка. Кроме того, AQL может также запрашивать и изменять данные, и, таким образом, сложные запросы могут создаваться путем объединения обоих процессов.
Обратите внимание, что AQL полностью совместим с ACID. Чтение или изменение запросов либо завершатся полностью, либо не завершатся вовсе. Даже чтение данных документа будет заканчиваться последовательной единицей данных.
Мы добавляем две новые песни в коллекцию песен, которую мы уже создали. Вместо того, чтобы печатать, вы можете скопировать следующий запрос и вставить его в редактор 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
Нажмите кнопку «Выполнить» в левом нижнем углу.
Он напишет два новых документа в сборник песен .
Этот запрос описывает, как работает цикл FOR в AQL; он перебирает список документов в кодировке JSON, выполняя кодированные операции с каждым из документов в коллекции. Различными операциями могут быть создание новых структур, фильтрация, выбор документов, изменение или вставка документов в базу данных (см. Мгновенный пример). По сути, AQL может эффективно выполнять операции CRUD.
Чтобы найти все песни в нашей базе данных, давайте еще раз выполним следующий запрос, эквивалентный песням SELECT * FROM базы данных типа SQL (поскольку редактор запоминает последний запрос, нажмите кнопку * New * , чтобы очистить редактор ) —
FOR song IN songs RETURN song
Результирующий набор покажет список песен, сохраненных в коллекции песен, как показано на скриншоте ниже.
Такие операции, как FILTER, SORT и LIMIT, могут быть добавлены в тело цикла For, чтобы сузить и упорядочить результат.
FOR song IN songs FILTER song.Year > 1940 RETURN song
Приведенный выше запрос даст песни, созданные после 1940 года, на вкладке «Результат» (см. Изображение ниже).
Ключ документа используется в этом примере, но любой другой атрибут также может использоваться в качестве эквивалента для фильтрации. Поскольку ключ документа гарантированно будет уникальным, этому фильтру будет соответствовать не более одного документа. Для других атрибутов это может быть не так. Чтобы вернуть подмножество активных пользователей (определяемое атрибутом с именем status), отсортированное по имени в порядке возрастания, мы используем следующий синтаксис:
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
Теперь мы можем проверить, что все наши песни имеют новую длину атрибута —
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, повторяющейся сначала во внутреннем цикле, по всей записи композитора, а затем по всем связанным песням, создавая новый документ, содержащий атрибут song_with_composer_key вместо атрибута песни .
Здесь идет запрос —
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 song 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, но на этот раз он приводит к операции Join, добавляя имя связанного композитора (выбирая с помощью `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" } ]