vecna

package module
v0.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 20, 2026 License: MIT Imports: 5 Imported by: 0

README

vecna

CI codecov Go Report Card CodeQL Go Reference License Go Version Release

Schema-validated filter builder for vector databases. Build type-safe metadata filters with compile-time field validation.

Filters That Know Your Schema

type DocumentMetadata struct {
    Category string   `json:"category"`
    Score    float64  `json:"score"`
    Tags     []string `json:"tags"`
}

builder, _ := vecna.New[DocumentMetadata]()

// Valid - field exists
filter := builder.Where("category").Eq("tech")

// Error - typo caught immediately
filter := builder.Where("categroy").Eq("tech")
// filter.Err() returns: vecna: field not found: categroy

Install

go get github.com/zoobz-io/vecna

Requires Go 1.24 or higher.

Quick Start

package main

import (
    "fmt"
    "github.com/zoobz-io/vecna"
)

type Metadata struct {
    Category string   `json:"category"`
    Score    float64  `json:"score"`
    Active   bool     `json:"active"`
    Tags     []string `json:"tags"`
}

func main() {
    // Create a schema-validated builder
    builder, err := vecna.New[Metadata]()
    if err != nil {
        panic(err)
    }

    // Build filters with validation
    filter := builder.And(
        builder.Where("category").Eq("tech"),
        builder.Or(
            builder.Where("score").Gte(0.8),
            builder.Where("active").Eq(true),
        ),
    )

    // Check for construction errors
    if err := filter.Err(); err != nil {
        panic(err)
    }

    // Use filter with your vector database provider
    fmt.Printf("Filter: %s %s %v\n", filter.Op(), filter.Field(), filter.Value())
}

Capabilities

Feature Description Docs
Schema Validation Field names validated against your struct at build time Concepts
Type Checking Comparison operators blocked on non-numeric fields Concepts
Deferred Errors Build complex filters, check errors once at the end Quickstart
Nested Logic Combine filters with And/Or for complex queries API
JSON Tags Uses existing json tags - no new annotations needed Concepts
Serializable Specs Build filters from JSON for dynamic/LLM-generated queries Specs

Why vecna?

  • Catch typos early — Field name errors surface when building filters, not at query time
  • Type safety — Comparison operators only work on numeric fields
  • Zero new tags — Uses your existing json struct tags
  • Provider agnostic — Filter AST translates to any vector database

Filters as Data

Filters can be built programmatically from serializable specs — enabling dynamic queries, stored filter configurations, and LLM-generated filters.

// Filter spec from JSON (API request, config file, LLM output)
specJSON := `{
    "op": "and",
    "children": [
        {"op": "eq", "field": "category", "value": "tech"},
        {"op": "gte", "field": "score", "value": 0.8}
    ]
}`

var spec vecna.FilterSpec
json.Unmarshal([]byte(specJSON), &spec)

// Convert to validated filter
builder, _ := vecna.New[Metadata]()
filter := builder.FromSpec(&spec)

if err := filter.Err(); err != nil {
    // Schema validation still applies - invalid fields caught here
}

The spec is validated against your schema. Field typos and type mismatches are caught at conversion time, not when the query hits your database.

Ecosystem

vecna powers the filter system in grub, providing schema-validated queries across vector database providers.

// In grub - vecna filters translate to provider-specific syntax
store, _ := grub.NewPinecone[Document](index, grub.WithNamespace("docs"))

filter := store.Filter().And(
    store.Filter().Where("category").Eq("tech"),
    store.Filter().Where("score").Gte(0.8),
)

results, _ := store.Query(ctx, embedding, grub.WithFilter(filter))

Supported providers: Pinecone, Qdrant, Weaviate, Milvus, pgvector.

Documentation

Learn

Guides

Reference

Contributing

See CONTRIBUTING.md for development workflow.

License

MIT - see LICENSE for details.

Documentation

Overview

Package vecna provides a schema-validated filter builder for vector database queries. It serves as the query language for vector metadata filtering, similar to how edamame provides SQL AST capabilities.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNotStruct is returned when the type parameter is not a struct.
	ErrNotStruct = errors.New("vecna: type must be a struct")

	// ErrFieldNotFound is returned when a field name is not found in the schema.
	ErrFieldNotFound = errors.New("vecna: field not found")

	// ErrInvalidFilter is returned when a filter contains validation errors.
	ErrInvalidFilter = errors.New("vecna: invalid filter")
)

Errors returned by vecna.

Functions

This section is empty.

Types

type Builder

type Builder[T any] struct {
	// contains filtered or unexported fields
}

Builder provides schema-validated filter construction for type T. Create a Builder using New[T]().

func New

func New[T any]() (*Builder[T], error)

New creates a schema-validated Builder for metadata type T. Uses sentinel to extract field metadata from T. Field names are resolved from: json tag > Go field name. Fields with json:"-" are excluded.

func (*Builder[T]) And

func (*Builder[T]) And(filters ...*Filter) *Filter

And combines filters with logical AND. Returns a Filter that matches when all child filters match.

func (*Builder[T]) FromSpec

func (b *Builder[T]) FromSpec(spec *FilterSpec) *Filter

FromSpec converts a FilterSpec to a validated Filter. The spec is validated against the schema defined by T. Any validation errors are accessible via Filter.Err().

func (*Builder[T]) Not

func (*Builder[T]) Not(filter *Filter) *Filter

