ArangoDB
NoSQLEn native multi-model database der kombinerer dokument-, graf- og nøgle-værdi-datamodeller i ét samlet forespørgselssprog.
Beskrivelse
ArangoDB er unik fordi den er en native multi-model database - i stedet for at vælge mellem dokument-, graf- eller nøgle-værdi-database, får du alle tre i én. Data gemmes som JSON-dokumenter i collections, men du kan også definere edges (forbindelser) mellem dokumenter for at lave property graphs. Dette betyder at du kan køre dokumentforespørgsler, graftravereringer og nøgle-værdi-opslag alt sammen i samme database med samme forespørgselssprog (AQL - ArangoDB Query Language). AQL ligner SQL men med udvidelser til graftravereringer og dokumentmanipulation. ArangoDB understøtter ACID-transaktioner, sekundære indekser, fuldtekstsøgning og geospatiale forespørgsler. Den kan deployes som single-server eller distribueret cluster med automatisk sharding og replikering. Foxx er microservices der kører direkte i databasen og giver dig mulighed for at skrive brugerdefinerede API'er i JavaScript. ArangoDB's multi-model tilgang er perfekt til komplekse domæner hvor data naturligt har både hierarkiske (dokumenter) og relationelle/netværks- (grafer) strukturer.
Features
- •Multi-model (dokument, graf, nøgle-værdi)
- •AQL-forespørgselssprog
- •ACID-transaktioner
- •Graftravereringer
- •Fuldtekstsøgning
- •Geospatiale forespørgsler
- •Foxx microservices
- •Distribueret clustering
Query Eksempel
// ArangoDB Query Language (AQL)
// 1. Opret collections
db._create("users");
db._createEdgeCollection("follows");
db._create("posts");
// 2. Indsæt documents
db.users.insert({
_key: "peter",
name: "Peter Hansen",
email: "peter@email.dk",
age: 30
});
db.users.insert({
_key: "maria",
name: "Maria Nielsen",
email: "maria@email.dk",
age: 28
});
// 3. Opret edge (graph relation)
db.follows.insert({
_from: "users/peter",
_to: "users/maria",
since: "2024-01-01"
});
// 4. Document query (like MongoDB)
FOR user IN users
FILTER user.age > 25
SORT user.name ASC
RETURN user
// 5. Graph traversal
FOR vertex, edge, path IN 1..3 OUTBOUND "users/peter" follows
RETURN {
user: vertex.name,
connection: edge,
depth: LENGTH(path.edges)
}
// 6. Find friends of friends
FOR user IN users
FILTER user._key == "peter"
FOR friend IN 2..2 OUTBOUND user follows
FILTER friend._key != user._key
RETURN DISTINCT friend.name
// 7. JOIN-like query
FOR post IN posts
LET author = FIRST(
FOR user IN users
FILTER user._key == post.authorId
RETURN user
)
RETURN {
title: post.title,
authorName: author.name
}
// 8. Aggregation
FOR user IN users
COLLECT ageGroup = FLOOR(user.age / 10) * 10
AGGREGATE count = LENGTH(1)
RETURN {
ageGroup: ageGroup,
count: count
}
// 9. Shortest path (graph algorithm)
FOR path IN OUTBOUND SHORTEST_PATH
"users/peter" TO "users/anders"
follows
RETURN path
// 10. Full-text search
FOR doc IN FULLTEXT(posts, "content", "database")
RETURN doc
// JavaScript Driver
const { Database, aql } = require('arangojs');
const db = new Database({
url: 'http://localhost:8529'
});
db.useDatabase('mydb');
db.useBasicAuth('root', 'password');
// Insert document
const users = db.collection('users');
await users.save({
_key: 'john',
name: 'John Doe',
email: 'john@email.com'
});
// Query with AQL
const cursor = await db.query(aql`
FOR user IN users
FILTER user.age > ${25}
RETURN user
`);
const result = await cursor.all();
console.log(result);
// Create edge
const follows = db.collection('follows');
await follows.save({
_from: 'users/peter',
_to: 'users/john',
since: new Date().toISOString()
});
// Graph traversal
const traversal = await db.query(aql`
FOR vertex IN 1..2 OUTBOUND ${'users/peter'} follows
RETURN vertex.name
`);
const friends = await traversal.all();
console.log(friends);
// Transaction
const trx = await db.beginTransaction({
write: ['users', 'posts']
});
try {
await trx.step(() =>
users.save({ name: 'Transaction User' })
);
await trx.step(() =>
db.collection('posts').save({ title: 'Post' })
);
await trx.commit();
} catch (err) {
await trx.abort();
}
// Named graph creation
const graph = db.graph('social_network');
await graph.create({
edgeDefinitions: [{
collection: 'follows',
from: ['users'],
to: ['users']
}]
});
// Foxx microservice (runs in database)
// manifest.json
{
"name": "my-api",
"version": "1.0.0",
"engines": {
"arangodb": "^3.0.0"
}
}
// index.js
const { context } = require('@arangodb/locals');
const router = context.createRouter();
router.get('/users', (req, res) => {
const users = db._query(
'FOR user IN users RETURN user'
).toArray();
res.json(users);
});Anvendelsesområder
- •Sociale netværk (brugere som dokumenter, forbindelser som grafer)
- •Anbefalingsmotorer
- •Svindelregistrering (grafanalyse)
- •Indholdsstyring med komplekse relationer
- •Videngrafer
Fordele
- ✓Én database for flere datamodeller
- ✓Kraftfulde graftravererings-kapabiliteter
- ✓Fleksibelt forespørgselssprog (AQL)
- ✓ACID-transaktioner på tværs af modeller
- ✓God ydeevne til både dokument- og grafforespørgsler
Ulemper
- ✗Mindre community end MongoDB eller Neo4j
- ✗Indlæringskurve for AQL
- ✗Overhead fra multi-model support
- ✗Færre managed cloud-tilbud
- ✗Dokumentation kan være fragmenteret
Bedst til
- →Sociale netværk med grafrelationer
- →Svindeldetekteringssystemer
- →Anbefalingsmotorer
- →Vidensstyringssystemer
- →Master data management
Ikke anbefalet til
- ⚠Simple CRUD-apps (overkill)
- ⚠Rene nøgle-værdi-arbejdsbyrder (brug Redis)
- ⚠Ren dokumentlagring (brug MongoDB)
- ⚠Rene grafer (brug Neo4j hvis kun graf)
- ⚠Teams uden grafdatabase-erfaring