-
Notifications
You must be signed in to change notification settings - Fork 0
Configuration
LottaDB configuration is split into two levels: catalog-level (shared infrastructure) and database-level (type registrations and handlers).
Storage is configured using Use*() extension methods. Each method sets up all three storage concerns -- table client, blob client, and Lucene directory -- in one call.
dotnet add package LottaDB
var catalog = new LottaCatalog("myapp", catalog => catalog.UseAzure(connectionString));Configures TableServiceClient and BlobServiceClient from the connection string. Lucene uses AzureDirectory (index persisted to blob storage).
A shorthand connection string constructor is also available:
// Equivalent to UseAzure(connectionString)
var catalog = new LottaCatalog("myapp", connectionString);dotnet add package LottaDB.Memory
var catalog = new LottaCatalog("myapp", catalog => catalog.UseMemory());Configures MemoryTableServiceClient, MemoryBlobServiceClient, and RAMDirectory. All data lives in memory -- fast, no I/O, no cleanup. Ideal for unit tests.
dotnet add package LottaDB.FileSystem
var catalog = new LottaCatalog("myapp", catalog => catalog.UseFileSystem(@"C:\data\myapp"));Configures FileTableServiceClient, FileBlobServiceClient, and FSDirectory. Data is persisted as files on disk under the specified root path. Good for local development and debugging test failures.
dotnet add package LottaDB.SQLite
var catalog = new LottaCatalog("myapp", catalog => catalog.UseSQLite(@"C:\data"));Configures SqliteTableServiceClient, SqliteBlobServiceClient, and FSDirectory. Table and blob data stored in a SQLite database file; Lucene index stored on disk. Good balance of speed and persistence.
The Use*() methods can be combined with other catalog-level settings in the same configure callback:
var catalog = new LottaCatalog("myapp", catalog =>
{
catalog.UseAzure(connectionString);
catalog.Analyzer = new StandardAnalyzer(LuceneVersion.LUCENE_48);
catalog.EmbeddingGenerator = myEmbeddingGenerator;
});These are internal and can only be set through the constructor's configure callback:
| Property | Type | Default | Description |
|---|---|---|---|
Analyzer |
Analyzer |
EnglishAnalyzer |
Lucene analyzer for text tokenization. Shared across all databases in the catalog. |
EmbeddingGenerator |
IEmbeddingGenerator<string, Embedding<float>>? |
null (disabled) |
Embedding generator for Vector Search. |
Configure databases via GetDatabaseAsync:
var db = await catalog.GetDatabaseAsync("social", config =>
{
config.Store<Actor>();
config.Store<Note>();
config.On<Note>(async (note, kind, db, ct) =>
{
// trigger logic
});
});Register a type with default settings (AutoQueryable on, ULID key auto-generated):
config.Store<Actor>();With fluent configuration:
config.Store<Note>(s =>
{
s.SetKey(n => n.NoteId);
s.AddQueryable(n => n.AuthorId).NotAnalyzed();
s.AddQueryable(n => n.Content);
s.DefaultSearch(n => n.Content);
});See Storing POCOs for the full fluent API.
Handlers run inline after every save or delete:
config.On<Note>(async (note, kind, db, ct) =>
{
if (kind == TriggerKind.Saved)
await db.SaveAsync(new NoteView { ... }, ct);
});See Triggers and Views for materialized views and cascading handlers.
Enable automatic metadata extraction when blobs are uploaded:
config.OnUpload(); // default handler: MIME detection, text extractionOr provide a custom handler:
config.OnUpload(async (path, contentType, content, db, ct) =>
{
// custom processing
return new BlobFile { Path = path, ContentType = contentType };
});See Blob Storage for details.
AutoQueryable is on by default. It promotes all simple-type properties to queryable columns. To disable for a specific type:
config.Store<Note>(s =>
{
s.AutoQueryable(false);
s.AddQueryable(n => n.AuthorId).NotAnalyzed();
s.AddQueryable(n => n.Content);
});| Property | Type | Default | Description |
|---|---|---|---|
AutoCommitDelay |
int |
(framework default) | Interval in milliseconds for automatic Lucene search commits |
AutoKeyProperties |
string[] |
id, _id, key, _key, pk, primaryKey, uuid, guid |
Convention-based key property names for auto-detection. First match wins (case-insensitive). |
var catalog = new LottaCatalog("tenant123", catalog =>
{
catalog.UseAzure(connectionString);
catalog.EmbeddingGenerator = new OllamaEmbeddingGenerator(...);
});
var db = await catalog.GetDatabaseAsync("notes", config =>
{
config.Store<Note>(s =>
{
s.SetKey(n => n.NoteId);
s.AddQueryable(n => n.Content).Vector();
s.DefaultSearch(n => n.Content);
});
config.Store<NoteView>();
config.On<Note>(async (note, kind, db, ct) =>
{
if (kind == TriggerKind.Deleted)
{
await db.DeleteManyAsync<NoteView>(nv => nv.NoteId == note.NoteId, ct);
return;
}
await db.SaveAsync(new NoteView
{
Id = $"nv-{note.NoteId}",
NoteId = note.NoteId,
Content = note.Content,
}, ct);
});
config.OnUpload();
});