Skip to content

feat(database): disable eager collection creation for all schemas#1554

Open
ChrisPdgn wants to merge 3 commits into
mainfrom
feat/lazy-collection-creation
Open

feat(database): disable eager collection creation for all schemas#1554
ChrisPdgn wants to merge 3 commits into
mainfrom
feat/lazy-collection-creation

Conversation

@ChrisPdgn

Copy link
Copy Markdown
Contributor

Summary

  • Set autoCreate: false and autoIndex: false on every Mongoose schema in the database adapter, not just views.
  • Collections are now created lazily on first write instead of at schema registration time, reducing empty collections on shared dev MongoDB clusters.
  • Index creation remains handled explicitly by Conduit's createIndexes() during schema registration.

Test plan

  • Start Conduit with MongoDB and register schemas that have no custom indexes; verify no empty collections are created until the first document insert.
  • Register a schema with custom indexes and confirm indexes are still created correctly.
  • Run findMany / findOne against a schema whose collection has not been created yet and confirm empty results are returned without errors.
  • Verify view schemas still behave correctly.

@ioanniskemerlis

Copy link
Copy Markdown
Contributor

Index creation remains handled explicitly by Conduit's createIndexes() during schema registration.

That’s only true for indexes that are still left in modelOptions.indexes after schemaConverter runs. Single-field indexes get peeled out of modelOptions.indexes and moved onto the field (SchemaConverter.convertModelOptionsIndexes), and field-level unique / index never go through createIndexes() at all. They used to rely on Mongoose autoIndex.

So with autoIndex: false on every schema, those indexes aren’t created on a fresh MongoDB. Compound ones still work.

Quick examples:

ChatRoom: { fields: ['participants'] } gets moved to the field; only { fields: ['participants', 'deleted'] } hits createIndexes()
EmailTemplate.name with unique: true, no unique index gets created on register

I checked this with Mongoose too: with autoIndex: false, path indexes show up in schema.indexes() but tagged _autoIndex: false, so they won’t be built. There’s also no ensureIndexes / syncIndexes fallback elsewhere in the adapter.

This won’t show up on DBs that already had the indexes from before, but it’s a real regression for fresh environments / new schemas.

I think we should keep autoCreate: false, but either:

  • explicitly create field-level indexes after model init, or
  • stop moving single-field indexes onto fields and always create them via createIndexes() (closer to the SQL path)

ChrisPdgn and others added 2 commits July 23, 2026 11:53
With autoIndex disabled, field-level unique/index definitions and
single-field indexes moved onto fields by SchemaConverter were not
being created on fresh databases. Create them explicitly from the
compiled Mongoose schema while skipping the default _id index so
schemas without other indexes remain lazy.

Co-authored-by: Cursor <[email protected]>
Align explicit field-index creation with MongoDB IndexSpecification
typing so the database module builds on v0.16.x.

Co-authored-by: Cursor <[email protected]>
@ChrisPdgn

Copy link
Copy Markdown
Contributor Author

Summary of changes

This PR disables eager MongoDB collection creation in the Mongoose adapter while preserving correct index behavior on fresh databases.

1. Lazy collection creation

In MongooseSchema.ts, all schemas now use:

  • autoCreate: false
  • autoIndex: false

This stops Mongoose from creating empty collections at schema registration time. Collections are created lazily on first write, or when an index is explicitly created.

2. Explicit field-level index creation

Disabling autoIndex exposed a regression: field-level indexes (unique: true, index: {...}) and single-field indexes moved onto fields by SchemaConverter were no longer being created on fresh MongoDB instances.

To fix that, MongooseAdapter now explicitly creates indexes declared on the compiled Mongoose schema via a new createMongooseFieldIndexes() helper, called from _createSchemaFromAdapter() after the existing createIndexes() path.

Important safeguards:

  • Skips the default { _id: 1 } index so schemas with no other indexes remain truly lazy
  • Skips views
  • Strips Mongoose-internal _autoIndex metadata before calling MongoDB createIndex()
  • Preserves existing compound-index creation through createIndexes()

Expected behavior

  • Schemas with no custom indexes: no collection created until first insert
  • Schemas with field-level indexes: collection + indexes created at registration
  • Schemas with compound indexes: unchanged, still created via createIndexes()
  • Reads against non-existent collections: return empty results without error

No Conduit schema migration is expected; _DeclaredSchema stores the original schema, not the converted Mongoose runtime schema.

@ChrisPdgn
ChrisPdgn marked this pull request as ready for review July 23, 2026 09:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants