Skip to content

Conversation

eramongodb
Copy link
Contributor

@eramongodb eramongodb commented Sep 16, 2025

Summary

Followup to #1447 and analogous to #1401 for bsoncxx.

As in #1401, this PR is a "lightweight" preview of the mongocxx::v1 interface, file structure, and class (+ some enumeration) API documentation. Unlike #1401, this PR includes declarations of some member classes and enumerations in advance to clarify relocated equivalents to v_noabi non-member classes and enumerations.

Most of the proposed v_noabi -> v1 relative changes are due to relocations and renaming of types to address CXX-1826:

Everything is nested way too deeply in namespaces, but requires those namespaces to disambiguate radically different types, e.g. bsoncxx::builder::basic::document and bsoncxx::builder::stream::document.

and CXX-1836

The types in the mongocxx::options namespace are confusingly separated from the types they are options for. Why mongocxx::options::transaction and not mongocxx::transaction::options?

To address both of these issues, the v_noabi::options and v_noabi::result namespaces+components are removed in favor of *_options and *_result suffixes instead. Options and result types specific to an existing class are made members of that class (e.g. v_noabi::options::* -> v1::*::options). The only nested namespaces remaining are v1::gridfs and v1::events.

Relative Changelog (v_noabi -> v1)

  • Added
    • v1::source_errc and v1::type_errc (same pattern as for bsoncxx::v1).
  • Changed
    • v_noabi::operation_exception -> v1::server_error
      • Mirroring C++ standard library's *_error suffix pattern.
      • CXX-834 no dedicated error code enumerations for external libraries (including mongoc and mongocrypt!): only unspecified error categories to define comparisons with v1::source_errc and v1::type_errc. User's responsibility to compare the int against library-specific error codes.
    • v_noabi::result::<command> -> v1::<command>_result
      • Related commands:
        • delete -> delete_one + delete_many
        • insert_one
        • insert_many
        • replace_one
        • rewrap_many_datakey
        • update -> update_one + update_many
      • Mirroring C++ standard library's *_result suffix pattern.
    • v_noabi::options::<command> -> v1::<command>_options
      • Related commands:
        • aggregate
        • count
        • delete -> delete_one + delete_many
        • distinct
        • encrypt
        • estimated_document_count
        • find + find_one_and_*
          • find_one_common_options -> return_document
        • options::gridfs::upload -> gridfs::upload_options
        • insert -> insert_one + insert_many
        • replace -> replace_one
        • update -> update_one + update_many
      • Symmetry with *_result pattern: <command>(): <command>_options + <command>_result.
      • Limited to options for commands with the same name (e.g. .count() vs. count_options). The _options suffix is not used for options-only types for non-commands (e.g. .apm_opts() vs. apm).
        "Options" classes which do not have the *_options suffix and are not nested in another class:
        • hint
        • apm
        • auto_encryption
        • range
        • server_api
        • tls
        • read_concern
        • read_preference
        • write_concern
    • v_noabi::events::<name>_event -> v_noabi::events::<name>
      • Related changes to improve naming consistency with specifications:
        • heartbeat_*_event -> server_heartbeat_*
        • topology_changed_event -> topology_description_changed
        • server_changed_event -> server_description_changed
      • Avoid events::*_event redundancy without possibility of conflation or confusion with overloaded terminology (unlike view, <command>, etc.).
    • v_noabi::index_view -> v1::indexes
      • Related:
        • v_noabi::index_model -> v1::indexes::model
        • v_noabi::options::index_view -> v1::indexes::options
        • v_noabi::options::index -> v1::indexes::options (merge index-related options into a single class; no clear reason to keep separate).
      • Avoid "view" vs. "value" conflation and "single" vs. "many" confusion.
      • Plural: does not represent a single specific index (unlike "database", "collection", "bucket", etc.).
    • v_noabi::search_index_view -> v1::search_indexes
      • Related:
        • v_noabi::search_index_model -> v1::search_indexes::model
      • For reasons similar to v1::indexes.
    • v_noabi::model::<command> -> v1::bulk_write::<command> (bulk write commands)
      • Related:
        • v_noabi::model::write -> v1::bulk_write::single
        • v_noabi::options::bulk_write -> v1::bulk_write::options
        • v_noabi::write_type -> v1::bulk_write::type
      • Clearly associate bulk write operations with v1::bulk_write as members.
    • v_noabi::server_api -> v1::stable_api
      • Better consistency with latest terminology (after several renames, e.g. formerly "Versioned API").
  • Removed
    • All exception classes that are not v1::exception or v1::server_error:
      • authentication_exception
      • bulk_write_exception
        • -> v1::server_error with v1::bulk_write::errc error codes.
      • gridfs_exception
        • -> v1::exception with v1::gridfs::*::errc (bucket, downloader, uploader).
      • logic_error
        • Reserved for future use by an internal exception-based contract violation framework.
      • query_exception
        • -> v1::exception with an unspecified error code that compares equal to v1::source_errc::mongoc or v1::source_errc::crypt.
        • -> v1::server_error with an unspecified error code that compares equal to v1::source_errc::server.
      • write_exception
        • -> v1::server_error with an unspecified error code that compares equal to v1::source_errc::server.
    • v_noabi::events::topology_description::server_descriptions
      • Just transform elements into std::vector<server_description> instead. The intermediate owning array returned by mongoc_client_get_server_descriptions() does not need to be preserved.
    • v_noabi::validation_criteria
    • v_noabi::options::index::*_storage_options
    • v_noabi::options::ssl
      • Deprecated by CXX-1681 in favor of tls.

@eramongodb eramongodb self-assigned this Sep 16, 2025
///
/// @attention This feature is experimental! It is not ready for use!
///
class options {};
Copy link
Contributor Author

Choose a reason for hiding this comment

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

v_noabi::options::index seems to be nearly-completely obsoleted by v_noabi::options::index_view. It's only current usage is in:

  • Isolated test and example code: easily replaceable.
  • v_noabi::gridfs::bucket::create_indexes_if_nonexistent: private API, easily replaceable.
  • v_noabi::options::index::operator bsoncxx::v_noabi::document::view_or_value: to support the deprecated *_storage_options API (not included in v1).

Therefore, v1::indexes::options will merge and fulfill the role of both the old index and index_view options classes.

///
/// Support for MongoDB indexes.
///
/// @note Not to be confused with Atlas Search indexes or Atlas Vector Search indexes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The distinction between index and index_view does not seem valuable (perhaps it might have been when CXX-1360 was resolved in Jun 2017...?). Besides the unnecessary "view" vs. "value" terminology (a la bsoncxx API), it may also be confused with MongoDB standard or on-demand materialized views as pertains to aggregation pipelines, which this class is not directly related to:

Standard views use the indexes of the underlying collection. As a result, you cannot create, drop or re-build indexes on a standard view directly, nor get a list of indexes on the view. You can create indexes directly on on-demand materialized views because they are stored on disk.

Copy link
Collaborator

Choose a reason for hiding this comment

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

The Index Management spec defines two APIs:

All drivers MUST offer at least one of the sections of operations, the Standard API or the Index View API. The driver MAY elect to have both.

The v_noabi API appears to only partially implement the Standard API (e.g. no collection::drop_index). I expect v1::indexes will serve as the Index View API.

I would also like to avoid the overloaded "view". The spec says this about naming:

When deviating from a defined name, an author should consider if the altered name is recognizable and discoverable to the user of another driver.

However, surveying other drivers found C#, Go, and Ruby implement the Index View API. C# uses a similarly named Indexes method to get the Index View. I expect "Indexes" is a discoverable API name for wanting to manage indexes, and I expect the distinction between the two APIs would not matter to most users.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do we want to leave a note/ticket to split v1::indexes::options (IndexOptions) into command-specific options classes for better accuracy with the Index View API specification (v1::indexes::create_one_options, v1::indexes::create_many_options, etc.) as done for the regular database command option classes (insert_one_options, insert_many_options, etc.)?

Copy link
Collaborator

Choose a reason for hiding this comment

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

No strong opinion. I am slightly in favor to split the options for spec and CRUD API consistency. But arguably, there is not much need since the options do not-yet differ from the combined options:

interface CreateOneIndexOptions {
  // same as CreateIndexOptions in the Standard API
}

interface CreateManyIndexesOptions {
  // same as CreateIndexesOptions in the Standard API
}

