## π€ AI Methods
### πΉ ann
Perform an Aproximate Nearest Neighbors search
```rust
client.ann(serde_json::json!({
"key": "user:123", //or vector: [f32]
"top_k" : 5 //return the top 5 neighbors
})).await?;
```
### πΉ query
Make a query to the db in natural language
```rust
client.query(serde_json::json!({
"query": "Insert the vertex user:2 to user:123",
"backend": "openai:gpt-4o-mini"
})).await?;
```
### πΉ ask
Ask questions about your data
```rust
client.ask(serde_json::json!({
"question": "How many users over 25 do we have",
"backend": "openai:gpt-4o-mini"
})).await?;
```
### πΉ set_middleware
Make the LLM analyze incoming querys and decide if it must reject them, accept them or modify them.
```rust
client.set_middleware(serde_json::json!({
"operation": "SET",
"middleware": "Only accept requests that have the amount field specified, and convert its value to dollars"
})).await?;
```
### Notes on AI
In the functions where `backend` must be specified this parameter must passed with the following format: `openai:model-name` or `ollama:model-name`. If you're using OpenAI as your backend you must specify the `OPENAI_API_KEY` env variable. If backend isn't specified `openai:gpt-4o-mini` will be used as default.
The trained embedding model will be at the root of your db in a folder called `satori_semantic_model`.
You can train your embedding model manually whenever you want to but Satori will automatically fine-tune your model with any new updates and use this updated model for all emebedding operations.
## Analytics
### πΉ get_operations
Returns all operations executed on the database.
### πΉ get_access_frequency
Returns the number of times an object has been queried or accessed.
```rust
client.get_access_frequency(serde_json::json!({
"key": "user:1",
})).await?;
```
---
# π¦ Schema Struct (Data Model) β Rust
You can use the `Schema` struct to model your data in an object-oriented way:
```rust
use satori_client::{Satori, Schema};
let satori = Satori::connect("username", "password", "ws://localhost:1234").await.unwrap();
let mut user = Schema::new(&satori, "user", Some("my_key".into()), Some(json!({ "name": "Anna" })));
user.set().await.unwrap();
```
It includes useful methods such as:
- `set`, `delete`, `encrypt`, `decrypt`, `set_vertex`, `get_vertex`, `delete_vertex`, `dfs`
- Array methods: `push`, `pop`, `splice`, `remove`
## π Complete Example
```rust
use satori_client::Satori;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let client = Satori::connect(
"username".to_string(),
"password".to_string(),
"ws://localhost:8000".to_string()
).await?;
client.set(serde_json::json!({
"key": "user:1",
"data": { "name": "Carlos", "age": 30 },
"type": "user"
})).await?;
client.set_notify("user:1", |data| {
println!("Real-time update: {:?}", data);
}).await?;
Ok(())
}
```
---
## π§ Key Concepts
- **key**: Unique identifier of the object.
- **type**: Object type (e.g., 'user').
- **field_array**: Advanced filters for bulk operations.
- **notifications**: Subscription to real-time changes.
- **vertices**: Graph-like relationships between objects.
---
## Responses
All responses obbey the following pattern:
```ts
{
data: any //the requested data if any
message: string //status message
type: string //SUCCESS || ERROR
}
```
AI responses obbey a different patern:
## ask
```ts
{
response: string //response to the question
}
```
## query
```ts
{
result: string //response from the operation made in the db
status: string //status
}
```
## ann
```ts
{
results: array //response from the operation made in the db
}
```
## π¬ Questions or Suggestions?
Feel free to open an issue or contribute! With β€οΈ from the Satori team.
---