Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.lambdadb.ai/llms.txt

Use this file to discover all available pages before exploring further.

Use the LambdaDB Migration CLI to migrate Qdrant collections into LambdaDB. The CLI inventories your Qdrant collection, generates an editable LambdaDB mapping, creates the target LambdaDB collection when needed, streams points as LambdaDB documents, saves local checkpoints, and validates migrated records before cutover. Qdrant models searchable records as points made of an id, one or more vectors, and an optional payload. LambdaDB models records as documents: each document is stored as JSON, while searchable fields are declared in the collection’s indexConfigs.

What the CLI supports

Qdrant dataLambdaDB targetMigration behavior
CollectionCollectionKeep one LambdaDB collection per Qdrant collection unless you are also changing tenancy or isolation boundaries.
Point IDDocument idNumeric Qdrant IDs are converted to strings. UUID IDs remain the same string value.
Unnamed dense vectorvector fieldThe generated mapping uses dense as the default target field.
Named dense vectorvector fieldEach Qdrant named vector maps to its own LambdaDB vector field.
Sparse vectorsparseVector fieldQdrant indices and values arrays are converted to a LambdaDB sparse object.
PayloadDocument fieldsPayload fields are flattened by default. Indexed payload fields become LambdaDB index configs.
Payload indexindexConfigs fieldSupported types include keyword, text, long, double, boolean, datetime, and object.
Qdrant multi-vectors and Manhattan distance collections require workload-specific review. The CLI detects them and rejects the default migration path instead of silently creating a misleading LambdaDB schema.

Step 1: Install the CLI

Install the latest release:
curl -fsSL https://raw.githubusercontent.com/lambdadb/lambdadb-migration/main/install.sh | sh
Install a specific version:
curl -fsSLO https://raw.githubusercontent.com/lambdadb/lambdadb-migration/main/install.sh
sh install.sh --version v0.1.5 --install-dir "$HOME/.local/bin"
Check the Qdrant command:
lambdadb-migration qdrant --help

Step 2: Set credentials

LambdaDB Cloud uses region-specific API base URLs. Use the base URL, project name, and project API key shown for your project in the LambdaDB Cloud console. Do not assume a global default URL or a fixed project name.
Set your LambdaDB connection values:
export LAMBDADB_BASE_URL="YOUR_REGION_BASE_URL"
export LAMBDADB_PROJECT_NAME="YOUR_PROJECT_NAME"
export LAMBDADB_PROJECT_API_KEY="YOUR_PROJECT_API_KEY"
If your Qdrant deployment requires an API key, pass it with --qdrant.api-key.

Step 3: Generate inventory and mapping

Run the inventory command against the Qdrant gRPC endpoint:
lambdadb-migration inventory qdrant \
  --qdrant.url http://localhost:6334 \
  --qdrant.collection articles \
  --output qdrant-inventory.yaml
The output includes the source inventory and an editable LambdaDB mapping:
mapping:
  target:
    collection: articles
    createCollection: true
  vectors:
    dense:
      targetField: dense
      dimensions: 1536
      similarity: cosine
  sparseVectors:
    sparse:
      targetField: sparse
  payload:
    mode: flatten
    rename:
      metadata.url: metadata_url
    indexConfigs:
      tenant_id:
        type: keyword
      title:
        type: text
      metadata_url:
        type: keyword
  ids:
    targetField: id
Review the generated mapping before running the migration. In particular, check vector dimensions, vector similarities, payload index types, renamed dotted fields, and the target collection name.
Generated mappings set target.createCollection: true by default. With that setting, the migration creates the LambdaDB collection if it is missing and waits until it is ready before writing documents.

Step 4: Run a dry run

Use a dry run to validate the mapping and inspect the planned migration without writing documents:
lambdadb-migration qdrant \
  --qdrant.url http://localhost:6334 \
  --qdrant.collection articles \
  --lambdadb.base-url "$LAMBDADB_BASE_URL" \
  --lambdadb.project-name "$LAMBDADB_PROJECT_NAME" \
  --lambdadb.api-key "$LAMBDADB_PROJECT_API_KEY" \
  --lambdadb.collection articles \
  --mapping-file qdrant-inventory.yaml \
  --migration.dry-run

Step 5: Run the migration

Run the migration with validation enabled:
lambdadb-migration qdrant \
  --qdrant.url http://localhost:6334 \
  --qdrant.collection articles \
  --lambdadb.base-url "$LAMBDADB_BASE_URL" \
  --lambdadb.project-name "$LAMBDADB_PROJECT_NAME" \
  --lambdadb.api-key "$LAMBDADB_PROJECT_API_KEY" \
  --lambdadb.collection articles \
  --mapping-file qdrant-inventory.yaml \
  --migration.write-mode bulk \
  --migration.validate \
  --migration.validation-report validation-report.json