Comment on lines +26 to +32
///
/// `returnDocument` from the CRUD API specification.
///
/// @see
/// - [CRUD API (MongoDB Specifications)](https://www.mongodb.com/docs/manual/reference/command/return_document/)
///
enum class return_document {};
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This replaces v_noabi::options::find_one_common_options as a more specific and direct component+class name describing its actual purpose (representing the returnDocument field option).

Comment on lines +26 to +33
///
/// A connection to a MongoDB deployment.
///
/// @important This interface does NOT fully conform to the CMAP specification!
///
/// @see
/// - [Connection Monitoring and Pooling (MongoDB Specifications)](https://specifications.readthedocs.io/en/latest/connection-monitoring-and-pooling/connection-monitoring-and-pooling/)
/// - [Connection Strings (MongoDB Manual)](https://www.mongodb.com/docs/manual/reference/connection-string/)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This PR proposes deferring as much documentation as possible into "See Also" links to MongoDB Manual or MongoDB Specification pages (+ occasionally mongoc API docs). C++ Driver API documentation is and should be specific to behaviors specific to the C++ Driver, not the MongoDB server behavior or other libraries.

Also added the "Important" note to several API docs clarifying that these are not CMAP-compliant, which can be relevant for certain APM event-handling, (unstructured) logging, and error handling behavior.

Comment on lines 26 to 36
///
/// Options related to field encryption for CSFLE and Queryable Encryption.
///
/// @see
/// - [Fields and Encryption Types (MongoDB Manual)](https://www.mongodb.com/docs/manual/core/csfle/fundamentals/encryption-algorithms/)
/// - [Encrypted Fields and Enabled Queries (MongoDB Manual)](https://mongodb.com/docs/manual/core/queryable-encryption/fundamentals/encrypt-and-query/)
/// - [Encryption Schemas](https://www.mongodb.com/docs/manual/core/csfle/fundamentals/create-schema/)
///
/// @attention This feature is experimental! It is not ready for use!
///
class encrypt {};
Copy link
Contributor Author

@eramongodb eramongodb Sep 16, 2025

Choose a reason for hiding this comment

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

The "encrypt" options class is overloaded in usage with both the .encrypt() database command as well as options pertaining to encrypted field configuration for CSFLE and Queryable Encryption. Unlike the <command>_one vs. <command>_many splits, this one was too complicated to attempt to split up by refined purpose as part of the v_noabi -> v1 migration effort. Perhaps it may be revisited in the future.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I expect v_noabi::options::encrypt model EncryptOpts from the spec. I expect these are only used for explicit encryption (client_encryption.encrypt()).

@eramongodb eramongodb marked this pull request as ready for review September 16, 2025 18:59
@eramongodb eramongodb requested a review from a team as a code owner September 16, 2025 18:59
Copy link
Collaborator

@kevinAlbs kevinAlbs left a comment

Choose a reason for hiding this comment

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

I very much like to flattening of option/result namespaces.

///
/// Support for MongoDB indexes.
///
/// @note Not to be confused with Atlas Search indexes or Atlas Vector Search indexes.
Copy link
Collaborator

Choose a reason for hiding this comment

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

The Index Management spec defines two APIs:

All drivers MUST offer at least one of the sections of operations, the Standard API or the Index View API. The driver MAY elect to have both.

The v_noabi API appears to only partially implement the Standard API (e.g. no collection::drop_index). I expect v1::indexes will serve as the Index View API.

I would also like to avoid the overloaded "view". The spec says this about naming:

When deviating from a defined name, an author should consider if the altered name is recognizable and discoverable to the user of another driver.

However, surveying other drivers found C#, Go, and Ruby implement the Index View API. C# uses a similarly named Indexes method to get the Index View. I expect "Indexes" is a discoverable API name for wanting to manage indexes, and I expect the distinction between the two APIs would not matter to most users.

Copy link
Contributor Author

@eramongodb eramongodb left a comment

Choose a reason for hiding this comment

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

Sorry for the premature push -> rebase (revert).

///
/// Support for MongoDB indexes.
///
/// @note Not to be confused with Atlas Search indexes or Atlas Vector Search indexes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do we want to leave a note/ticket to split v1::indexes::options (IndexOptions) into command-specific options classes for better accuracy with the Index View API specification (v1::indexes::create_one_options, v1::indexes::create_many_options, etc.) as done for the regular database command option classes (insert_one_options, insert_many_options, etc.)?

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