ArangoDB – мультимодельная БД с возможностью хранения данных как графов, документов и ключ-значение.
Взял материал с бесплатного курса на udemy и Outline курса
Стоит обратить внимание на training center и доки
Можно работать по HTTP API, фронт, терминал и библиотеку питона
Концепция
ArangoDB хранит объекты в json документах с поддержкой обращения по ключу, за которое отвечает специальное поле _key.
Есть два типа коллекций:
Стандартная. Хранилище документов json, специальные поля _key, _rev, _id. key можно задать самому. Последние два создаются автоматически.
_key – ключ объекта в коллекции. ВАЖНО: case sensitive
_rev – используется для внутренних алгоритмов
_id – используется для связи с другими коллекциями. Имеет формат {collection name}/_key
Edge. Специальные коллекции, хранящие в себе объекты связи между объектами стандартных коллекций. Имею два дополнительных поля _to, _from, в которых хранятся _id объектов, которых edge объект связывает
Есть фронт для работы с БД.
Есть утилита для подключения и работы с БД в терминале.
CRUD
Используется свой язык AQL.
Создание
Создание объектов. Добавляем какие хотим значения, при попытке добавления объекта с существующем _key будет ошибка.
Синтаксис:
INSERT {key: value} INTO collection [RETURN NEW]
RETURN NEW позволяет вернуть добавленный объект
Чтение
Чтение объектов
Синтаксис:
RETURN DOCUMENT(_id) – вернёт объект по _id
RETURN DOCUMENT(collection_name, [_key, ...]) – вернёт список объектов из коллекции по ключам
Обновление
Обновление объектов
Синтаксис:
UPDATE {_key: "value"} WITH {newVal: 1234} IN collection
Удаление
Синтаксис:
REMOVE {_key: "value"} IN collection
FOR
Синтаксис: FOR variableName IN expression
Итерируется по массиву объектов
Поддерживает вложенность
Особенности в работе с графами
Update нескольких документов:
FOR doc in ["key1", "key2"]:
UPDATE doc WITH {newVal: 1234} IN collection
Фичи
Индексы
Можем ускорить операции индексируя ключи объектов. По дефолту ключи _key, _id, _to и _from индексируются.
Есть 7 типов индексов:
Primary – автоматически генерируемый для покрытия _key и _id
Edge – автоматически генерируемый для покрытия _from и _to
Hash – создаётся вручную и покрывает нужные поля
Skiplist
Persistent
Geo
Fulltext
При создании индекса запускается процесс индексации и рассчитывается коэффициент Selectivity, который отвечает за приоритет при выборе индекса для работы запроса
Фильтрация
Синтаксис: FILTER condition
В одном запросе может быть несколько фильтров.
Например, хотим получить вип полёты:
FOR flight IN flights
FILTER flight.type == "VIP"
RETURN flight
Без индексации на большом объеме данных может выполнятся сотни миллисекунд.
Объединение
Работают за счёт вложенных циклов.
Например, хотим получить все полёты В аэропорты Далласа.
FOR airport IN airports
FILTER airport.city == "Dallas"
FOR flight in flights
FILTER flight._to == airport._id
RETURN {"airport": airport.name, "flight": flight.FlightNum}
Группировка
Синтаксис:
COLLECT variableName = expression options
Например, хотим собрать все штаты аэропортов:
FOR airport IN airports COLLECT state = airport.state RETURN state
Или посчитать сколько аэропортов в каждом штате и отсортировать по убыванию
FOR airport IN airports
COLLECT state = airport.state WITH COUNT INTO total
SORT total DESC
RETURN {"state": state, "total":total}
Графы
Связь объектов коллекций происходит с помощью коллекций связи (edge collections). В стандартных коллекциях у каждого объекта есть поле _id, которое содержит информацию о коллекции объекта и ключу объекта в этой коллекции.
Объекты коллекции edge имеют поля _to и _from, которые содержат _id объектов, которые они связывают. Объекты этой коллекции также json, то есть мы можем добавлять в них любую информацию, описывая связь между объектами.
Синтаксис:
FOR vertex, edge, path IN 1..1 OUTBOUND _id GRAPH edge_collection RETURN path
FOR vertex, edge, path IN 1..1 OUTBOUND _id edge_collection RETURN path – анонимный граф, потому что не указали GRAPH. Можем использовать несколько edge коллекций
vertex – текущая вершина, обязательна
edge – текущее ребро
path – содержит два списка: всех вершин и всех рёбер между запрошенными вершинами
IN задаёт глубину поиска, min..max
OUTBOUND/INBOUND/ANY задаёт движение поиск. Смотрит на ключи _from, _to соответсвенно.
_id содержит строку с id объекта. Может быть самим объектом
GRAPH указывает на коллекцию edge типа, по которой будем искать связи
Например, мы хотим прямой рейс из Сан-Франциско на Гавайи:
FOR airport in airports
FILTER airport.city == "San Francisco"
FOR v, e, p IN 1..1 OUTBOUND airport flights
FILTER v._id == "airports/KOA"
RETURN p
Или хотим рейс с пересадками из Сан-Франциско на Гавайи:
FOR airport in airports
FILTER airport.city == "San Francisco"
FOR v, e, p IN 2..3 OUTBOUND airport flights
FILTER v._id == "airports/KOA"
RETURN p
Нужно быть осторожными с сложными запросами на графах, так как они могут выполняться долго. Для оптимизации стоит использовать индексы и ограничивать сложность запросов
Поиск
Используется встроенный движок ArangoSearch, поддерживающий все модели данных БД.
Включает в себя полнотекстовый поиск, нечёткий поиск благодаря индексации, обработку текста и рангирование поиска
ArangoSearch состоит из двух компонентов: движок поиска и движок интеграций.
Движок поиска – это analyzers, views и links
Analyzers позволяют сконфигурировать правила, по которым текст будет обработан. Есть набор встроенных анализаторов на популярные языки. Можно создавать свои анализаторы.
Views специальные объекты, которые хранят данные о результатах аналитики/индексации
Links объекты связывающие коллекции и views правилами аналитики полей. То есть мы задаём связь с коллекцией и какими анализаторами обрабатывать поля её объектов.
Движок интеграции – слой предоставления данных.
Search – препроцессор, работает над views, может видеть только индексированные поля, то есть такие, которые мы описали в links.
Rank позволяет получить вес результатов, в соответсвии с запросом на поиск. Также можем ставить свои веса для частей поиска.
Пример поиска слова "ninja" в описании фильмa:
FOR doc in view
SEARCH ANALYZER(d.description == "ninja", "text_en")
RETURN doc