RFC: Write Support (INSERT / CREATE TABLE AS) for v1 #47
stephaniewang526
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
The most requested feature for this extension is write support. Some example answers from a user survey:
This RFC proposes a simple v1 of write support. Feedback welcome on scope, API surface, and priorities.
Scope
INSERT INTO mongo.collection SELECT ...UPDATE,DELETEvia DMLCREATE TABLE mongo.db.new_coll AS SELECT ...ON CONFLICT/ upsertCOPY ... TO(bulk export to MongoDB)insertManyunder the hoodaddress_city-> nestedaddress.city)RETURNINGclauseThe core value prop: users can ETL into MongoDB from any DuckDB source (Parquet, CSV, Postgres, another Mongo collection, etc.) using standard SQL.
Architecture (3 pieces)
1.
MongoInsertOperator-- custom PhysicalOperatorA new
PhysicalOperatorsubclass that receivesDataChunks from DuckDB's pipeline and callsinsertManyon the target collection.Key design decisions:
insertManywithordered: falsefor throughput.FlattenDocument-- DuckDB values -> BSON. Reuse thecolumn_name_to_mongo_pathmap to reconstruct nested docs (e.g., columnaddress_citywrites to{"address": {"city": ...}})._idhandling: if source data has an_idcolumn, pass it through; otherwise let MongoDB auto-generate ObjectIds.2. Wire into
MongoCatalog::PlanInsert/PlanCreateTableAsReplace the current
throw NotImplementedException(...)stubs:PlanInsert: create aMongoInsertOperator, connect the child plan as its input. The target collection comes fromLogicalInsert::table.PlanCreateTableAs: create the collection (it auto-creates on first insert in MongoDB), then behave likePlanInsert.The catalog already has
connection_stringanddatabase_name-- just pass them down.3. DuckDB-value-to-BSON serializer
A new helper (inverse of
FlattenDocument):Type mapping:
Nested reconstruction: if
column_name_to_mongo_path["address_city"] == "address.city", split on.and build nested BSON subdocuments, merging sibling fields (e.g.,address_city+address_zip-> singleaddresssubdoc).Execution flow
For
INSERT INTO mongo.db.users SELECT ...:mongo.db.usersviaMongoCatalog.MongoCatalog::PlanInsertcreatesMongoInsertOperator(connection_string, "db", "users", column_info).MongoInsertOperator::Sink(chunk)for each output chunk.vector<bsoncxx::document::value>, flushes every 1000 docs viacollection.insert_many(batch).Finalize()flushes remaining docs, returns row count.Open questions for feedback
address_cityautomatically nest it asaddress.cityin MongoDB, or should that be opt-in?ordered: false), should we report the count of successful inserts and continue, or abort?UPDATE/DELETEnext, orCOPY TObulk export?Looking forward to your thoughts!
All reactions