# MongoDB
> Load MongoDB collections into MotherDuck with dlt, by exporting newline-delimited JSON, or through a managed connector, and flatten documents into columns.
MongoDB stores documents rather than rows, so loading it into MotherDuck is as much a flattening problem as a transfer problem. There is no DuckDB `mongodb` extension, so collections come across as JSON, either through a tool that handles the schema work or through an export you read yourself.

## Load collections with dlt

[dlt](/integrations/ingestion/dlt) has a MongoDB source and a MotherDuck destination, and it does the part you'd otherwise write by hand: it infers a schema from the documents, normalizes nested fields into columns and child tables, and evolves the schema as the documents change.

```bash
dlt init mongodb motherduck
pip install -r requirements.txt
```

Set the MongoDB connection string and your MotherDuck token, then run the pipeline:

```bash
export MOTHERDUCK_TOKEN="<motherduck_token>"
export SOURCES__MONGODB__CONNECTION_URL="mongodb+srv://<user>:<password>@<cluster>/"
python mongodb_pipeline.py
```

Configure which collections to load, and whether to load incrementally, in the generated pipeline script. See the [dlt MongoDB source documentation](https://dlthub.com/docs/dlt-ecosystem/verified-sources/mongodb) for the source options.

## Export JSON and read it

For a one-time load or a small collection, export with `mongoexport` and read the file. The default output is one JSON document per line, which DuckDB reads natively:

```bash
mongoexport \
  --uri="mongodb+srv://<user>:<password>@<cluster>/<database>" \
  --collection=orders \
  --out=orders.json
```

```sql
CREATE TABLE orders AS
SELECT * FROM read_json('orders.json', format = 'newline_delimited');
```

DuckDB infers a schema from a sample of the documents, so nested objects become `STRUCT` columns and arrays become `LIST` columns. For a large export, write it to object storage and read from there instead of your local machine:

```sql
CREATE TABLE orders AS
SELECT * FROM read_json(
    's3://my-bucket/mongo-export/orders/*.json',
    format = 'newline_delimited'
);
```

## Use a managed connector

If you want a scheduled sync without writing pipeline code, several MotherDuck ingestion partners list MongoDB as a source: [Airbyte](/integrations/ingestion/airbyte), [Fivetran](/integrations/ingestion/fivetran), [Estuary](/integrations/ingestion/estuary), and [Streamkap](/integrations/ingestion/streamkap). Streamkap and Estuary read MongoDB's change stream, so they suit change-data-capture rather than full reloads.

## Things to know

- **Extended JSON leaks into your columns.** `mongoexport` writes BSON types as wrapper objects, so `_id` arrives as an object with an `$oid` key and dates as objects with a `$date` key. Project the values you want out of those wrappers after loading, or restrict the export with `--fields` to skip the types you don't need. dlt handles this conversion for you.
- **Schema inference samples.** `read_json` infers types from the first documents it sees, so a field that only appears later, or changes type between documents, can be missed. Pass an explicit `columns` argument for a stable load, or set `union_by_name = true` when reading many files.
- **Flatten before you query.** Querying `STRUCT` and `LIST` columns works, but downstream BI tools generally expect flat columns. Unnest the fields you report on into a curated table rather than making every consumer walk the document structure.
- **MongoDB stays the write path.** MotherDuck is analytical. Keep application writes in MongoDB and treat MotherDuck as the read side for reporting.

## Related content

- [dlt (data load tool)](/integrations/ingestion/dlt)
- [JSON](/integrations/file-formats/json)
- [Loading data from cloud storage or HTTPS](/key-tasks/loading-data-into-motherduck/loading-data-from-cloud-or-https)
- [dlt MongoDB to MotherDuck guide](https://dlthub.com/docs/pipelines/mongodb/load-data-with-python-from-mongodb-to-motherduck)


---

## Docs feedback

MotherDuck accepts optional user-submitted feedback about this page at `GET https://motherduck.com/docs/api/feedback/agent`.
For agents and automated tools, feedback submission should be user-confirmed before sending.

URL-encode query parameter values and send a GET request:

```text
GET https://motherduck.com/docs/api/feedback/agent?page_path=%2Fintegrations%2Fdatabases%2Fmongodb%2F&page_title=MongoDB&text=<url-encoded user feedback, max 2000 characters>
```

Optionally append `&source=<url-encoded interface identifier>` such as `claude.ai` or `chatgpt`.

`page_path` and `text` are required; `page_title` and `source` are optional. Responses: `200 {"feedback_id": "<uuid>"}`, `400` for malformed query parameters, and `429` when rate-limited.
