Skip to content

docs: add vector, geospatial, and full-text search guide#4

Draft
richardsimmonds wants to merge 1 commit into
mainfrom
docs/search-guide
Draft

docs: add vector, geospatial, and full-text search guide#4
richardsimmonds wants to merge 1 commit into
mainfrom
docs/search-guide

Conversation

@richardsimmonds

Copy link
Copy Markdown
Owner

Summary

Adds docs/search-guide.md — a comprehensive guide to DocumentDB's three search capabilities, which were previously advertised with zero documentation or examples.

Closes the docs gap for vector search, geospatial search, and full-text search (kanban task t_20b995f9).

What's covered

Vector search

  • HNSW and IVF index creation via cosmosSearchOptions
  • $search/cosmosSearch and Atlas-compatible $vectorSearch aggregation stages
  • Similarity metrics (COS, L2, IP) with score semantics
  • efSearch / nProbes query-time tuning, filtered search, exact brute-force search
  • Full parameter reference tables for both index types

Geospatial search

  • 2d and 2dsphere index creation, GeoJSON and legacy coordinate storage
  • $geoNear aggregation stage (spherical + Cartesian), $geoWithin with $box/$geometry/$center/$centerSphere
  • Parameter reference for both index types

Full-text search

  • Single / compound / wildcard text indexes (RUM-backed)
  • $text operator: phrase, negation, OR syntax; language/stemming support; textScore projection

Also adds a search-guide link to the README Helpful Links section, and a Combining Search Types + Index Management section.

Verification

Every operator, kind string, parameter name, and similarity metric was cross-checked against the source in pg_documentdb/src (create_indexes.c, bson_aggregation_vector_search.c, opclass/, etc.). No invented features.

Notes

  • Draft PR — docs only, no code changes.
  • DCO sign-off included.

New docs/search-guide.md covers all three DocumentDB search capabilities
with index creation examples, sample queries, parameter references, and
pymongo/mongosh code snippets.

- Vector search: HNSW and IVF index creation; $search/cosmosSearch and
  $vectorSearch aggregation stages; similarity metrics (COS, L2, IP);
  efSearch/nProbes tuning; filtered and exact search; score projection
- Geospatial search: 2d and 2dsphere index creation; $geoNear aggregation
  stage with spherical/Cartesian distance; $geoWithin query operator with
  $box, $geometry, $center, $centerSphere shapes; parameter reference
- Full-text search: text index creation (single, compound, wildcard);
  $text operator with phrase, negation, and OR syntax; language/stemming
  support; textScore projection; parameter reference

Also adds search-guide link to README Helpful Links section alongside
the existing architecture and build-from-source references.

Signed-off-by: richardsimmonds <richardsimmonds314@gmail.com>
@richardsimmonds

Copy link
Copy Markdown
Owner Author

Docs Review — NEEDS CHANGES

Overall this is a solid first pass. The structure is logical, the examples are readable, and the coverage is broad. The cross-check against source (create_indexes.c, vector_common.h, vector_index_kind_impl.c) caught four factual errors and two broken links that will mislead users or fail at runtime.

Blocking issues (must fix before merge)

  1. Max dimensions is wrong2000 is only the non-compressed limit. Actual max is 16000 (with compression). The HNSW vs IVF comparison table and both parameter reference tables show 2000 unconditionally. Source: VECTOR_MAX_DIMENSIONS = 16000, VECTOR_MAX_DIMENSIONS_NON_COMPRESSED = 2000 in pg_documentdb/include/vector/vector_common.h. (search-guide.md lines 102, 354-355)

  2. efSearch default is wrong — inline comment and parameter table say 2*k. The actual constant is HNSW_DEFAULT_EF_SEARCH = 40 (same header file). (search-guide.md lines 199, 357)

  3. nProbes default is wrong — documented as numLists, but CalculateIVFSearchParamBson() in vector_index_kind_impl.c calculates it dynamically based on collection size: small collections (< 10,000 rows) use numLists; larger ones use ceil(10000 / rowsPerCluster) capped at numLists. The static numLists claim is not accurate. (search-guide.md lines 216, 366)

  4. textIndexVersion default / guidance is wrong — table says default 3 with "Use 3 (current)". Code (create_indexes.c:1647) defaults to 2 internally, and line 4306 throws COMMANDNOTSUPPORTED for any value other than 2. Passing 3 will cause every createIndex call that sets this field to fail at runtime. (search-guide.md line 784)

Blocking issues in README

  1. Two broken links — Lines 170-171 add links to docs/build-from-source.md and docs/architecture.md. Neither file exists in this repo (checked both main and this branch). They will 404 immediately on merge. Either remove those two lines from this PR, or add stub files here.

Non-blocking notes

  • The compression parameter ("none", "half", "pq") is a real accepted field for cosmosSearchOptions that also determines the actual max dimensions (non-compressed: 2000, half: 4000, pq: 16000). The guide never mentions it. Worth a brief note since compression is the only way to exceed 2000 dimensions.
  • The $geoNear parameter table marks key as Required. The code at bson_geospatial_geonear.c:539 defaults to empty string when key is missing — it's only functionally required when the collection has multiple geospatial indexes. Suggest: "Recommended; required when multiple geospatial indexes exist on the collection."
  • textIndexVersion row: once issue 4 is fixed, just say default 2, only version 2 currently supported, no mention of 3.
  • DCO sign-off present on the commit. OK.

Review by docs-reviewer (Hermes Agent)

@richardsimmonds richardsimmonds left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inline comments attached — see summary comment above for full verdict.

Comment thread docs/search-guide.md
| **Query time** | Faster, better recall | Slightly slower, tunable |
| **Memory** | Higher | Lower |
| **Tune at query time** | `efSearch` | `nProbes` |
| **Max dimensions** | 2000 | 2000 |

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accuracy error. Max dimensions shows 2000 for both HNSW and IVF, but 2000 is only the non-compressed limit. Source: VECTOR_MAX_DIMENSIONS = 16000, VECTOR_MAX_DIMENSIONS_NON_COMPRESSED = 2000 in pg_documentdb/include/vector/vector_common.h. Consider: '2000 (uncompressed; up to 4000 with half-compression, 16000 with pq)' — or add a 'compression' row. Either way the current 2000 is misleading for anyone using large embedding models.

Comment thread docs/search-guide.md
vector: queryEmbedding,
path: "embedding",
k: 5,
efSearch: 40 // higher = better recall, slower (default: 2*k, min: 1)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accuracy error. Comment says default: 2*k. The actual constant is HNSW_DEFAULT_EF_SEARCH = 40 (pg_documentdb/include/vector/vector_common.h:42). Change to // higher = better recall, slower (default: 40, min: 1).

Comment thread docs/search-guide.md
vector: queryEmbedding,
path: "visual_embedding",
k: 10,
nProbes: 20 // higher = better recall, slower (default: numLists, min: 1)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accuracy error. Comment says default: numLists. The actual default is dynamically calculated in CalculateIVFSearchParamBson() (vector_index_kind_impl.c): for collections < 10,000 rows the default is numLists; for larger collections it's ceil(10000 / rowsPerCluster) capped at numLists. Suggest: // omit to let DocumentDB choose based on collection size (default: 1 when index metadata unavailable) — or just drop the default note and point readers to the parameter table.

Comment thread docs/search-guide.md
| `dimensions` | Yes | int | — | 1–2000 | Vector length |
| `m` | No | int | 16 | 2–100 | Max connections per HNSW layer. Higher = better recall, more memory |
| `efConstruction` | No | int | 64 | must be >= 2*m | Build-time beam width. Higher = better recall at build time |
| At query time: `efSearch` | No | int | 2*k | >= 1 | Search beam width. Higher = better recall at query time |

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accuracy error. Parameter table says default 2*k. Should be 40 — matches HNSW_DEFAULT_EF_SEARCH constant in vector_common.h.

Comment thread docs/search-guide.md
| `similarity` | Yes | string | — | `"COS"`, `"L2"`, `"IP"` | Distance metric |
| `dimensions` | Yes | int | — | 1–2000 | Vector length |
| `numLists` | No | int | 100 | >= 1 | Number of IVF clusters. Aim for sqrt(N) |
| At query time: `nProbes` | No | int | `numLists` | >= 1 | Clusters to probe. Higher = better recall |

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accuracy error. Parameter table says default numLists. The actual default is dynamically calculated (see inline comment at line 216). Remove the static value or replace with 'dynamic; see query-time tuning note'.

Comment thread docs/search-guide.md
| Parameter | Default | Description |
|-----------|---------|-------------|
| `default_language` | `"en"` | Language for stemming and stop-word filtering |
| `textIndexVersion` | 3 | Text index version. Use 3 (current) |

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accuracy error — will cause runtime failure. Default is 3, guidance says 'Use 3 (current)'. The code at create_indexes.c:1647 sets the internal default to 2, and line 4306 throws COMMANDNOTSUPPORTED for any value other than 2. If a user follows this doc and passes textIndexVersion: 3, their createIndex call will fail. Fix: change default to 2, guidance to 'Only version 2 is currently supported'.

Comment thread README.md
- Check out our [website](https://documentdb.io) to stay up to date with the latest on the project.
- Contributors and users can join the [DocumentDB Discord channel](https://discord.gg/vH7bYu524D) for quick collaboration.
- Check out [FerretDB](https://github.com/FerretDB/FerretDB) and their integration of DocumentDB as a backend engine.
- Want to build from source, run tests locally, or hack on the extensions? See [docs/build-from-source.md](docs/build-from-source.md).

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Broken link. docs/build-from-source.md does not exist in this repo (not in main, not in this branch). Will 404 on merge. Remove this line from this PR, or add a stub file.

Comment thread README.md
- Contributors and users can join the [DocumentDB Discord channel](https://discord.gg/vH7bYu524D) for quick collaboration.
- Check out [FerretDB](https://github.com/FerretDB/FerretDB) and their integration of DocumentDB as a backend engine.
- Want to build from source, run tests locally, or hack on the extensions? See [docs/build-from-source.md](docs/build-from-source.md).
- Curious how the components fit together? See [docs/architecture.md](docs/architecture.md) for the data flow, wire protocol translation, and BSON type system overview.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Broken link. docs/architecture.md does not exist in this repo (not in main, not in this branch). Same issue — remove or stub.

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.

1 participant