diff --git a/docs/reference/schema-operations.txt b/docs/reference/schema-operations.txt
index 6d3617302a..8d67d569fb 100644
--- a/docs/reference/schema-operations.txt
+++ b/docs/reference/schema-operations.txt
@@ -15,4 +15,5 @@ including managing databases, collections, indexes and users.
/reference/database-tasks
/reference/collection-tasks
/reference/indexing
+ /reference/search-indexes
/reference/collations
diff --git a/docs/reference/search-indexes.txt b/docs/reference/search-indexes.txt
new file mode 100644
index 0000000000..91f99670f7
--- /dev/null
+++ b/docs/reference/search-indexes.txt
@@ -0,0 +1,129 @@
+********************
+Atlas Search Indexes
+********************
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+ :local:
+ :backlinks: none
+ :depth: 1
+ :class: singlecol
+
+If you are using a database hosted by MongoDB Atlas, the driver provides the
+ability to create, drop and view `Atlas search indexes `_
+on a collection through the ``search_indexes`` attribute:
+
+.. code-block:: ruby
+
+ client = Mongo::Client.new(your_atlas_uri, database: 'music')
+ client[:bands].search_indexes
+ # => # ...>
+
+
+Creating Search Indexes
+=======================
+
+Search indexes can be created one at a time, or several can be created in
+parallel in a single operation.
+
+To create a single index, use ``search_indexes#create_one``, passing the index
+definition as the first argument, and an optional name for the index as the
+second argument.
+
+.. code-block:: ruby
+
+ client[:bands].search_indexes.create_one({ dynamic: true })
+
+ client[:bands].search_indexes.create_one(
+ {
+ dynamic: false,
+ fields: {
+ name: { type: 'string', analyzer: 'lucene.simple' }
+ }
+ },
+ 'band-name-index'
+ )
+
+To create multiple indexes, use ``search_indexes#create_many`` which accepts
+an array of index specifications. Unlike ``create_one``, each index
+specification is a hash with at least a ``definition`` key, which
+defines the index. Each has may also specify a ``name`` key, to name
+the index.
+
+.. code-block:: ruby
+
+ client[:bands].search_indexes.create_many([
+ { definition: { dynamic: true } },
+ { name: 'band-name-index,
+ definition: {
+ dynamic: false,
+ fields: {
+ name: { type: 'string', analyzer: 'lucene.simple' }
+ }
+ }
+ },
+ ])
+
+Note that whether you call ``create_one`` or ``create_many``, the
+method will return immediately, before the indexes are created. The
+indexes are then created in the background, asynchronously.
+
+
+Update Search Indexes
+=====================
+
+You can programmatically update an Atlas search index. For example, you
+might do this to change the analyzer used, or to provide an explicit field
+mapping, instead of a dynamic one. To do this, use the ``search_indexes#update_one``
+method:
+
+.. code-block:: ruby
+
+ client[:bands].search_indexes.update_one(new_definition, id: index_id)
+
+ client[:bands].search_indexes.update_one(new_definition, name: index_name)
+
+Indexes may be identified by either id, or name, but you must specify one
+or the other. The new index definition must be a complete definition--it will
+take precedence as specified over the existing definition.
+
+To get the id or name of an index that you wish to update, you can
+`list the search indexes <#listing-search-indexes>`_.
+
+
+Dropping Search Indexes
+=======================
+
+To drop Atlas search indexes, call ``search_indexes#drop_one`` and
+provide either the ``id`` or the ``name`` of the index you wish to
+drop.
+
+.. code-block:: ruby
+
+ client[:bands].search_indexes.drop_one(id: index_id)
+
+ client[:bands].search_indexes.drop_one(name: index_name)
+
+In either case, the method will return immediately and the index will
+be dropped in the background, asynchronously.
+
+To get the id or name of an index that you wish to drop, you can
+`list the search indexes <#listing-search-indexes>`_.
+
+
+Listing Search Indexes
+======================
+
+To list the available search indexes, iterate over the
+``search_indexes`` object:
+
+.. code-block:: ruby
+
+ client[:bands].search_indexes.each do |index_spec|
+ p index_spec['id']
+ p index_spec['name']
+ p index_spec['status']
+ p index_spec['queryable']
+ p index_spec['latestDefinition']
+ end
diff --git a/docs/release-notes.txt b/docs/release-notes.txt
index f8eebf104a..d69063a17e 100644
--- a/docs/release-notes.txt
+++ b/docs/release-notes.txt
@@ -42,10 +42,12 @@ This release includes the following new features:
when Azure Key Vault is used for client side encryption.
- `Queryable Encryption `_ support is extended.
- Added support for Queryable Encryption Range Indexes.
-- A `crypt_shared `_
+- A `crypt_shared `_
library can be now used instead of ``mongocryptd``.
- Added support for AWS IAM Roles for service accounts, EKS in particular.
- AWS Credentials are now cached when possible.
+- Added support for creating and managing `Atlas search indexes `_ via the
+ Ruby driver.
.. _release-notes-2.18:
diff --git a/gemfiles/standard.rb b/gemfiles/standard.rb
index ca63921b8f..60a710586f 100644
--- a/gemfiles/standard.rb
+++ b/gemfiles/standard.rb
@@ -49,6 +49,7 @@ def standard_dependencies
group :testing do
gem 'timecop'
gem 'ice_nine'
+ gem 'async-io', '~> 1.36.0' # 1.37.0 introduced a regression that breaks on Ruby 2.5, 2.6
gem 'rubydns', platforms: :mri
gem 'rspec-retry'
gem 'rfc', '~> 0.2.0'
diff --git a/lib/mongo/version.rb b/lib/mongo/version.rb
index 119302c0dd..3fc377862e 100644
--- a/lib/mongo/version.rb
+++ b/lib/mongo/version.rb
@@ -20,5 +20,5 @@ module Mongo
# The current version of the driver.
#
# @since 2.0.0
- VERSION = '2.19.2'.freeze
+ VERSION = '2.19.3'.freeze
end
diff --git a/release/mri/Dockerfile b/release/mri/Dockerfile
index b6da2a23c7..68c21a15ac 100644
--- a/release/mri/Dockerfile
+++ b/release/mri/Dockerfile
@@ -3,7 +3,7 @@ FROM debian:10
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && \
- apt-get -y install git ruby-bundler make gcc ruby-dev
+ apt-get -y install zlib1g-dev git ruby-bundler make gcc ruby-dev
WORKDIR /app