NEWVectors or files. Pick a path.Start →
    Similar

    Dense Search Over Your Own Embeddings, and What Hybrid Needs

    Upsert documents you embedded elsewhere into an MVS namespace and search them by raw vector through the features search endpoint. Hybrid BM25 plus dense is not part of a plain BYO upsert: the documents carry dense vectors only and no text index is created. If you want a lexical leg later, declare a TEXT payload index on the field when you create the namespace; this recipe shows that declaration and the dense search that works today.

    text
    Single Tier
    18.7K runs
    Run in Builder

    "FastAPI Pydantic v2 validation patterns"

    Why This Matters

    Pure vector search misses exact identifiers and error codes, and teams that bring their own embeddings often assume keyword matching comes with the vector store. On BYO documents it does not unless the text index exists before the first upsert. Declaring it up front is cheap; discovering its absence after indexing a corpus is not.

    from openai import OpenAI
    from mixpeek import Mixpeek
    openai = OpenAI(api_key="your-openai-key")
    mvs = Mixpeek(api_key="your-mvs-key")
    NAMESPACE = "my-namespace"
    def embed(text: str) -> list[float]:
    resp = openai.embeddings.create(model="text-embedding-3-small", input=text)
    return resp.data[0].embedding
    # The one step a plain BYO upsert does not do for you: if you will ever want BM25
    # over these documents, the TEXT payload index has to exist before the first upsert.
    mvs.namespaces.create(
    namespace_name=NAMESPACE,
    payload_indexes=[{"field_name": "content", "type": "text"}],
    )
    # Upsert documents with your own dense vectors. Vectors are named; "dense" is the
    # name you will search by. The text goes in payload so it is stored with the document.
    documents = [
    {"text": "FastAPI uses Pydantic v2 for data validation and serialization", "topic": "python"},
    {"text": "Express.js middleware handles request/response transformations", "topic": "node"},
    {"text": "FastAPI supports async/await natively with Starlette ASGI", "topic": "python"},
    {"text": "Django ORM provides database abstraction with QuerySet API", "topic": "python"},
    ]
    mvs.namespaces.documents.upsert(
    namespace=NAMESPACE,
    collection_id="col_your_collection",
    documents=[{
    "document_id": f"doc-{i}",
    "vectors": {"dense": embed(doc["text"])},
    "payload": {"content": doc["text"]},
    "metadata": {"topic": doc["topic"]},
    } for i, doc in enumerate(documents)],
    )
    # Dense search by raw vector. feature_uri MUST name your vector ("dense"); the
    # default is a text_extractor index and would silently return 0 results.
    query_text = "FastAPI Pydantic validation"
    results = mvs.features.search(
    collection_identifiers=["col_your_collection"],
    feature_uri="dense",
    query={"input_mode": "vector", "vector": embed(query_text)},
    top_k=5,
    )
    for doc in results:
    print(f"{doc['score']:.3f} | {doc['metadata'].get('topic', '')} | {doc['payload']['content'][:80]}")

    Feature Extractors

    Retriever Stages

    feature search

    Search and filter documents by vector similarity using feature embeddings

    filter

    attribute filter

    Filter documents by metadata attribute values using boolean logic

    filter

    limit

    Truncate results to a maximum count with optional offset for pagination

    reduce