Skip to main content
Attach metadata to documents at index time, then constrain queries to the documents whose metadata matches a filter. Filtering is evaluated on the locally loaded index, so call load_index() (or open a session) before querying with a filter.

Operators

OperatorMeaning
$eq, $neequals / not equals
$gt, $gte, $lt, $ltegreater / less than (values compared as strings)
$in, $ninvalue in / not in a list
$nearwithin a haversine distance of a point: "lat,lng,radiusMeters"
Compose multiple conditions with $and / $or (nestable). A single condition can be passed on its own without a wrapper.

Examples

import asyncio
from datetime import datetime
from moss import DocumentInfo, MossClient, QueryOptions

async def main():
    client = MossClient(MOSS_PROJECT_ID, MOSS_PROJECT_KEY)

    docs = [
        DocumentInfo(id="doc1", text="Running shoes with breathable mesh for daily training.",
                     metadata={"category": "shoes", "price": "79", "city": "new-york",
                               "location": "40.7580,-73.9855"}),
        DocumentInfo(id="doc2", text="Trail running shoes built for rocky terrain.",
                     metadata={"category": "shoes", "price": "149", "city": "seattle",
                               "location": "47.6062,-122.3321"}),
        DocumentInfo(id="doc3", text="Lightweight city backpack with laptop compartment.",
                     metadata={"category": "bags", "price": "95", "city": "new-york",
                               "location": "40.7505,-73.9934"}),
    ]

    index = f"catalog-{datetime.now():%Y%m%d-%H%M%S}"
    await client.create_index(index, docs)
    await client.load_index(index)   # required before filtering

    # $eq - a single condition needs no wrapper
    await client.query(index, "running gear",
        QueryOptions(top_k=5, filter={"field": "category", "condition": {"$eq": "shoes"}}))

    # $and - shoes under $100
    await client.query(index, "running shoes",
        QueryOptions(top_k=5, alpha=0.6, filter={"$and": [
            {"field": "category", "condition": {"$eq": "shoes"}},
            {"field": "price",    "condition": {"$lt": "100"}},
        ]}))

    # $in - city in a set
    await client.query(index, "city essentials",
        QueryOptions(top_k=5, filter={"field": "city", "condition": {"$in": ["new-york"]}}))

    # $near - within 5km of Times Square
    await client.query(index, "city products",
        QueryOptions(top_k=5, filter={"field": "location",
                                      "condition": {"$near": "40.7580,-73.9855,5000"}}))

asyncio.run(main())
Metadata values are stored and compared as strings, so write numeric filters as strings ("100", not 100). Filtering is only applied on locally loaded indexes.

Hybrid search

Blend semantic and keyword scoring.

Retrieval

Retrieval strategies overview.