Browse the documentation

Documents & collections

Typed, dynamic and named collections, metadata, schemas and the change feed.

Kinds of collection

  • Typed collections store instances of a C# type. You query them with LINQ and get your type back. Register them with AddNetlyDBCollection<T>() or open them from IDocumentStore.
  • Dynamic collections store JSON documents without a .NET type - typically created through the REST API or the Management UI. Their field schema is inferred by sampling stored documents, and they are queried with the same filter language.
  • File collections store binary files with queryable metadata. See File collections.
TypedYour C# type in, your C# type back. LINQ queries, dependency injection.
DynamicJSON documents without a .NET type. Schema inferred by sampling; same filter language.
FileBinary files with queryable metadata, virtual folders and tags.

Opening collections from the store

IDocumentStore is registered by AddNetlyDB. It opens typed collections by type or by name and exposes the lower-level IDocumentCollection<T>, which adds text queries, projections, query explanations, optimistic concurrency (TryUpdate / TryDelete with an expected revision) and mutation-status lookup.

var docStore = host.Services.GetRequiredService<IDocumentStore>();

// Typed: the collection name defaults to the type name
var users = docStore.GetCollection<User>();

// Explicitly named
var archive = docStore.GetCollection<User>("UsersArchive");

Named collections

Register several logical collections for the same document type:

builder.Services.AddNetlyDB()
    .AddNetlyDBCollection<AuditEntry>("audit")
    .AddNetlyDBCollection<AuditEntry>("security");

var provider = host.Services.GetRequiredService<INamedNetlyDBCollectionProvider<AuditEntry>>();
var audit = provider.Get("audit");
var security = provider.Get("security");

Document metadata

Every document carries system metadata - its id, creation and modification times among them - that you can filter on with the Meta. prefix. See Text queries.

Time-to-live

Pass a ttl when adding a document and it is removed automatically after it expires. A background cleanup service does the removal (EnableTtlCleanup, default on).

Schema validation

Attach opt-in field rules to a collection; local writes that violate them are rejected with a SchemaValidationException. Collections without a schema are unaffected and pay no overhead. Each rule supports Required, a Type (String, Integer, Number, Boolean), MinLength / MaxLength, Min / Max, a regular-expression Pattern, and AllowedValues.

builder.Services.AddNetlyDB(o =>
{
    o.Validation.Collections["Person"] = new CollectionValidationSchema
    {
        Rules =
        [
            new FieldValidationRule { Path = "Name",   Required = true, Type = FieldValueType.String, MaxLength = 40 },
            new FieldValidationRule { Path = "Age",    Type = FieldValueType.Integer, Min = 0, Max = 130 },
            new FieldValidationRule { Path = "Status", AllowedValues = ["active", "inactive"] }
        ]
    };
})
.AddNetlyDBCollection<Person>();

// A write that violates the rules throws SchemaValidationException;
// over the REST API it surfaces as a 400 with the field violations.

Change notifications

The engine publishes an in-process feed of document changes, which NetlyDB uses internally - for example to keep automatically embedded vector indexes current. The change feed is not part of the public API in the current release, so applications cannot subscribe to it directly.

An unhandled error has occurred. Reload X

Reconnecting

Restoring the connection to the server...

Still trying

Next attempt in seconds

Connection lost

We could not reach the server.