Not negates a filter. Returns a Filter that matches when the child filter does not match.

func (*Builder[T]) Or

func (*Builder[T]) Or(filters ...*Filter) *Filter

Or combines filters with logical OR. Returns a Filter that matches when any child filter matches.

func (*Builder[T]) Spec

func (b *Builder[T]) Spec() Spec

Spec returns the schema for documentation/export.

func (*Builder[T]) Where

func (b *Builder[T]) Where(field string) *FieldBuilder[T]

Where begins a filter condition on a field. If the field doesn't exist in T, the returned FieldBuilder will produce a Filter with an error accessible via Filter.Err().

type FieldBuilder

type FieldBuilder[T any] struct {
	// contains filtered or unexported fields
}

FieldBuilder constructs conditions for a specific field.

func (*FieldBuilder[T]) Contains

func (fb *FieldBuilder[T]) Contains(value any) *Filter

Contains creates an array membership filter (array field contains value).

func (*FieldBuilder[T]) Eq

func (fb *FieldBuilder[T]) Eq(value any) *Filter

Eq creates an equality filter (field == value).

func (*FieldBuilder[T]) Gt

func (fb *FieldBuilder[T]) Gt(value any) *Filter

Gt creates a greater-than filter (field > value).

func (*FieldBuilder[T]) Gte

func (fb *FieldBuilder[T]) Gte(value any) *Filter

Gte creates a greater-than-or-equal filter (field >= value).

func (*FieldBuilder[T]) In

func (fb *FieldBuilder[T]) In(values ...any) *Filter

In creates a set membership filter (field IN values).

func (*FieldBuilder[T]) Like

func (fb *FieldBuilder[T]) Like(pattern string) *Filter

Like creates a pattern matching filter (field LIKE pattern). Pattern syntax is provider-dependent but typically supports % and _ wildcards.

func (*FieldBuilder[T]) Lt

func (fb *FieldBuilder[T]) Lt(value any) *Filter

Lt creates a less-than filter (field < value).

func (*FieldBuilder[T]) Lte

func (fb *FieldBuilder[T]) Lte(value any) *Filter

Lte creates a less-than-or-equal filter (field <= value).

func (*FieldBuilder[T]) Ne

func (fb *FieldBuilder[T]) Ne(value any) *Filter

Ne creates a not-equal filter (field != value).

func (*FieldBuilder[T]) Nin

func (fb *FieldBuilder[T]) Nin(values ...any) *Filter

Nin creates a set exclusion filter (field NOT IN values).

type FieldKind

type FieldKind uint8

FieldKind categorizes field types for validation.

const (
	KindString FieldKind = iota
	KindInt
	KindFloat
	KindBool
	KindSlice
	KindUnknown
)

Field kind constants.

func (FieldKind) String

func (k FieldKind) String() string

String returns the string representation of the field kind.

type FieldSpec

type FieldSpec struct {
	Name   string    // JSON field name (from tag or Go name)
	GoName string    // Original Go field name
	Kind   FieldKind // Type category
}

FieldSpec describes a single filterable field.

type Filter

type Filter struct {
	// contains filtered or unexported fields
}

Filter represents a filter condition or logical group. Construct filters using Builder[T].Where(), And(), or Or().

func (*Filter) Children

func (f *Filter) Children() []*Filter

Children returns the child filters for logical operators (And, Or). Returns nil for field conditions.

func (*Filter) Err

func (f *Filter) Err() error

Err returns any error that occurred during filter construction. This enables deferred error checking after building complex filters.

func (*Filter) Field

func (f *Filter) Field() string

Field returns the field name for field conditions. Returns empty string for logical operators (And, Or).

func (*Filter) Op

func (f *Filter) Op() Op

Op returns the filter operator.

func (*Filter) Value

func (f *Filter) Value() any

Value returns the comparison value for field conditions. Returns nil for logical operators (And, Or).

type FilterSpec

type FilterSpec struct {
	Op       string        `json:"op"`                 // Operator: "eq", "ne", "gt", "gte", "lt", "lte", "in", "and", "or"
	Field    string        `json:"field,omitempty"`    // Field name (for field conditions)
	Value    any           `json:"value,omitempty"`    // Comparison value (for field conditions)
	Children []*FilterSpec `json:"children,omitempty"` // Child filters (for and/or)
}

FilterSpec represents a serializable filter specification. This enables programmatic filter construction from JSON or other external sources.

type Op

type Op uint8

Op represents a filter operator.

const (
	Eq       Op = iota // Equal
	Ne                 // Not equal
	Gt                 // Greater than
	Gte                // Greater than or equal
	Lt                 // Less than
	Lte                // Less than or equal
	In                 // In set
	Nin                // Not in set
	Like               // Pattern match
	Contains           // Array contains
	And                // Logical AND
	Or                 // Logical OR
	Not                // Logical NOT
)

Filter operators.

func (Op) String

func (o Op) String() string

String returns the string representation of the operator.

type Spec

type Spec struct {
	TypeName string      // Go type name
	Fields   []FieldSpec // Filterable fields
}

Spec describes the metadata schema extracted from T.

func (*Spec) Field

func (s *Spec) Field(name string) *FieldSpec

Field returns the FieldSpec for the given field name, or nil if not found.

Directories

Path Synopsis
Package testing provides test helpers for vecna.
Package testing provides test helpers for vecna.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL