diff --git a/.changeset/mongodb-readme-lookup-index-honest.md b/.changeset/mongodb-readme-lookup-index-honest.md new file mode 100644 index 0000000000..332854b088 --- /dev/null +++ b/.changeset/mongodb-readme-lookup-index-honest.md @@ -0,0 +1,30 @@ +--- +"@objectstack/driver-mongodb": patch +--- + +docs(driver-mongodb): stop teaching the spec-refused `reference_to` in the published README, and stop promising a lookup index the driver does not build (#12252 / #13223) + +The schema-sync example in this package's README — which ships to npm — declared +its lookup as `company_id: { type: 'lookup', reference_to: 'company' }` and +closed with `// Creates: … idx_company_id_lookup`. Both halves were wrong, in +opposite directions: + +- `reference` is the only relationship spelling `@objectstack/spec` declares. + `reference_to` is a **rejected alias**, answered by `FieldSchema` with + `unrecognized_keys` and *"Did you mean `reference_to` → `reference`?"* — so + the sample instructed authors to write a key the platform refuses, in the one + place a reader is most likely to copy verbatim. +- The `// Creates:` line promised an index that a *correctly* spelled lookup + does not get. `syncCollectionSchema`'s lookup arm gates on + `field.reference_to`, so it cannot fire for a spec-conformant lookup. Fixing + only the spelling would have left the sample promising an outcome the driver + had just stopped producing. + +The sample now uses `reference`, lists only the three indexes an authored object +actually gets, and the surrounding prose no longer claims lookup fields index +themselves — it names the defect and points at #13222, which owns the fix. + +**No runtime behaviour changes here.** Whether the lookup arm learns to read +`reference` — which would index 57 relationship fields across the 44 exported +platform objects that get no join index today — is #13222's decision, not this +change's. diff --git a/packages/drivers/driver-mongodb/README.md b/packages/drivers/driver-mongodb/README.md index 0ace28d9be..77f6f603b2 100644 --- a/packages/drivers/driver-mongodb/README.md +++ b/packages/drivers/driver-mongodb/README.md @@ -158,10 +158,14 @@ try { Schema sync creates collections and indexes: -Field-level `unique` and lookup fields index themselves; everything else is -declared in the object's `indexes[]` — the one surface an index is declared on -(a field-level `indexed` flag is not a `FieldSchema` key and never built an -index, #2377 / #6810). +Field-level `unique` fields index themselves; everything else is declared in the +object's `indexes[]` — the one surface an index is declared on (a field-level +`indexed` flag is not a `FieldSchema` key and never built an index, +#2377 / #6810). + +⚠️ Lookup fields are **not** indexed today. The lookup arm gates on +`reference_to`, a spelling `FieldSchema` refuses, so a canonically-spelled +`reference` lookup gets no join index — see #13222, which owns that fix. ```typescript await driver.syncSchema('account', { @@ -169,11 +173,11 @@ await driver.syncSchema('account', { fields: { name: { type: 'string', unique: true }, email: { type: 'email' }, - company_id: { type: 'lookup', reference_to: 'company' }, + company_id: { type: 'lookup', reference: 'company' }, }, indexes: [{ fields: ['email'] }], }); -// Creates: idx_id_unique, idx_name_unique, idx_email, idx_company_id_lookup +// Creates: idx_id_unique, idx_name_unique, idx_email ``` ### Aggregation diff --git a/packages/drivers/driver-mongodb/src/mongodb-driver.test.ts b/packages/drivers/driver-mongodb/src/mongodb-driver.test.ts index 7e26f41115..8f0b120a0b 100644 --- a/packages/drivers/driver-mongodb/src/mongodb-driver.test.ts +++ b/packages/drivers/driver-mongodb/src/mongodb-driver.test.ts @@ -344,7 +344,7 @@ describe.skipIf(!sharedMongod)('MongoDBDriver', () => { fields: { name: { type: 'string', unique: true }, email: { type: 'email' }, - company_id: { type: 'lookup', reference_to: 'company' }, + company_id: { type: 'lookup', reference: 'company' }, }, // [#6810] `email` used to carry a field-level `indexed: true` here. That // was never a `FieldSchema` key (#2377 / ADR-0049); the index is @@ -361,7 +361,32 @@ describe.skipIf(!sharedMongod)('MongoDBDriver', () => { expect(indexNames).toContain('idx_id_unique'); expect(indexNames).toContain('idx_name_unique'); expect(indexNames).toContain('idx_email'); - expect(indexNames).toContain('idx_company_id_lookup'); + /** + * ⚠️ [#12252] DIVERGENCE PINNED, DISPOSITION OPEN (#13222) — a + * canonically-spelled lookup gets NO join index here. + * + * This fixture used to spell the field `reference_to: 'company'` and + * assert `idx_company_id_lookup` was CREATED. `reference_to` is a key + * `FieldSchema` REFUSES (`unrecognized_keys`), so the object it described + * was one no author could publish — and the assertion passed only because + * this fixture was the sole thing in the tree reaching the lookup arm of + * `mongodb-schema.ts`, which gates on `field.reference_to` and reads no + * other relationship key. + * + * So correcting the spelling does not leave the outcome alone. Measured + * differentially against the real `syncCollectionSchema`, + * `idx_company_id_lookup` is the ONE index that disappears; a + * `type: 'user'` field still gets its index, so the gate is live rather + * than dead code. The consequence in production is that EVERY authored + * lookup on MongoDB is unindexed — 57/57 relationship fields across the + * 44 exported platform objects (#13222). + * + * ⛔ This records what the driver DOES, not what it SHOULD do. Whether + * the lookup arm learns to read `reference` is #13222's to settle, ⛔ not + * this pin's — when it lands, this line flips back to `toContain` + * deliberately rather than the divergence reopening in silence. + */ + expect(indexNames).not.toContain('idx_company_id_lookup'); }); it('should be idempotent (safe to call multiple times)', async () => {