<p align="center">
<img src="https://raw.githubusercontent.com/AutomataNexus/assets/main/AegisDB-logo.png" alt="AegisDB Logo" width="300">
</p>
# aegis-document
<p align="center">
<a href="https://opensource.org/licenses/Apache-2.0"><img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg" alt="License"></a>
<a href="https://www.rust-lang.org/"><img src="https://img.shields.io/badge/Rust-1.75%2B-orange.svg" alt="Rust"></a>
<img src="https://img.shields.io/badge/crate-0.2.6-green.svg" alt="Version">
<a href="../../README.md"><img src="https://img.shields.io/badge/part%20of-AegisDB-teal.svg" alt="AegisDB"></a>
</p>
Document store engine for the Aegis Database Platform.
## Overview
`aegis-document` provides a flexible document storage system with schema-optional JSON storage, full-text search, JSONPath queries, and schema validation. It's designed for semi-structured data that doesn't fit traditional relational models.
## Features
- **Schema-Optional** - Store any JSON document
- **Collections** - Logical grouping of documents
- **Full-Text Search** - Tokenized text search with ranking
- **JSONPath Queries** - Query nested document fields
- **Schema Validation** - Optional JSON Schema enforcement
- **Secondary Indexes** - Index any field for fast lookups
## Architecture
```
┌─────────────────────────────────────────────────┐
│ Document Engine │
├─────────────────────────────────────────────────┤
│ Query Processor │
│ ┌──────────┬──────────────┬─────────────────┐ │
│ │ JSONPath │ Full-Text │ Aggregation │ │
│ │ Parser │ Search │ Engine │ │
│ └──────────┴──────────────┴─────────────────┘ │
├─────────────────────────────────────────────────┤
│ Index Manager │
│ ┌──────────┬──────────────┬─────────────────┐ │
│ │ B-Tree │ Inverted │ Composite │ │
│ │ Index │ Index │ Index │ │
│ └──────────┴──────────────┴─────────────────┘ │
├─────────────────────────────────────────────────┤
│ Collection Manager │
│ (Schema Validation Layer) │
└─────────────────────────────────────────────────┘
```
## Modules
| `engine` | Main document engine |
| `collection` | Collection management |
| `query` | Document query execution |
| `index` | Secondary index management |
| `validation` | JSON Schema validation |
| `types` | Document type definitions |
## Usage
```toml
[dependencies]
aegis-document = { path = "../aegis-document" }
```
### Collections
```rust
use aegis_document::{DocumentEngine, Collection, CollectionOptions};
let engine = DocumentEngine::new(storage)?;
// Create a collection
engine.create_collection("users", CollectionOptions {
schema: None, // Schema-optional
indexes: vec![
Index::new("email").unique(true),
Index::new("name"),
],
})?;
// Create with schema validation
let schema = json!({
"type": "object",
"required": ["name", "email"],
"properties": {
"name": { "type": "string" },
"email": { "type": "string", "format": "email" },
"age": { "type": "integer", "minimum": 0 }
}
});
engine.create_collection("validated_users", CollectionOptions {
schema: Some(schema),
indexes: vec![],
})?;
```
### CRUD Operations
```rust
// Insert
let doc_id = engine.insert("users", json!({
"name": "Alice",
"email": "alice@example.com",
"tags": ["admin", "developer"],
"profile": {
"bio": "Software engineer",
"location": "San Francisco"
}
}))?;
// Find by ID
let doc = engine.find_by_id("users", &doc_id)?;
// Update
engine.update("users", &doc_id, json!({
"$set": { "profile.location": "New York" },
"$push": { "tags": "speaker" }
}))?;
// Delete
engine.delete("users", &doc_id)?;
```
### Querying
```rust
use aegis_document::query::{Query, Filter, Sort};
// Simple filter
let results = engine.find("users", Query {
filter: Filter::eq("email", "alice@example.com"),
..Default::default()
})?;
// Complex query
let results = engine.find("users", Query {
filter: Filter::and(vec![
Filter::gt("age", 21),
Filter::in_array("tags", vec!["developer", "admin"]),
Filter::regex("email", r".*@company\.com$"),
]),
sort: Sort::desc("created_at"),
skip: 0,
limit: 100,
projection: vec!["name", "email"],
})?;
// Nested field query (JSONPath)
let results = engine.find("users", Query {
filter: Filter::eq("profile.location", "San Francisco"),
..Default::default()
})?;
```
### Full-Text Search
```rust
use aegis_document::search::{TextSearch, SearchOptions};
// Create text index
engine.create_index("articles", Index::text(vec!["title", "content"]))?;
// Search
let results = engine.search("articles", TextSearch {
query: "rust database performance",
options: SearchOptions {
fuzzy: true,
highlight: true,
..Default::default()
},
})?;
for result in results {
println!("Score: {}, Title: {}", result.score, result.doc["title"]);
println!("Highlights: {:?}", result.highlights);
}
```
### Aggregation
```rust
use aegis_document::aggregation::{Pipeline, Stage};
let results = engine.aggregate("orders", Pipeline::new()
.match_stage(Filter::gte("created_at", "2024-01-01"))
.group(json!({
"_id": "$customer_id",
"total": { "$sum": "$amount" },
"count": { "$count": {} }
}))
.sort(Sort::desc("total"))
.limit(10)
)?;
```
### Update Operators
| `$set` | Set field value | `{"$set": {"name": "Bob"}}` |
| `$unset` | Remove field | `{"$unset": {"temp": ""}}` |
| `$inc` | Increment number | `{"$inc": {"count": 1}}` |
| `$push` | Add to array | `{"$push": {"tags": "new"}}` |
| `$pull` | Remove from array | `{"$pull": {"tags": "old"}}` |
| `$addToSet` | Add unique to array | `{"$addToSet": {"tags": "x"}}` |
## Configuration
```toml
[document]
default_collection_options = { max_documents = 1000000 }
text_search_language = "english"
[document.indexes]
auto_create = true
background_build = true
```
## Tests
```bash
cargo test -p aegis-document
```
**Test count:** 634 tests (workspace total)
## License
Apache-2.0