Migration progress is written to stderr with accepted count, percent, batch size, rate, and elapsed time. The CLI stores checkpoints under .lambdadb-migration/checkpoints by default. If the command is interrupted, rerun the same command to resume. Use --migration.restart to ignore an existing checkpoint and start from the beginning. Use --migration.create-collection=false when the target LambdaDB collection already exists and the migration should not create it.

Step 6: Review validation

--migration.validate checks the accepted record count, fetches a sample of migrated documents from LambdaDB using strongly consistent reads, and compares sampled fields. --migration.validation-report writes the validation result as JSON. The report includes source count, accepted records, LambdaDB numDocs, sampled IDs, compared sample count, query overlap results, and validation errors.
numDocs is reported for visibility, but sample fetch and field comparison are the stronger validation checks for read-after-write confirmation.
For dense-vector migrations, add query overlap checks:
lambdadb-migration qdrant \
  --qdrant.url http://localhost:6334 \
  --qdrant.collection articles \
  --lambdadb.base-url "$LAMBDADB_BASE_URL" \
  --lambdadb.project-name "$LAMBDADB_PROJECT_NAME" \
  --lambdadb.api-key "$LAMBDADB_PROJECT_API_KEY" \
  --lambdadb.collection articles \
  --mapping-file qdrant-inventory.yaml \
  --migration.validate \
  --migration.validation-report validation-report.json \
  --migration.query-overlap
By default, --migration.query-overlap reports dense-vector overlap without failing the migration. Set --migration.query-overlap-min-ratio above 0 to require a minimum average overlap.

Mapping details

Use this distance mapping when creating LambdaDB vector fields:
Qdrant distanceLambdaDB similarity
Cosinecosine
Dotdot_product
Euclideuclidean
ManhattanNo direct equivalent. Re-evaluate the embedding/search setup before migrating.
For a Qdrant point with a single dense vector:
Qdrant point
{
  "id": 1,
  "vector": [0.12, 0.34, 0.56],
  "payload": {
    "tenant_id": "acme",
    "title": "Refund policy",
    "body": "Refunds are available within 7 days.",
    "created_at": "2026-05-01T10:00:00Z"
  }
}
the CLI writes a LambdaDB document like this:
LambdaDB document
{
  "id": "1",
  "tenant_id": "acme",
  "title": "Refund policy",
  "body": "Refunds are available within 7 days.",
  "created_at": "2026-05-01T10:00:00Z",
  "dense": [0.12, 0.34, 0.56]
}
For Qdrant named vectors:
Qdrant point with named vectors
{
  "id": 1,
  "vector": {
    "title_dense": [0.1, 0.2, 0.3],
    "body_dense": [0.4, 0.5, 0.6]
  },
  "payload": {
    "title": "Refund policy",
    "body": "Refunds are available within 7 days."
  }
}
the CLI writes separate LambdaDB vector fields:
LambdaDB document
{
  "id": "1",
  "title": "Refund policy",
  "body": "Refunds are available within 7 days.",
  "title_dense": [0.1, 0.2, 0.3],
  "body_dense": [0.4, 0.5, 0.6]
}
For Qdrant sparse vectors, the CLI converts indices and values to an object whose keys are index strings:
Qdrant sparse vector
{
  "indices": [1, 42],
  "values": [0.22, 0.8]
}
LambdaDB sparse vector
{
  "sparse": {
    "1": 0.22,
    "42": 0.8
  }
}

Reduce application changes with SDK compatibility

After data is in LambdaDB, Python and TypeScript applications can use LambdaDB’s Qdrant compatibility clients as a bridge before rewriting every query to native LambdaDB APIs. The compatibility clients support common Qdrant-style calls such as collection creation, dense-vector upsert, dense-vector query, retrieve, delete, filtered scroll, and unfiltered count. They are not full Qdrant client replacements, and unsupported behavior raises an explicit error where possible.

Qdrant SDK compatibility

Use Python lambdadb.compat.qdrant or TypeScript @functional-systems/lambdadb/compat/qdrant to reduce application code changes.
A Qdrant query against a named vector:
Python
from qdrant_client import models

