Quick start¶
Two APIs¶
| API | When to use |
|---|---|
| Typed (recommended) | IZvecCollection<T>, ZVecCollectionSchemaBuilder.From<T>(), AddZVecCollection<T>, expression filters |
| Dynamic (escape hatch) | IZvecCollection, ZVecDoc, string field names, ZVecFilterBuilder |
Typed is a thin façade over dynamic (IZvecCollection<T>.Untyped).
DDL
Native add_column / typed EnsureSchema only add nullable numeric columns. Put string/array fields in the create-time schema.
Console / script (typed)¶
using ZVec.NET;
using ZVec.NET.Mapping;
using var factory = new ZVecFactory();
factory.Initialize(new ZVecOptions { LogLevel = ZVecLogLevel.Warn });
var path = "/tmp/products";
var schema = ZVecCollectionSchemaBuilder.From<Product>().Build();
using var untyped = factory.CreateAndOpen(path, schema);
using IZvecCollection<Product> products = new ZVecCollection<Product>(untyped);
products.Insert(new Product
{
Id = "p1",
Title = "Hello ZVec",
Category = "demo",
Embedding = new float[768]
});
var hits = products.Query(p => p.Embedding, queryVec, topK: 10, filter: p => p.Category == "demo");
foreach (var hit in hits)
Console.WriteLine($"{hit.Record.Id} (score: {hit.Score:F4})");
// Later / after restart: Open loads Schema from on-disk metadata (no schema argument).
using var reopened = factory.Open(path);
using IZvecCollection<Product> again = new ZVecCollection<Product>(reopened);
var doc = again.Fetch("p1");
_ = reopened.Schema;
Document model (Product)¶
using ZVec.NET.Mapping;
public sealed class Product
{
public string Id { get; set; } = "";
public string Title { get; set; } = "";
public string Category { get; set; } = "";
[ZVecVector(768, Metric = ZVecMetricType.Cosine, M = 32, EfConstruction = 256)]
public ReadOnlyMemory<float> Embedding { get; set; }
}
| Member | Required? | Rule |
|---|---|---|
| Identity | Yes (exactly one) | Convention: public string Id / ID, or [ZVecId] |
| Vector properties | Yes [ZVecVector(dim, …)] |
Dimension / metric / index cannot be inferred from ReadOnlyMemory<float> alone |
| Scalar properties | Usually none | Mapped by property name + CLR type |
| Skip a property | [ZVecIgnore] |
Typed filters¶
products.Query(p => p.Embedding, vec, topK: 10, filter: p => p.Category == "demo");
products.Query(p => p.Embedding, vec, topK: 10, filter: p => p.Year > 2020);
products.DeleteByFilter(p => p.Category == "expired");
| Supported | Ops / shapes |
|---|---|
| Compare | == != < <= > >= |
| Boolean | && \|\| ! |
| Null | == null / != null |
Unsupported (throws ZVecException): method calls (StartsWith, Contains, …). Escape hatch: products.Untyped.Query(...) with ZVecFilterBuilder.