CocoIndex supports Qdrant natively - the integration features a high performance Rust stack with incremental processing end to end for scale and data freshness. 🎉 We just rolled out our latest change that handles automatic target schema setup with Qdrant from CocoIndex indexing flow.

That means, developers don’t need to do any schema setup - including setting up table, field type, keys and index for target stores. The setup is the result of schema inference from CocoIndex flow definition. It is already supported with native integration with Postgres, Neo4j, and Kuzu. This allows for more seamless operation between the indexing and target stores.

No more manual setup

Previously, users had to manually create the collection before indexing:

curl -X PUT 'http://localhost:6333/collections/image_search' \
  -H 'Content-Type: application/json' \
  -d '{
    "vectors": {
      "embedding": {
        "size": 768,
        "distance": "Cosine"
      }
    }
  }'

With the new change, user don’t need to do any manual collection management.

How it works

Following dataflow programming model, user defines a flow, where every step has output data type information, and next setup takes in data type information. See an example (~100 lines of python end to end)

In short, it can be presented as the following lineage graph.

In the declarative dataflow as above

Target = Formula (Source)

It implies both data and the expected target schema. A single flow definition drives both data processing (including change handling) and target schema setup—providing a single source of truth for both data and schema. A similar way to think about it is like type systems inferring data type from operators and inputs - type inference (for example, Rust)

In the indexing flow, export embeddings and metadata directly to Qdrant is all you need.

doc_embeddings.export(
    "doc_embeddings",
    cocoindex.storages.Qdrant(collection_name=QDRANT_COLLECTION),
    primary_key_fields=["id"],
)

To run start a CocoIndex process, users need to first run the setup, that covers all the necessary setup for any backends needed.

cocoindex setup main.py

cocoindex setup

Developers then run

cocoindex update main.py [-L]

to start a indexing pipeline (-L for long running).

If you’ve made logic updates that requires the schema on the target store to be updated, don’t worry. When you run cocoindex update again after the logic update. CocoIndex will infer the schema for the target store. It requires an cocoindex setup to push the schema to the target store, which will notify you in the CLI. As a choice of design, CocoIndex won’t update any schema without your notice, as some schema update may involve destructive changes.

To drop a flow, you’d run

cocoindex drop main.py

cocoindex drop drops the backends when dropping the flow.

All backend entities for the target stores — such as a PostgreSQL table or a Qdrant collection - are owned by the flow as derived data, so will be dropped too.

Why automatic target schema inference?

The question should really be, why not?

The traditional way is users fully figure out when and how to setup/update the target schema themselves, including the specific schema. Indexing flows often span multiple systems. For example:

On the target store:

The data types you're outputting and your target schema must match up.

If there’s any internal state tracking, e.g., in the case of incremental processing

It’s tedious and painful in doing this manually, as all of these systems must agree on schema and structure. This typically requires:

Any addition moving parts to the indexing pipeline system adds frictions — any mismatch between the logic and the storage schema could result in silent failures or subtle bugs.

Continuous changes to a system introduce persistent pains in production. Every time a data flow is updated, the target schema must evolve alongside — making it not a one-off tedious process, but an ongoing source of friction.

In real-world data systems, new fields often need indexing, old ones get deprecated, and transformations evolve. If a type changes, the schema must adapt. These shifts magnify the complexity and underscore the need for more resilient, adaptable infrastructure.

Following the dataflow programming model, every step is derived data all the way to the end. Indexing infrastructure requires data consistency between indexing pipeline and target stores, and the less loose ends, the easier and more robust it will be.

Our Vision: Declarative, Flow-Based Indexing

When we started CocoIndex, our vision was to allow developers to define data transformation and indexing logic declaratively — and CocoIndex do the rest. One big step toward this is automatic schema setup.

We’re committed to taking care of the underlying infrastructure, so developers can focus on what matters: the data and the logic. We are serious when we say, you can have production-ready data pipeline for AI with ~100 lines of Python code.

If you’ve ever struggled with keeping your indexing logic and storage setup in sync — we’ve been there. Let us know what you’d love to see next.