qdrant.query_points(
    collection_name="articles",
    query=query_vector,
    using="dense",
    limit=10,
    query_filter=models.Filter(
        must=[
            models.FieldCondition(
                key="tenant_id",
                match=models.MatchValue(value="acme"),
            )
        ]
    ),
    with_payload=True,
)
becomes a LambdaDB knn query:
Python
results = coll.query(
    query={
        "knn": {
            "field": "dense",
            "queryVector": query_vector,
            "k": 10,
            "filter": {
                "queryString": {
                    "query": '"acme"',
                    "defaultField": "tenant_id",
                }
            },
        }
    },
    size=10,
)
When using LambdaDB managed embeddings, send query text instead of a vector:
Python
results = coll.query(
    query={
        "knn": {
            "field": "bodyEmbedding",
            "queryText": "refund policy",
            "k": 10,
        }
    },
    size=10,
)

Rewrite filters

Qdrant filters commonly use must, must_not, and should clauses. In LambdaDB, use a bool query when the filter logic is larger than a single query string.
Qdrant filter
{
  "must": [
    { "key": "tenant_id", "match": { "value": "acme" } },
    { "key": "created_at", "range": { "gte": "2026-01-01T00:00:00Z" } }
  ],
  "must_not": [
    { "key": "status", "match": { "value": "deleted" } }
  ]
}
LambdaDB bool query
{
  "bool": [
    {
      "queryString": {
        "query": "tenant_id:acme"
      },
      "occur": "filter"
    },
    {
      "queryString": {
        "query": "created_at:[2026-01-01T00:00:00Z TO *]"
      },
      "occur": "filter"
    },
    {
      "queryString": {
        "query": "status:deleted"
      },
      "occur": "must_not"
    }
  ]
}
Use field types intentionally:
Qdrant payload useLambdaDB index type
Exact string match, tags, IDs, tenant IDskeyword
Natural-language matchingtext
Integer range or sortinglong
Floating-point range or sortingdouble
Date/time range or sortingdatetime
Boolean flagsboolean
Nested JSON kept as a searchable objectobject
Qdrant hybrid queries often use prefetch plus RRF fusion across dense and sparse vectors.
Qdrant hybrid query
{
  "prefetch": [
    {
      "query": { "indices": [1, 42], "values": [0.22, 0.8] },
      "using": "sparse",
      "limit": 20
    },
    {
      "query": [0.01, 0.45, 0.67],
      "using": "dense",
      "limit": 20
    }
  ],
  "query": { "fusion": "rrf" },
  "limit": 10
}
In LambdaDB, express the same dense/sparse fusion with rrf:
LambdaDB hybrid query
{
  "rrf": [
    {
      "sparseVector": {
        "field": "sparse",
        "queryVector": {
          "1": 0.22,
          "42": 0.8
        }
      }
    },
    {
      "knn": {
        "field": "dense",
        "queryVector": [0.01, 0.45, 0.67],
        "k": 20
      }
    }
  ]
}
You can also combine lexical and vector relevance:
LambdaDB lexical + vector hybrid query
{
  "l2": [
    {
      "queryString": {
        "query": "refund policy",
        "defaultField": "body"
      },
      "boost": 0.4
    },
    {
      "knn": {
        "field": "dense",
        "queryVector": [0.01, 0.45, 0.67],
        "k": 20
      },
      "boost": 0.6
    }
  ]
}

Common gotchas

  • IDs: LambdaDB document IDs are strings. Numeric Qdrant IDs are converted to strings during migration.
  • Field names: LambdaDB field names cannot contain dots. The generated mapping renames dotted Qdrant payload keys, such as metadata.url to metadata_url.
  • Schema: Qdrant can store payload without deciding every searchable field up front. In LambdaDB, decide which fields need indexes before migration.
  • Bulk writes: Regular upsert accepts request payloads up to 6 MB. Bulk upsert accepts up to 200 MB, but not for collections with managed embeddings.
  • Sparse vectors: Qdrant sparse vectors use separate indices and values; LambdaDB uses object key-value pairs.
  • Multi-vectors: Qdrant multi-vectors store matrices for late-interaction models. Plan and validate these workloads separately.
  • Consistency: LambdaDB uses eventual reads by default, but supports consistentRead for strong read-after-write checks. The CLI validation uses strongly consistent sample fetches. For bulk upsert, allow time for documents to become visible after indexing completes.

Next steps

Migration CLI

Review the shared LambdaDB Migration CLI workflow.

Qdrant SDK compatibility

Keep common Qdrant-style Python and TypeScript client calls while migrating application code.

Create a collection

Define LambdaDB index configurations for your migrated data.

Bulk upsert data

Load larger migrated datasets through the bulk upsert workflow.

Hybrid query

Combine lexical, dense vector, and sparse vector search.