# Advanced — Search and Vector Search **Capabilities:** `MongoCapability.SEARCH`, `MongoCapability.VECTOR_SEARCH` **Properties:** `ca-skeleton.persistence-mongo.advanced.search.enabled`, `ca-skeleton.persistence-mongo.advanced.vector-search.enabled` **Status:** Experimental (design §3.3). Hybrid search likewise. ## Requirements | | | |---|---| | Topology | A deployment with the search service. Atlas Local in a container is a pull-request convenience and is **not** release evidence. | | Privilege | `MongoPrincipalRole.SEARCH_ADMIN` for index management; the application role queries only. | | Gate | `MongoAtlasCapabilityContractSuite` on the actual target deployment. | ## 1. Created is not ready `MongoSearchIndexState`: `CREATED` → `BUILDING` → `READY`, plus `FAILED` and `DELETING`. `MongoSearchReadinessGate.requireReady(state)` refuses anything but `READY`. A search index is built asynchronously: the create call returns immediately and the index answers queries with *partial* results while building. Not an error, not empty — partial. A deployment that creates an index and starts querying serves incomplete results for as long as the build takes, and nothing reports it. ## 2. Search indexes are not application-owned `MongoSearchIndexDescriptor.metadataOwnership()` is `MongoMetadataOwnership.SEARCH_MANAGED`, and `droppableByApplicationDrift()` is false. The index reconciliation described in [ADR-MONGO-004](../../adr/ADR-MONGO-004-index-schema-admin-plane.md) must not drop it. ## 3. Query guardrails `MongoSearchQuery` binds an index, an allowlist of paths, the search text and a result limit. - `requireAllowedPaths(allowed)` raises `MongoOperationRejectedException` on a path outside the allowlist. Without it, a caller can search any indexed field, including ones indexed for a different purpose. - Search text length and result count are bounded at construction. An unbounded search text is a cost multiplier on someone else's service. ## 4. Vector search `MongoVectorIndexDescriptor.cosine(path, dimensions)` declares the index. `MongoEmbedding.forIndex(index, values)` binds an embedding to it and **rejects a dimension mismatch** — a 1536-dimension embedding against a 768-dimension index is not a runtime degradation, it is a category error, and catching it at construction beats catching it as a confusing server message. `MongoEmbedding` copies its backing array in and out. A vector that shares an array with its caller can be mutated after the query is built, which produces a query nobody wrote. `MongoVectorQuery` requires `numCandidates > limit` — searching 10 candidates to return 10 results is an exhaustive scan wearing an ANN index's name. `MongoVectorQuery.nearest(embedding, 10)` uses the standard 20× ratio (200 candidates for 10 results). ## 5. Relevance is the gate, not functionality `MongoVectorSearchBenchmarkGate.standard()` requires **recall** alongside latency and index size. `requiredEvidence()` names recall explicitly. This is the difference between search and everything else in the platform. A vector index can be functionally perfect — it accepts the index, accepts the query, returns k results, within the latency budget — and return the wrong k. A gate that measures only latency certifies a fast wrong answer. `failures(recall, latencyMs, indexMb)` reports which dimension failed so the finding is actionable. ## 6. Failure recovery | Symptom | Cause | Action | |---|---|---| | Incomplete results after a deploy | Queried a `BUILDING` index | Wait for `READY`. The gate prevents this; if it fired, something bypassed it. | | `MongoOperationRejectedException` on a path | Path not in the allowlist | Add it deliberately, or fix the caller. | | Dimension mismatch | Model changed | A new model means a new index. Build alongside, cut over, then retire. | | Recall dropped without a code change | The index was rebuilt with different parameters, or the data distribution shifted | Re-run the benchmark gate; treat a recall regression like a failing test. | | Index `FAILED` | Build error on the search service | Search-side diagnosis; the application must not fall back to a scan silently. | ## 7. Promotion evidence Per [ADR-MONGO-ADV-001](../../adr/ADR-MONGO-ADV-001-capability-promotion.md): the actual target deployment (not Atlas Local), security review of `SEARCH_ADMIN`, a rebuild path, failure cases (non-ready index refused, disallowed path refused, dimension mismatch refused), this document as the runbook, **and** relevance evidence. Search and vector search do not promote on functional success.