Skip to main content

Predicates

Predicates in Ahnlich are metadata-based filters that allow you to query and filter stored data beyond just similarity search. They work alongside vector similarity to enable powerful hybrid queries.

Overview

When you store data in Ahnlich (both DB and AI), each entry consists of:

  • Key: The vector embedding (or raw key for DB stores)
  • Value: Metadata as key-value pairs (e.g., {"author": "Alice", "category": "tech"})

Predicates let you filter results based on this metadata.

Core Concepts

Predicate

A predicate is a single comparison operation on a metadata field. Ahnlich supports four operators:

OperatorDescriptionExample
EQUALSExact matchauthor = "Alice"
NOT EQUALSNot equalstatus != "draft"
INValue in listcategory IN ["tech", "science"]
NOT INValue not in listpriority NOT IN ["low", "spam"]

Predicate Condition

A predicate condition combines predicates using logical operators:

OperatorDescriptionExample
ANDBoth conditions must be true(author = "Alice") AND (category = "tech")
OREither condition must be true(status = "published") OR (priority = "high")

Conditions can be nested to create complex queries:

(author = "Alice" AND category = "tech") OR (priority = "high")

Predicate Index

A predicate index optimizes queries on specific metadata fields. Without an index, Ahnlich scans all entries. With an index, lookups are much faster.

Creating an index:

CREATEPREDINDEX (author, category) IN my_store

Dropping an index:

DROPPREDINDEX (category) IN my_store

Indexes are idempotent - creating an existing index won't error, it just adds new ones.

Supported Data Types

Predicates work with metadata values of type:

  • String - Text values like "Alice", "tech", "published"
  • Binary - Raw bytes (for image hashes, etc.)

Examples

Simple Predicate Query

Find all entries where author is "Alice":

GETPRED (author = "Alice") IN my_store

Complex Condition

Find tech articles by Alice or Bob:

GETPRED (((author = Alice) OR (author = Bob)) AND (category = tech)) IN my_store

Hybrid Query (Similarity + Predicate)

Find similar documents, filtered by author:

Ahnlich AI:

GETSIMN 5 WITH [machine learning tutorial] USING cosinesimilarity IN my_store WHERE (author = Alice)

Ahnlich DB:

GETSIMN 5 WITH [0.1, 0.2, ...] USING cosinesimilarity IN my_store WHERE (author = "Alice")

This combines vector similarity with metadata filtering.

Using IN Operator

Find entries with multiple allowed values:

GETPRED (category IN (tech, science, ai)) IN my_store

Delete by Predicate

Remove all draft entries:

DELPRED (status = "draft") IN my_store

Best Practices

1. Create Indexes for Frequently Queried Fields

If you often filter by author, create an index:

CREATEPREDINDEX (author) IN my_store

2. Declare Predicates at Store Creation

Specify expected predicates upfront:

Ahnlich AI:

CREATESTORE my_store 
QUERYMODEL all-minilm-l6-v2
INDEXMODEL all-minilm-l6-v2
PREDICATES (author, category, status)

Ahnlich DB:

CREATESTORE my_store 
DIMENSION 384
CREATEPREDINDEX (author, category, status)

3. Keep Metadata Lightweight

Predicates are for filtering, not bulk data storage. Keep values small:

  • ✅ Good: {"author": "Alice", "category": "tech"}
  • ❌ Bad: {"content": "<entire article text>"}

4. Use AND/OR Efficiently

  • Use AND when both conditions must match (narrows results)
  • Use OR when either condition matches (broadens results)

5. Index High-Cardinality Fields

If a field has many unique values (like author), index it. Low-cardinality fields (like status with only 2-3 values) benefit less from indexing.

CLI Command Reference

CommandDescription
CREATEPREDINDEXCreate index on metadata fields
DROPPREDINDEXRemove index from fields
GETPREDQuery by predicate only
GETSIMN ... WHERESimilarity search filtered by predicate
DELPREDDelete entries matching predicate

See detailed examples in:

Limitations

  • Predicates only support equality-based comparisons (no regex, range queries, or full-text search yet)
  • Index updates are synchronous - creating an index on a large store may take time
  • No support for numeric comparisons (e.g., age > 18) - use string equality as a workaround

Advanced: Predicate Internals

Under the hood, predicates are structured as:

PredicateCondition:
- Value(Predicate) // Single predicate
- And(left, right) // Logical AND
- Or(left, right) // Logical OR

Predicate:
- Equals(key, value)
- NotEquals(key, value)
- In(key, [values])
- NotIn(key, [values])

This structure allows nesting and complex boolean logic while keeping the implementation efficient.