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.