From a8b42fc547af281dc789f1eaff42aa3b2c3d33b2 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Thu, 17 Oct 2024 08:37:08 -0500 Subject: [PATCH 01/35] compat changes --- source/compatibility.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/compatibility.txt b/source/compatibility.txt index ce124f4b..ec543b32 100644 --- a/source/compatibility.txt +++ b/source/compatibility.txt @@ -29,7 +29,7 @@ The first column lists the driver version. .. sharedinclude:: dbx/compatibility-table-legend.rst -.. include:: /includes/mongodb-compatibility-table-csharp.rst +.. sharedinclude:: dbx/mongodb-compatibility-table-csharp.rst Language Compatibility ---------------------- @@ -39,7 +39,7 @@ The following compatibility table specifies the recommended version of the The first column lists the driver version. -.. include:: /includes/language-compatibility-table-csharp.rst +.. sharedinclude:: dbx/language-compatibility-table-csharp.rst For more information on how to read the compatibility tables, see our guide on :ref:`MongoDB Compatibility Tables. ` From fcc74c6392b06c8b15d8f97b96d10aeab173f1f6 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Fri, 18 Oct 2024 08:05:59 -0500 Subject: [PATCH 02/35] DOCSP-43148 - Refactor AWS authentication (#258) Co-authored-by: Jordan Smith <45415425+jordan-smith721@users.noreply.github.com> (cherry picked from commit 1d75584da4e004cc1ff8fb39169db45072a141e7) --- source/fundamentals/authentication.txt | 24 +++++++++++++++++++----- source/upgrade/v3.txt | 7 ++++++- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/source/fundamentals/authentication.txt b/source/fundamentals/authentication.txt index 6152db22..931a1e64 100644 --- a/source/fundamentals/authentication.txt +++ b/source/fundamentals/authentication.txt @@ -153,12 +153,26 @@ MONGODB-AWS The ``MONGODB-AWS`` authentication mechanism is available only for MongoDB deployments on MongoDB Atlas. -The ``MONGODB-AWS`` authentication mechanism uses your Amazon Web Services -Identity and Access Management (AWS IAM) credentials to authenticate your -user. You can either specify your credentials explicitly -or instruct the driver to retrieve them automatically from an external source. +The ``MONGODB-AWS`` authentication mechanism uses Amazon Web Services +Identity and Access Management (AWS IAM) credentials to authenticate a user to MongoDB. -The following sections contain code examples that use the following placeholders: +To use AWS authentication, first perform the following steps: + +- Add the `MongoDB.Driver.Authentication.AWS `__ + NuGet package to your project. +- Add the following line of code to your application's bootstrap code to register the + AWS authentication provider: + + .. code-block:: csharp + :copyable: true + + MongoClientSettings.Extensions.AddAWSAuthentication(); + +After you register the AWS authentication provider, you can either specify the AWS IAM +credentials explicitly or instruct the driver to retrieve them automatically from an +external source. The following sections describe both of these methods. + +The code examples in these sections use the following placeholders: - ```` - value of the AWS access key ID - ```` - value of the AWS secret access key diff --git a/source/upgrade/v3.txt b/source/upgrade/v3.txt index 759b65af..66ec0a0c 100644 --- a/source/upgrade/v3.txt +++ b/source/upgrade/v3.txt @@ -150,6 +150,11 @@ Version 3.0 Breaking Changes - The ``MongoClient`` constructor accepts only one ``Credential`` object instead of an array. +- To use Amazon Web Services (AWS) authentication, you must add the + ``MongoDB.Driver.Authentication.AWS`` package to your project and register the + authentication provider in your application's bootstrap code. To learn more about + using AWS authentication with the {+driver-short+}, see :ref:`csharp-mongodb-aws`. + - If you try to serialize or deserialize a floating-point ``Infinity`` or ``NaN`` value to an integral representation, the driver throws an ``OverflowException``. To learn more about floating-point ``Infinity`` and ``NaN`` @@ -157,4 +162,4 @@ Version 3.0 Breaking Changes `Double.NaN, `__ `Double.PositiveInfinity, `__ and `Double.NegativeInfinity. `__ - on MSDN. \ No newline at end of file + on MSDN. From 9ec74f8a30dddecc73ead62dacd679ab02a55969 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Fri, 18 Oct 2024 12:23:23 -0500 Subject: [PATCH 03/35] DOCSP-44476 - BsonValue properties (#256) (cherry picked from commit dd333de276499c9fa6f373acc51ebface1fe8f1f) --- source/upgrade/v3.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/source/upgrade/v3.txt b/source/upgrade/v3.txt index 66ec0a0c..c0619dc5 100644 --- a/source/upgrade/v3.txt +++ b/source/upgrade/v3.txt @@ -163,3 +163,15 @@ Version 3.0 Breaking Changes `Double.PositiveInfinity, `__ and `Double.NegativeInfinity. `__ on MSDN. + +- The driver includes the following changes to the ``BsonValue`` class: + + - Removes the ``[Obsolete]`` attribute from the ``AsLocalTime`` and + ``AsUniversalTime`` properties. + - Adds the `AsNullableLocalTime <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonValue.AsNullableLocalTime.html#MongoDB_Bson_BsonValue_AsNullableLocalTime>`__ + and `AsNullableUniversalTime <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonValue.AsNullableUniversalTime.html#MongoDB_Bson_BsonValue_AsNullableUniversalTime>`__ + properties. + - Removes the ``AsDateTime`` property. Use the `AsUniversalTime <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonValue.AsUniversalTime.html#MongoDB_Bson_BsonValue_AsUniversalTime>`__ + property instead. + - Removes the ``AsNullableDateTime`` property. Use the `AsNullableUniversalTime <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonValue.AsNullableUniversalTime.html#MongoDB_Bson_BsonValue_AsNullableUniversalTime>`__ + property instead. \ No newline at end of file From a5d5937dece0ef6c2ce7c78d1372b850b515e7ba Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Mon, 21 Oct 2024 11:27:39 -0400 Subject: [PATCH 04/35] (DOCSP-44251) Removed EOL'd v2.20 and v2.19 (#262) Co-authored-by: your proper name --- source/whats-new.txt | 32 +------------------------------- 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/source/whats-new.txt b/source/whats-new.txt index a4c51e9d..8ef5042f 100644 --- a/source/whats-new.txt +++ b/source/whats-new.txt @@ -30,8 +30,6 @@ Learn what's new in: * :ref:`Version 2.23 ` * :ref:`Version 2.22 ` * :ref:`Version 2.21 ` -* :ref:`Version 2.20 ` -* :ref:`Version 2.19 ` .. _upcoming-breaking-changes: @@ -353,32 +351,4 @@ The 2.21 driver release includes the following new features: - Accepts options for Atlas Search sorting, tracking, and scoring. - Supports the Atlas Search :atlas:`embeddedDocument ` operator. - Offers an API for Atlas Search index management. -- Accepts anonymous types in the ``ObjectSerializer.DefaultAllowedTypes`` method. - -.. _version-2.20: - -What's New in 2.20 ------------------- - -The 2.20 driver release includes the following new features: - -- Added full support for {+mdb-server+} version 7.0.0. -- Added support for equality query types in Queryable Encryption GA. -- Improvements to LINQ3 integration. -- Improvements to serialization features. -- Improvements to the logging framework. - -.. _version-2.19: - -What's New in 2.19 ------------------- - -The 2.19 driver release includes the following new features: - -- The ``ObjectSerializer`` allows deserialization of only safe types, as determined by - the configurable ``AllowedTypes`` function. -- Changed the default ``LinqProvider`` to LINQ3. -- Added Atlas Search (``$search``) support to builders, aggregation pipelines, and LINQ3. -- Added support for ``$bucket`` and ``$bucketAuto`` aggregation pipeline stages in LINQ3. -- Added support for automatic KMS credentials for Azure VM Managed Identities. -- Added native support for AWS IAM roles. +- Accepts anonymous types in the ``ObjectSerializer.DefaultAllowedTypes`` method. \ No newline at end of file From 35be495d0e5070bb9cf9466e1957dd4775e1a798 Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Mon, 21 Oct 2024 13:46:50 -0400 Subject: [PATCH 05/35] Fix broken 3.0 link (#266) (cherry picked from commit 42bd42f11821eee143880e43277c4dc222b50989) --- source/fundamentals/enterprise-authentication.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/fundamentals/enterprise-authentication.txt b/source/fundamentals/enterprise-authentication.txt index fdc07b44..95dedec6 100644 --- a/source/fundamentals/enterprise-authentication.txt +++ b/source/fundamentals/enterprise-authentication.txt @@ -446,4 +446,4 @@ guide, see the following API Documentation: - `MongoClientSettings <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.MongoClientSettings.html>`__ - `CreateGssapiCredential() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.MongoCredential.CreateGssapiCredential.html>`__ - `CreatePlainCredential() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.MongoCredential.CreatePlainCredential.html>`__ -- `IOidcCallback <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Core.Authentication.Oidc.IOidcCallback.html>`__ +- `IOidcCallback <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Authentication.Oidc.IOidcCallback.html>`__ From 5888fc65989e158550d87469245c1594b464b6f6 Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Mon, 21 Oct 2024 14:26:10 -0400 Subject: [PATCH 06/35] DOCSP-44588: Add trailing slash to Analyzer URL (#267) (cherry picked from commit be18c2436e5d325269da914e4ab4fcb4bdf8c7ed) --- source/index.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/index.txt b/source/index.txt index 616b5043..716ad2c0 100644 --- a/source/index.txt +++ b/source/index.txt @@ -24,7 +24,7 @@ MongoDB C# Driver /compatibility /upgrade Entity Framework Provider - {+analyzer-short+} + {+analyzer-short+} Introduction ------------ From 39c42003b446cf3415a3fe544208f374cf8e18f4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 22 Oct 2024 16:47:42 -0500 Subject: [PATCH 07/35] DOCSP-44438 - Remove nil (#268) (#269) (cherry picked from commit cd5c1b50342e68a44afa125c0b0ed5fbae832fc5) Co-authored-by: Mike Woofter <108414937+mongoKart@users.noreply.github.com> --- source/fundamentals/crud/read-operations/count.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/fundamentals/crud/read-operations/count.txt b/source/fundamentals/crud/read-operations/count.txt index 360c48ac..53dcede1 100644 --- a/source/fundamentals/crud/read-operations/count.txt +++ b/source/fundamentals/crud/read-operations/count.txt @@ -99,19 +99,19 @@ You can set the following properties in a ``CountOptions`` object: * - ``Collation`` - | The type of language collation to use when sorting results. - | Default: ``nil`` + | Default: ``null`` * - ``Hint`` - | The index to use to scan for documents to count. - | Default: ``nil`` + | Default: ``null`` - * - ``Limit`` + * - ``Limit`` - | The maximum number of documents to count. - | Default: ``0`` + | Default: ``0`` * - ``MaxTime`` - | The maximum amount of time that the query can run on the server. - | Default: ``nil`` + | Default: ``null`` * - ``Skip`` - | The number of documents to skip before counting. @@ -164,7 +164,7 @@ You can set the following properties in a ``EstimatedDocumentCountOptions`` obje * - ``MaxTime`` - | The maximum amount of time that the query can run on the server. - | Default: ``nil`` + | Default: ``null`` Example ``````` From 0732a9418a53c300a9b0747b896a97b1a3bf6dbc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 22 Oct 2024 17:18:29 -0500 Subject: [PATCH 08/35] v3 Post-Release Updates (#265) (#280) (cherry picked from commit 4409e9ee210e18633fe2449202c2186734e8af2f) Co-authored-by: Mike Woofter <108414937+mongoKart@users.noreply.github.com> --- .../language-compatibility-table-csharp.rst | 5 +++++ source/upgrade/v3.txt | 18 ++++++++++++++++++ source/whats-new.txt | 5 ----- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/source/includes/language-compatibility-table-csharp.rst b/source/includes/language-compatibility-table-csharp.rst index af1eedbb..ea72ea6e 100644 --- a/source/includes/language-compatibility-table-csharp.rst +++ b/source/includes/language-compatibility-table-csharp.rst @@ -45,6 +45,11 @@ - .NET 4.7 [#2.14-note]_ - .NET 4.6 + * - 3.0 + - ✓ + - ✓ + - + * - 2.13 to 2.30 - ✓ - ✓ diff --git a/source/upgrade/v3.txt b/source/upgrade/v3.txt index c0619dc5..46b5f236 100644 --- a/source/upgrade/v3.txt +++ b/source/upgrade/v3.txt @@ -61,6 +61,18 @@ Version 3.0 Breaking Changes and {+mdb-server+} versions, visit the :ref:`Compatibility ` page. +- The driver drops support for .NET Core 2.x and .NET Framework 4.6. You must upgrade to + .NET Core 3.x or later, or .NET Framework 4.7.2 or later. + + To learn more about the compatibility between .NET/C# driver versions + and .NET versions, visit the + :ref:`Compatibility ` page. + +- The driver removes the + `mongocsharpdriver `__ + NuGet package, which implements the legacy v1.x API in driver versions 2.x. + If you're using the v1.x API, you must migrate to the new API. + - The classes, methods, and properties in the ``MongoDB.Driver.Core`` namespace that were deprecated in v{+last-version-2-number+} are marked ``internal``. If the driver provides a replacement for a deprecated class, method, or property, the compiler @@ -155,6 +167,12 @@ Version 3.0 Breaking Changes authentication provider in your application's bootstrap code. To learn more about using AWS authentication with the {+driver-short+}, see :ref:`csharp-mongodb-aws`. +- To use In-Use Encryption, you must add the ``MongoDB.Driver.Encryption`` package to + your project and register the encryption mechanism in your application's bootstrap code. + To learn more about using In-Use Encryption with the {+driver-short+}, see + :manual:`In-Use Encryption ` in the {+mdb-server+} + manual. + - If you try to serialize or deserialize a floating-point ``Infinity`` or ``NaN`` value to an integral representation, the driver throws an ``OverflowException``. To learn more about floating-point ``Infinity`` and ``NaN`` diff --git a/source/whats-new.txt b/source/whats-new.txt index 8ef5042f..d4b88da5 100644 --- a/source/whats-new.txt +++ b/source/whats-new.txt @@ -45,11 +45,6 @@ What's New in 3.0 The 3.0 driver release includes the following new features: -- Removes the - `mongocsharpdriver `__ NuGet package, - which implements the v1.x driver API in driver versions 2.x. This package will no - longer receive updates. - - Adds the ``MongoClientSettings.TranslationOptions`` connection option, which specifies options for translating LINQ queries to the Query API. See :ref:`csharp-connection-options` for more information. From eefde24827c03411848f5dbacdb1ab14323daa35 Mon Sep 17 00:00:00 2001 From: Maya Raman Date: Thu, 24 Oct 2024 11:45:13 -0400 Subject: [PATCH 09/35] DOCSP-34044: Add bitwise operators to aggregation pipeline (#253) * changing code + checkpint * very preliminary first draft * correct code block * code blocks * and and or * xor, not, and other small tweaks * changing variable type in linq.cs * never mind * back to double * addressing basic comments * move code to include * io code block * reworking first sentence * bullet list * bullet list pt 2 * bullet list pt 3 * feedback * nits * change example * correction * snake case * refining note * vale (cherry picked from commit a1b1f4c49032d3ad455cc67ed1a9c0ed5fe4b432) --- .github/workflows/vale-tdbx.yml | 3 + source/fundamentals/linq.txt | 184 +++++++++++++++++- source/includes/convention-pack-note.rst | 2 +- .../fundamentals/code-examples/linq.cs | 57 +++++- 4 files changed, 240 insertions(+), 6 deletions(-) diff --git a/.github/workflows/vale-tdbx.yml b/.github/workflows/vale-tdbx.yml index 284033ab..8e4b6f49 100644 --- a/.github/workflows/vale-tdbx.yml +++ b/.github/workflows/vale-tdbx.yml @@ -12,6 +12,9 @@ jobs: - name: checkout uses: actions/checkout@master + - name: Install docutils + run: sudo apt-get install -y docutils + - id: files uses: masesgroup/retrieve-changed-files@v2 with: diff --git a/source/fundamentals/linq.txt b/source/fundamentals/linq.txt index bf8b4345..491c98e7 100644 --- a/source/fundamentals/linq.txt +++ b/source/fundamentals/linq.txt @@ -7,7 +7,7 @@ LINQ .. contents:: On this page :local: :backlinks: none - :depth: 2 + :depth: 3 :class: singlecol .. facet:: @@ -73,10 +73,11 @@ object that links to the collection. To create the object, use the ``AsQueryable as follows: .. code-block:: csharp - :emphasize-lines: 2 + :emphasize-lines: 3 - var restaurantsCollection = restaurantsDatabase.GetCollection("restaurants"); - var queryableCollection = restaurantsCollection.AsQueryable(); + var restaurantsDatabase = client.GetDatabase("sample_restaurants"); + var restaurantsCollection = restaurantsDatabase.GetCollection("restaurants"); + var queryableCollection = restaurantsCollection.AsQueryable(); Once you have the queryable object, you can compose a query using **method syntax**. Some pipeline stages also support **query comprehension syntax**, @@ -587,6 +588,181 @@ in the Atlas manual. For more examples about running Atlas Vector Search queries {+driver-short+}, see :atlas:`Run Vector Search Queries ` in the Atlas manual and select :guilabel:`C#` from the language dropdown. +Bitwise Operators +~~~~~~~~~~~~~~~~~ + +This section describes the :wikipedia:`bitwise operators ` +supported by the {+driver-short+} that you can use in an aggregation pipeline. +You can use multiple bitwise operators in the same +stage. The following guidelines apply when using bitwise operators: + +- All operands must be of type ``int`` or ``long``. + +- ``$bitAnd``, ``$bitOr``, and ``$bitXor`` take two or more operands. ``$bitNot`` takes one operand. + +- Bitwise operations are evaluated from left to right. + +The examples in this section use the following documents in a collection called +``ingredients``: + +.. code-block:: json + + { "_id" : 1, "name" : "watermelon", "is_available" : 1, "is_cheap" : 1 }, + { "_id" : 2, "name" : "onions", "is_available" : 1, "is_cheap" : 0 }, + { "_id" : 3, "name" : "eggs", "is_available" : 0, "is_cheap" : 0 }, + { "_id" : 4, "name" : "potatoes", "is_available" : 1, "is_cheap" : 1 }, + { "_id" : 5, "name" : "pasta", "is_available" : 0, "is_cheap" : 1 }, + { "_id" : 6, "name" : "cheese", "is_available" : 1 } + +The ``"is_available"`` field represents if an ingredient is available. If this +field has a value of ``0``, the ingredient is not available. If it has a value +of ``1``, the ingredient is available. + +The ``"is_cheap"`` field represents if an ingredient is cheap. If this field has +a value of ``0``, the ingredient is not cheap. If it has a value of ``1``, the +ingredient is cheap. + +The following ``Ingredient`` class models the documents in the ``ingredients`` +collection: + +.. literalinclude:: /includes/fundamentals/code-examples/linq.cs + :language: csharp + :dedent: + :start-after: start-ingredient-model + :end-before: end-ingredient-model + +.. note:: Missing or Undefined Operands + + If the operands you pass to any bitwise operator are of type `nullable `__ + ``int`` or ``long`` and contain a missing or undefined value, the entire expression + evaluates to ``null``. If the operands are of type non-nullable ``int`` or + ``long`` and contain a missing or undefined value, the {+driver-short+} will + throw an error. + +$bitAnd ++++++++ + +The ``$bitAnd`` aggregation operator performs a bitwise AND operation on the given +arguments. You can use the ``$bitAnd`` operator by connecting two or more +clauses with a ``&`` character. + +The following example shows how to create a ``$bitAnd`` stage by using LINQ. The +code retrieves the document in which the ``Name`` field has the +value ``"watermelon"``. It then performs a bitwise AND operation on the values of the +``IsAvailable`` and ``IsCheap`` fields in this document. + +.. literalinclude:: /includes/fundamentals/code-examples/linq.cs + :language: csharp + :dedent: + :start-after: start-bitAnd-example + :end-before: end-bitAnd-example + +The preceding code returns ``1``, the result of the AND operation on the values +of the ``IsAvailable`` field (``1``) and the ``IsCheap`` field (``1``). + +The following example performs the same bitwise AND operation on all +documents in the collection: + +.. io-code-block:: + :copyable: true + + .. input:: /includes/fundamentals/code-examples/linq.cs + :language: csharp + :dedent: + :start-after: start-bitAnd-collection-example + :end-before: end-bitAnd-collection-example + + .. output:: + :language: json + :visible: false + + 1 + 0 + 0 + 1 + 0 + null + +The ``null`` result comes from the document where the ``Name`` field +has the value of ``"cheese"``. This document is missing an ``IsCheap`` field, so +the expression evaluates to ``null``. + +$bitOr +++++++ + +The ``$bitOr`` aggregation operator performs a bitwise OR operation on the given +arguments. You can use the ``$bitOr`` operator by connecting two or more +clauses with a ``|`` character. + +The following example shows how to create a ``$bitOr`` stage by using LINQ. The +code retrieves the document in which the ``Name`` field has the +value ``"onions"``. It then performs a bitwise OR operation on the values of the +``IsAvailable`` and ``IsCheap`` fields in this document. + +.. literalinclude:: /includes/fundamentals/code-examples/linq.cs + :language: csharp + :dedent: + :start-after: start-bitOr-example + :end-before: end-bitOr-example + +The preceding code returns ``1``, the result of the OR operation on the values +of the ``IsAvailable`` field (``1``) and the ``IsCheap`` field (``0``). + +$bitNot ++++++++ + +The ``$bitNot`` aggregation operator performs a bitwise NOT operation on the given +argument. You can use the ``$bitNot`` operator by preceding an +operand with a ``~`` character. ``$bitNot`` only takes one argument. The +following example shows how to create a ``$bitNot`` stage by using LINQ: + +.. io-code-block:: + :copyable: true + + .. input:: /includes/fundamentals/code-examples/linq.cs + :language: csharp + :dedent: + :start-after: start-bitNot-example + :end-before: end-bitNot-example + + .. output:: + :language: json + :visible: false + + -2 + -1 + -1 + -2 + -2 + null + +$bitXor ++++++++ + +The ``$bitXor`` aggregation operator performs a bitwise XOR operation on the given +arguments. You can use the ``$bitXor`` operator by connecting two or more +clauses with a ``^`` character. + +The following example shows how to create a ``$bitXor`` stage by using LINQ. The +code retrieves the documents in which the ``Name`` field has +the value ``"watermelon"`` or ``"onions"``. It then performs a bitwise XOR +operation on the values of the ``IsAvailable`` and ``IsCheap`` fields in these +documents. + +.. literalinclude:: /includes/fundamentals/code-examples/linq.cs + :language: csharp + :dedent: + :start-after: start-bitXor-example + :end-before: end-bitXor-example + +The result contains the following values: + +.. code-block:: json + + 0 + 1 + + Unsupported Aggregation Stages ------------------------------ diff --git a/source/includes/convention-pack-note.rst b/source/includes/convention-pack-note.rst index cb322ef4..97338a26 100644 --- a/source/includes/convention-pack-note.rst +++ b/source/includes/convention-pack-note.rst @@ -1,6 +1,6 @@ .. note:: - The documents in the ``restaurants`` collection use the camel-case naming + The documents in the ``restaurants`` collection use the snake-case naming convention. The examples in this guide use a ``ConventionPack`` to deserialize the fields in the collection into Pascal case and map them to the properties in the ``Restaurant`` class. diff --git a/source/includes/fundamentals/code-examples/linq.cs b/source/includes/fundamentals/code-examples/linq.cs index aa4336e8..de5ab12e 100644 --- a/source/includes/fundamentals/code-examples/linq.cs +++ b/source/includes/fundamentals/code-examples/linq.cs @@ -26,7 +26,7 @@ public class Address public string Building { get; set; } [BsonElement("coord")] - public float[] Coordinates { get; set; } + public double[] Coordinates { get; set; } public string Street { get; set; } @@ -63,3 +63,58 @@ public class Review } // end-review-model + +// start-ingredient-model + +public class Ingredient +{ + public int Id { get; set; } + + public string Name { get; set; } + + [BsonElement("is_available")] + public int? IsAvailable { get; set; } + + [BsonElement("is_cheap")] + public int? IsCheap { get; set; } +} + +// end-ingredient-model + +// start-bitAnd-example + +var query = queryableCollection + .Where(i => i.Name == "watermelon") + .Select(i => i.IsAvailable & i.IsCheap); + +// end-bitAnd-example + +// start-bitAnd-collection-example + +var query = queryableCollection + .Select(i => i.IsAvailable & i.IsCheap); + +// end-bitAnd-collection-example + +// start-bitOr-example + +var query = queryableCollection + .Where(i => i.Name == "onions") + .Select(i => i.IsAvailable | i.IsCheap); + +// end-bitOr-example + +// start-bitNot-example + +var query = queryableCollection + .Select(i => ~i.IsCheap); + +// end-bitNot-example + +// start-bitXor-example + +var query = queryableCollection + .Where(i => i.Name == "watermelon" || i.Name == "onions") + .Select(i => i.IsAvailable ^ i.IsCheap); + +// end-bitXor-example \ No newline at end of file From 425cb6c80f6e445bb617d0c9b93984630737c062 Mon Sep 17 00:00:00 2001 From: Jordan Smith <45415425+jordan-smith721@users.noreply.github.com> Date: Mon, 28 Oct 2024 06:06:26 -0700 Subject: [PATCH 10/35] update incorrect whats new bullet (#281) (cherry picked from commit 69a08d069eb842bddbd1dac53481094bd9e61f13) --- source/whats-new.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source/whats-new.txt b/source/whats-new.txt index d4b88da5..d23b430a 100644 --- a/source/whats-new.txt +++ b/source/whats-new.txt @@ -57,8 +57,11 @@ The 3.0 driver release includes the following new features: - The ``IMongoClient`` interface inherits the ``IDisposable`` interface. As a result, the ``MongoClient`` class and other classes that implement the ``IMongoClient`` interface - contain a ``Dispose()`` method, which disposes of the underlying cluster and - connections to the MongoDB server. This implementation is experimental. + contain a ``Dispose()`` method, which disposes of the client. This method does not + dispose the underlying cluster and connections to the MongoDB server. To + dispose of the cluster and connections, call the + ``ClusterRegistry.UnregisterAndDisposeCluster()`` method. + The implementation of the ``IDisposable`` interface is experimental. To learn more about the ``IDisposable`` interface and use of the ``Dispose()`` method, see From 87c3bff5e3902d252c138f6c8b903279d477914d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 30 Oct 2024 11:35:03 -0500 Subject: [PATCH 11/35] DOCSP-44422 - Bulk write API (#257) (#282) Co-authored-by: Rea Rustagi <85902999+rustagir@users.noreply.github.com> (cherry picked from commit 12fc8ef00817e2951e5976992eb6cd9590f0a81b) Co-authored-by: Mike Woofter <108414937+mongoKart@users.noreply.github.com> --- source/fundamentals/crud/write-operations.txt | 4 +- .../crud/write-operations/bulk-write.txt | 582 ++++++++++++++++++ .../fundamentals/code-examples/BulkWrite.cs | 201 ++++++ source/whats-new.txt | 3 + 4 files changed, 789 insertions(+), 1 deletion(-) create mode 100644 source/fundamentals/crud/write-operations/bulk-write.txt create mode 100644 source/includes/fundamentals/code-examples/BulkWrite.cs diff --git a/source/fundamentals/crud/write-operations.txt b/source/fundamentals/crud/write-operations.txt index 67fdd956..ec132498 100644 --- a/source/fundamentals/crud/write-operations.txt +++ b/source/fundamentals/crud/write-operations.txt @@ -13,7 +13,9 @@ Write Operations /fundamentals/crud/write-operations/insert /fundamentals/crud/write-operations/modify /fundamentals/crud/write-operations/delete + /fundamentals/crud/write-operations/bulk-write +- :ref:`csharp-insert-guide` - :ref:`csharp-change-guide` - :ref:`csharp-delete-guide` -- :ref:`csharp-insert-guide` +- :ref:`csharp-bulk-write` diff --git a/source/fundamentals/crud/write-operations/bulk-write.txt b/source/fundamentals/crud/write-operations/bulk-write.txt new file mode 100644 index 00000000..8da9b794 --- /dev/null +++ b/source/fundamentals/crud/write-operations/bulk-write.txt @@ -0,0 +1,582 @@ +.. _csharp-bulk-write: + +===================== +Bulk Write Operations +===================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: insert, update, replace, code example + +Overview +-------- + +This guide shows you how to use the {+driver-short+} to perform **bulk write operations** +from your ``MongoClient`` instance. A bulk write operation is a single database call +that performs multiple write operations on one or more MongoDB collections. This is more +efficient than performing multiple individual write operations because it reduces the +number of round trips between your application and the database. + +Sample Data +~~~~~~~~~~~ + +The examples in this guide use the ``sample_restaurants.restaurants`` collection +from the :atlas:`Atlas sample datasets `. To learn how to create a +free MongoDB Atlas cluster and load the sample datasets, see the +:ref:`` tutorial. + +Define the Write Operations +--------------------------- + +For each write operation you want to perform, create an instance of one of +the following ``BulkWriteModel`` classes: + +- ``BulkWriteInsertOneModel`` +- ``BulkWriteUpdateOneModel`` +- ``BulkWriteUpdateManyModel`` +- ``BulkWriteReplaceOneModel`` +- ``BulkWriteDeleteOneModel`` +- ``BulkWriteDeleteManyModel`` + +The following sections show how to create and use instances of the preceding classes +to perform the corresponding write operation in a bulk write. + +.. tip:: Bulk Write Operations with POCOs + + The examples in this guide use the ``BsonDocument`` type for the ``TDocument`` type + in all generic classes. You can also use a Plain Old CLR Object (POCO) for these + classes. To do so, you must define a class that represents the documents in your + collection. The class must have properties that match the fields in your documents. + For more information, see :ref:``. + +Insert Operations +~~~~~~~~~~~~~~~~~ + +To perform an insert operation, create an instance of the +``BulkWriteInsertOneModel`` class. +The ``BulkWriteInsertOneModel`` constructor accepts the following parameters: + +.. list-table:: + :header-rows: 1 + :stub-columns: 1 + + * - Parameter + - Description + + * - ``collectionNamespace`` + - | The database and collection to insert the BSON document into. + | + | **Data Type:** {+string-data-type+} or `CollectionNamespace <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.CollectionNamespace.html>`__ + + * - ``document`` + - | The document to insert into the collection. + | + | **Data Type:** ``TDocument`` + +The following example creates an instance of the ``BulkWriteInsertOneModel`` +class. This instance directs the driver to insert a document in which the ``"name"`` field +is ``"Mongo's Deli"`` into the ``sample_restaurants.restaurants`` collection. + +.. literalinclude:: /includes/fundamentals/code-examples/BulkWrite.cs + :start-after: start-bulk-insert-one + :end-before: end-bulk-insert-one + :language: csharp + :copyable: + :dedent: 8 + +.. tip:: Insert Multiple Documents + + To insert multiple documents, create an instance of the + ``BulkWriteInsertOneModel`` class for each document you want to insert. + +Update Operations +~~~~~~~~~~~~~~~~~ + +To update a single document, create an instance of the ``BulkWriteUpdateOneModel`` +class. The ``BulkWriteUpdateOneModel`` constructor accepts the following +parameters: + +.. list-table:: + :header-rows: 1 + :stub-columns: 1 + + * - Parameter + - Description + + * - ``collectionNamespace`` + - | The database and collection to insert the BSON document into. + | + | **Data Type:** {+string-data-type+} or `CollectionNamespace <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.CollectionNamespace.html>`__ + + * - ``filter`` + - | The **query filter** that specifies the criteria used to match documents in your collection. + The ``UpdateOne`` operation updates *only the first document* that matches the + query filter. + | + | **Data Type:** `FilterDefinition <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.FilterDefinition-1.html>`__ + + * - ``update`` + - | The update operation you want to perform. For more information about update + operations, see :manual:`Field Update Operators ` + in the {+mdb-server+} manual. + | + | **Data Type:** `UpdateDefinition <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateDefinition-1.html>`__ + + * - ``collation`` + - | *Optional.* The language collation to use when sorting results. See the + :manual:`{+mdb+server+} manual` + for more information. + | + | **Data Type:** `Collation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Collation.html>`__ + | **Default:** ``null`` + + * - ``hint`` + - | *Optional.* The index to use to scan for documents. + See the :manual:`{+mdb-server+} manual` + for more information. + | + | **Data Type:** `BsonValue <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonValue.html>`__ + | **Default:** ``null`` + + * - ``isUpsert`` + - | *Optional.* Specifies whether the update operation performs an upsert operation if no + documents match the query filter. See the :manual:`{+mdb-server+} manual` + for more information. + | + | **Data Type:** {+bool-data-type+} + | **Default:** ``false`` + + * - ``arrayFilters`` + - | Specifies which array elements to modify for an update operation on an array field. + See the :manual:`{+mdb-server+} manual` + for more information. + | + | **Data Type:** `IEnumerable `__ + | **Default:** ``null`` + +In the following code example, the ``BulkWriteUpdateOneModel`` object +represents an update operation on the ``sample_restaurants.restaurants`` collection. +The operation matches the first document in the collection where the value of the ``name`` +field is ``"Mongo's Deli"``. It then updates the value of the ``cuisine`` field in the +matched document to ``"Sandwiches and Salads"``. + +.. literalinclude:: /includes/fundamentals/code-examples/BulkWrite.cs + :start-after: start-bulk-update-one + :end-before: end-bulk-update-one + :language: csharp + :copyable: + :dedent: 8 + +To update multiple documents, create an instance of the +``BulkWriteUpdateManyModel`` class. The constructor for this class +accepts the same parameters as the ``BulkWriteUpdateOneModel`` constructor. +The ``BulkWriteUpdateManyModel`` +operation updates *all documents* that match your query filter. + +In the following code example, the ``BulkWriteUpdateManyModel`` object +represents an update operation on the ``sample_restaurants.restaurants`` collection. +The operation matches all documents in the collection where +the value of the ``name`` field is ``"Mongo's Deli"``. It then updates +the value of the ``cuisine`` field to ``"Sandwiches and Salads"``. + +.. literalinclude:: /includes/fundamentals/code-examples/BulkWrite.cs + :start-after: start-bulk-update-many + :end-before: end-bulk-update-many + :language: csharp + :copyable: + :dedent: 8 + +Replace Operations +~~~~~~~~~~~~~~~~~~ + +To replace the fields in a document, create an instance of the +``BulkWriteReplaceOneModel`` class. The ``BulkWriteReplaceOneModel`` +constructor accepts the following parameters: + +.. list-table:: + :header-rows: 1 + :stub-columns: 1 + + * - Parameter + - Description + + * - ``collectionNamespace`` + - | The database and collection to insert the BSON document into. + | + | **Data Type:** {+string-data-type+} or `CollectionNamespace <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.CollectionNamespace.html>`__ + + * - ``filter`` + - | The **query filter** that specifies the criteria used to match documents in your collection. + The ``UpdateOne`` operation updates *only the first document* that matches the + query filter. + | + | **Data Type:** `FilterDefinition <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.FilterDefinition-1.html>`__ + + * - ``replacement`` + - | The replacement document, which specifies the fields and values to insert in the + target document. + | + | **Data Type:** ``TDocument`` + + * - ``collation`` + - | *Optional.* The language collation to use when sorting results. See + the :manual:`{+mdb-server+} manual` + for more information. + | + | **Data Type:** `Collation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Collation.html>`__ + | **Default:** ``null`` + + * - ``hint`` + - | *Optional.* The index to use to scan for documents. + See the :manual:`{+mdb-server+} manual` + for more information. + | + | **Data Type:** `BsonValue <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonValue.html>`__ + | **Default:** ``null`` + + * - ``isUpsert`` + - | *Optional.* Specifies whether the update operation performs an upsert operation if no + documents match the query filter. + See the :manual:`{+mdb-server+} manual` + for more information. + | + | **Data Type:** {+bool-data-type+} + | **Default:** ``false`` + +In the following example, the ``BulkWriteReplaceOneModel`` object +represents a replace operation on the ``sample_restaurants.restaurants`` collection. +The operation matches the document in the collection +where the value of the ``restaurant_id`` field is ``"1234"``. It then +removes all fields other than ``_id`` from this document, and sets new values in the +``name``, ``cuisine``, ``borough``, and ``restaurant_id`` fields. + +.. literalinclude:: /includes/fundamentals/code-examples/BulkWrite.cs + :start-after: start-bulk-replace-one + :end-before: end-bulk-replace-one + :language: csharp + :copyable: + :dedent: 8 + +.. tip:: Replace Multiple Documents + + To replace multiple documents, create an instance of the + ``BulkWriteReplaceOneModel`` class for each document you want to replace. + +Delete Operations +~~~~~~~~~~~~~~~~~ + +To delete a document, create an instance of the ``BulkWriteDeleteOneModel`` +class. The ``BulkWriteDeleteOneModel`` constructor accepts the following +parameters: + +.. list-table:: + :header-rows: 1 + :stub-columns: 1 + + * - Parameter + - Description + + * - ``collectionNamespace`` + - | The database and collection to insert the BSON document into. + | + | **Data Type:** {+string-data-type+} or `CollectionNamespace <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.CollectionNamespace.html>`__ + + * - ``filter`` + - | The **query filter** that specifies the criteria used to match documents in your collection. + The ``DeleteOne`` operation deletes *only the first document* that matches the + query filter. + | + | **Data Type:** `FilterDefinition <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.FilterDefinition-1.html>`__ + + * - ``collation`` + - | *Optional.* The language collation to use when sorting results. See + the :manual:`{+mdb-server+} manual` + for more information. + | + | **Data Type:** `Collation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Collation.html>`__ + | **Default:** ``null`` + + * - ``hint`` + - | *Optional.* The index to use to scan for documents. + See the :manual:`{+mdb-server+} manual` + for more information. + | + | **Data Type:** `BsonValue <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonValue.html>`__ + | **Default:** ``null`` + +In the following code example, the ``BulkWriteDeleteOneModel`` object +represents a delete operation on the ``sample_restaurants.restaurants`` collection. +The operation matches and deletes the first document +where the value of the ``restaurant_id`` field is ``"5678"``. + +.. literalinclude:: /includes/fundamentals/code-examples/BulkWrite.cs + :start-after: start-bulk-delete-one + :end-before: end-bulk-delete-one + :language: csharp + :copyable: + :dedent: 8 + +To delete multiple documents, create an instance of the ``BulkWriteDeleteManyModel`` +class and pass a query filter that specifies the document that you want to delete. +The ``DeleteMany`` operation removes *all documents* that match your +query filter. + +In the following code example, the ``BulkWriteDeleteManyModel`` object +represents a delete operation on the ``sample_restaurants.restaurants`` collection. +The operation matches and deletes all documents +where the value of the ``name`` field is ``"Mongo's Deli"``. + +.. literalinclude:: /includes/fundamentals/code-examples/BulkWrite.cs + :start-after: start-bulk-delete-many + :end-before: end-bulk-delete-many + :language: csharp + :copyable: + :dedent: 8 + +Run the Write Operations +------------------------ + +After you define a ``BulkWriteModel`` instance for each operation that you want to perform, +create an instance of a class that implements the ``IReadOnlyList`` interface. Add your +``BulkWriteModel`` objects to this ``IReadOnlyList``, then pass the ``IReadOnlyList`` +to the ``BulkWrite()`` or ``BulkWriteAsync()`` method. By default, these methods run +the operations in the order they're defined in the collection. + +.. tip:: IReadOnlyList + + ``Array`` and ``List`` are two common classes that implement the ``IReadOnlyList`` + interface. + +Select from the following tabs to view how to use the asynchronous +``BulkWriteAsync()`` method and the synchronous ``BulkWrite()`` method to +perform a bulk write operation. + +.. tabs:: + + .. tab:: Asynchronous + :tabid: bulk-write-async + + .. literalinclude:: /includes/fundamentals/code-examples/BulkWrite.cs + :start-after: start-bulk-write-async + :end-before: end-bulk-write-async + :language: csharp + :copyable: + :dedent: 8 + + .. tab:: Synchronous + :tabid: bulk-write-sync + + .. literalinclude:: /includes/fundamentals/code-examples/BulkWrite.cs + :start-after: start-bulk-write-sync + :end-before: end-bulk-write-sync + :language: csharp + :copyable: + :dedent: 8 + +The preceding code examples produce the following output: + +.. code-block:: shell + + BulkWriteResult({'writeErrors': [], 'writeConcernErrors': [], 'nInserted': 2, 'nUpserted': 0, 'nMatched': 2, 'nModified': 2, 'nRemoved': 1, 'upserted': []}, acknowledged=True) + +Customize Bulk Write Operations +------------------------------- + +When you call the ``BulkWrite()`` or ``BulkWriteAsync()`` method, you can pass an +instance of the ``ClientBulkWriteOptions`` class. The ``ClientBulkWriteOptions`` class +contains the following properties, which represent options you can use to configure the +bulk write operation: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Property + - Description + + * - ``BypassDocumentValidation`` + - | Specifies whether the operation bypasses document-level validation. For more + information, see :manual:`Schema + Validation ` in the {+mdb-server+} + manual. + | Defaults to ``false``. + + * - ``Comment`` + - | A comment to attach to the operation, in the form of a ``BsonValue``. For + more information, see the :manual:`delete command + fields ` guide in the + {+mdb-server+} manual. + + * - ``IsOrdered`` + - | If ``true``, the driver performs the write operations in the order + provided. If an error occurs, the remaining operations are not + attempted. + | + | If ``false``, the driver performs the operations in an + arbitrary order and attempts to perform all operations. If any of the write + operations in an unordered bulk write fail, the driver + reports the errors only after attempting all operations. + | Defaults to ``True``. + + * - ``Let`` + - | A map of parameter names and values, in the form of a ``BsonDocument``. Values + must be constant or closed + expressions that don't reference document fields. For more information, + see the :manual:`let statement + ` in the + {+mdb-server+} manual. + + * - ``VerboseResult`` + - | Specifies whether the ``ClientBulkWriteResult`` object returned by the operation + includes detailed results for each successful write operation. + | Defaults to ``false``. + + * - ``WriteConcern`` + - | The write concern to use for the write operation, as a value from the ``WriteConcern`` + enum. + | Defaults to the write concern of the collection on which the operation is running. + +The following code examples use a ``ClientBulkWriteOptions`` object to customize +a delete operation: + +.. tabs:: + + .. tab:: Asynchronous + :tabid: bulk-write-options-async + + .. literalinclude:: /includes/fundamentals/code-examples/BulkWrite.cs + :start-after: start-bulk-write-options-async + :end-before: end-bulk-write-options-async + :language: csharp + :copyable: + :dedent: 8 + + .. tab:: Synchronous + :tabid: bulk-write-options-sync + + .. literalinclude:: /includes/fundamentals/code-examples/BulkWrite.cs + :start-after: start-bulk-write-options-sync + :end-before: end-bulk-write-options-sync + :language: csharp + :copyable: + :dedent: 8 + +Return Value +------------ + +The ``BulkWrite()`` and ``BulkWriteAsync()`` methods return a ``ClientBulkWriteResult`` +object that contains the following properties: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Property + - Description + + * - ``Acknowledged`` + - | Indicates whether the server acknowledged the bulk write operation. If the + value of this property is ``false`` and you try to access any other property + of the ``ClientBulkWriteResult`` object, the driver throws an exception. + + * - ``DeleteResults`` + - | An ``IReadOnlyDictionary`` object containing the + results of each successful delete operation, if any. + + * - ``DeletedCount`` + - | The number of documents deleted, if any. + + * - ``InsertResults`` + - | An ``IReadOnlyDictionary`` object containing the + results of each successful insert operation, if any. + + * - ``InsertedCount`` + - | The number of documents inserted, if any. + + * - ``MatchedCount`` + - | The number of documents matched for an update, if applicable. + + * - ``ModifiedCount`` + - | The number of documents modified, if any. + + * - ``UpsertResults`` + - | An ``IReadOnlyDictionary`` object containing the + results of each successful update operation, if any. + + * - ``UpsertedCount`` + - | The number of documents upserted, if any. + +Handling Exceptions +------------------- + +If any of the operations in a bulk write operation fail, the {+driver-short+} throws a +``ClientBulkWriteException`` and does not perform any further operations. + +A ``ClientBulkWriteException`` object contains the following properties: + +.. list-table:: + :header-rows: 1 + :stub-columns: 1 + + * - Property + - Description + * - ``connectionId`` + - | The connection identifier. + | + | **Data Type:** `ConnectionId <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Core.Connections.ConnectionId.html>`__ + * - ``message`` + - | The error message. + | + | **Data Type:** string + * - ``writeErrors`` + - | A dictionary of errors that occurred during the bulk write operation. + | + | **Data Type:** IReadOnlyDictionary`__> + * - ``partialResult`` + - | The results of any successful operations performed before the exception was thrown. + | + | **Data Type:** `ClientBulkWriteResult <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ClientBulkWriteResult.html>`__ + * - ``writeConcernErrors`` + - | Write concern errors that occurred during execution of the bulk write operation. + | + | **Data Type:** IReadOnlyList<`MongoWriteConcernException <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.MongoWriteConcernException.html>`__> + * - ``innerException`` + - | The inner exception. + | + | **Data Type:** `Exception `__ + +Additional Information +---------------------- + +To learn how to perform individual write operations, see the following guides: + +- :ref:`csharp-change-guide` +- :ref:`csharp-insert-guide` +- :ref:`csharp-delete-guide` + +To learn more about any of the methods or types discussed in this +guide, see the following API documentation: + +- `BulkWrite() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoClient.BulkWrite.html>`__ +- `BulkWriteAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoClient.BulkWriteAsync.html>`__ +- `ClientBulkWriteOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ClientBulkWriteOptions.html>`__ +- `ClientBulkWriteResult <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ClientBulkWriteResult.html>`__ +- `BulkWriteInsertOneModel <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.BulkWriteInsertOneModel-1.html>`__ +- `BulkWriteUpdateOneModel <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.BulkWriteUpdateOneModel-1.html>`__ +- `BulkWriteUpdateManyModel <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.BulkWriteUpdateManyModel-1.html>`__ +- `BulkWriteReplaceOneModel <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.BulkWriteReplaceOneModel-1.html>`__ +- `BulkWriteDeleteOneModel <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.BulkWriteDeleteOneModel-1.html>`__ +- `BulkWriteDeleteManyModel <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.BulkWriteDeleteManyModel-1.html>`__ +- `BulkWriteInsertOneResult <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.BulkWriteInsertOneResult.html>`__ +- `BulkWriteUpdateResult <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.BulkWriteUpdateResult.html>`__ +- `BulkWriteDeleteResult <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.BulkWriteDeleteResult.html>`__ +- `ClientBulkWriteException <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ClientBulkWriteException.html>`__ diff --git a/source/includes/fundamentals/code-examples/BulkWrite.cs b/source/includes/fundamentals/code-examples/BulkWrite.cs new file mode 100644 index 00000000..4ee5e0c6 --- /dev/null +++ b/source/includes/fundamentals/code-examples/BulkWrite.cs @@ -0,0 +1,201 @@ +using System; + +class BulkWrite +{ + static void InsertOne() + { + // start-bulk-insert-one + var insertOneModel = new BulkWriteInsertOneModel( + "sample_restaurants.restaurants", + new BsonDocument{ + { "name", "Mongo's Deli" }, + { "cuisine", "Sandwiches" }, + { "borough", "Manhattan" }, + { "restaurant_id", "1234" } + } + ); + // end-bulk-insert-one + } + + static void UpdateOne() + { + // start-bulk-update-one + var updateOneModel = new BulkWriteUpdateOneModel( + "sample_restaurants.restaurants", + Builders.Filter.Eq("name", "Mongo's Deli"), + Builders.Update.Set("cuisine", "Sandwiches and Salads") + ); + // end-bulk-update-one + } + + static void UpdateMany() + { + // start-bulk-update-many + var updateManyModel = new BulkWriteUpdateManyModel( + "sample_restaurants.restaurants", + Builders.Filter.Eq("name", "Mongo's Deli"), + Builders.Update.Set("cuisine", "Sandwiches and Salads") + ); + // end-bulk-update-many + } + + static void ReplaceOne() + { + // start-bulk-replace-one + var replaceOneModel = new BulkWriteReplaceOneModel( + "sample_restaurants.restaurants", + Builders.Filter.Eq("restaurant_id", "1234"), + new BsonDocument{ + { "name", "Mongo's Pizza" }, + { "cuisine", "Pizza" }, + { "borough", "Brooklyn" }, + { "restaurant_id", "5678" } + } + ); + // end-bulk-replace-one + } + + static void DeleteOne() + { + // start-bulk-delete-one + var deleteOneModel = new BulkWriteDeleteOneModel( + "sample_restaurants.restaurants", + Builders.Filter.Eq("restaurant_id", "5678") + ); + // end-bulk-delete-one + } + + static void DeleteMany() + { + // start-bulk-delete-many + var deleteManyModel = new BulkWriteDeleteManyModel( + "sample_restaurants.restaurants", + Builders.Filter.Eq("name", "Mongo's Deli") + ); + // end-bulk-delete-many + } + + static void BulkWriteSync() + { + // start-bulk-write-sync + var client = new MongoClient("mongodb://localhost:27017"); + var collection = "sample_restaurants.restaurants"; + + var bulkWriteModels = new[] + { + new BulkWriteInsertOneModel( + collection, + new BsonDocument{ + { "name", "Mongo's Deli" }, + { "cuisine", "Sandwiches" }, + { "borough", "Manhattan" }, + { "restaurant_id", "1234" } + } + ), + new BulkWriteInsertOneModel( + collection, + new BsonDocument{ + { "name", "Mongo's Deli" }, + { "cuisine", "Sandwiches" }, + { "borough", "Brooklyn" }, + { "restaurant_id", "5678" } + } + ), + new BulkWriteUpdateManyModel( + collection, + Builders.Filter.Eq("name", "Mongo's Deli"), + Builders.Update.Set("cuisine", "Sandwiches and Salads") + ), + new BulkWriteDeleteOneModel( + collection, + Builders.Filter.Eq("restaurant_id", "1234") + ) + }; + + var results = client.BulkWrite(bulkWriteModels); + Console.WriteLine("Bulk write results: " + results); + // end-bulk-write-sync + } + static async Task BulkWriteAsync() + { + // start-bulk-write-async + var client = new MongoClient("mongodb://localhost:27017"); + var collection = "sample_restaurants.restaurants"; + + var bulkWriteModels = new[] + { + new BulkWriteInsertOneModel( + collection, + new BsonDocument{ + { "name", "Mongo's Deli" }, + { "cuisine", "Sandwiches" }, + { "borough", "Manhattan" }, + { "restaurant_id", "1234" } + } + ), + new BulkWriteInsertOneModel( + collection, + new BsonDocument{ + { "name", "Mongo's Deli" }, + { "cuisine", "Sandwiches" }, + { "borough", "Brooklyn" }, + { "restaurant_id", "5678" } + } + ), + new BulkWriteUpdateManyModel( + collection, + Builders.Filter.Eq("name", "Mongo's Deli"), + Builders.Update.Set("cuisine", "Sandwiches and Salads") + ), + new BulkWriteDeleteOneModel( + collection, + Builders.Filter.Eq("restaurant_id", "1234") + ) + }; + + var results = await client.BulkWriteAsync(bulkWriteModels); + Console.WriteLine("Bulk write results: " + results); + // end-bulk-write-async + } + + static void BulkWriteOptionsSync() + { + // start-bulk-write-options-sync + var client = new MongoClient("mongodb://localhost:27017"); + + var deleteOneModel = new BulkWriteDeleteOneModel( + "sample_restaurants.restaurants", + Builders.Filter.Eq("restaurant_id", "5678") + ); + + var clientBulkWriteOptions = new ClientBulkWriteOptions + { + IsOrdered = false, + WriteConcern = WriteConcern.Unacknowledged, + VerboseResult = true + }; + + var results = client.BulkWrite(deleteOneModel, clientBulkWriteOptions); + // end-bulk-write-options-sync + } + static async Task BulkWriteOptionsAsync() + { + // start-bulk-write-options-async + var client = new MongoClient("mongodb://localhost:27017"); + + var deleteOneModel = new BulkWriteDeleteOneModel( + "sample_restaurants.restaurants", + Builders.Filter.Eq("restaurant_id", "5678") + ); + + var clientBulkWriteOptions = new ClientBulkWriteOptions + { + IsOrdered = false, + WriteConcern = WriteConcern.Unacknowledged, + VerboseResult = true + }; + + var results = await client.BulkWriteAsync(deleteOneModel, clientBulkWriteOptions); + // end-bulk-write-options-async + } +} \ No newline at end of file diff --git a/source/whats-new.txt b/source/whats-new.txt index d23b430a..c66dad0f 100644 --- a/source/whats-new.txt +++ b/source/whats-new.txt @@ -148,6 +148,9 @@ The 3.0 driver release includes the following new features: To learn more about using the aggregation pipeline with the {+driver-short+}, see :ref:`csharp-aggregation`. +- Adds a ``MongoClient`` API for bulk write operations. To learn more about bulk write + operations, see :ref:`csharp-bulk-write`. + For more information about this release, see the :github:`v3.0 release notes `. From 083e7e93bd0fbaaf9ff03df06e4bb397865c1681 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 31 Oct 2024 11:19:45 -0500 Subject: [PATCH 12/35] DOCSP-44845 - Fix tip box (#283) (#285) (cherry picked from commit ab943f9ad13c03cf2473c24f23fa73ce059d295e) --- source/whats-new.txt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/source/whats-new.txt b/source/whats-new.txt index c66dad0f..790b8317 100644 --- a/source/whats-new.txt +++ b/source/whats-new.txt @@ -143,7 +143,15 @@ The 3.0 driver release includes the following new features: .. tip:: MongoClientSettings To enable client-side projection for all queries on a client, set the - ``TranslationOptions`` property of the ``MongoClientSettings`` object to ``true``. + ``TranslationOptions`` property of your ``MongoClientSettings`` object, as shown + in the following example: + + .. code-block:: csharp + + clientSettings.TranslationOptions = new ExpressionTranslationOptions + { + EnableClientSideProjections = true + }; To learn more about using the aggregation pipeline with the {+driver-short+}, see :ref:`csharp-aggregation`. From db189ed66ceafd464444a681bc03a5766acbdb1e Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Mon, 4 Nov 2024 12:23:08 -0600 Subject: [PATCH 13/35] wip --- source/fundamentals.txt | 1 + source/fundamentals/gridfs.txt | 348 ++++++++++++++++++++++ source/includes/code-examples/GridFS.cs | 100 +++++++ source/includes/figures/GridFS-upload.png | Bin 0 -> 9225 bytes 4 files changed, 449 insertions(+) create mode 100644 source/fundamentals/gridfs.txt create mode 100644 source/includes/code-examples/GridFS.cs create mode 100644 source/includes/figures/GridFS-upload.png diff --git a/source/fundamentals.txt b/source/fundamentals.txt index 9ef0956e..5972a82c 100644 --- a/source/fundamentals.txt +++ b/source/fundamentals.txt @@ -30,6 +30,7 @@ Fundamentals /fundamentals/time-series /fundamentals/encrypt-fields /fundamentals/geo + Store Large Files - :ref:`Connecting to MongoDB ` - :ref:`csharp-db-coll` diff --git a/source/fundamentals/gridfs.txt b/source/fundamentals/gridfs.txt new file mode 100644 index 00000000..e7cd8d79 --- /dev/null +++ b/source/fundamentals/gridfs.txt @@ -0,0 +1,348 @@ +.. _csharp-gridfs: + +================= +Store Large Files +================= + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: binary large object, blob, storage, code example + +Overview +-------- + +In this guide, you can learn how to store and retrieve large files in +MongoDB by using **GridFS**. GridFS is a specification implemented by +the {+driver-short+} that describes how to split files into chunks when storing them +and reassemble those files when retrieving them. The driver's implementation of +GridFS is an abstraction that manages the operations and organization of +the file storage. + +Use GridFS if the size of your files exceeds the BSON document +size limit of 16MB. For more detailed information about whether GridFS is +suitable for your use case, see :manual:`GridFS ` in the +{+mdb-server+} manual. + +How GridFS Works +---------------- + +GridFS organizes files in a **bucket**, a group of MongoDB collections +that contain the chunks of files and information describing them. The +bucket contains the following collections, named using the convention +defined in the GridFS specification: + +- ``chunks``: Stores the binary file chunks +- ``files``: Stores the file metadata + +The driver creates the GridFS bucket, if it doesn't exist, when you first +write data to it. The bucket contains the preceding collections +prefixed with the default bucket name ``fs``, unless you specify a different +name. To ensure efficient retrieval of the files and related metadata, the driver +creates an index on each collection. The driver ensures that these indexes exist +before performing read and write operations on the GridFS bucket. + +For more information about GridFS indexes, see :manual:`GridFS Indexes +` in the {+mdb-server+} manual. + +When using GridFS to store files, the driver splits the files into smaller +chunks, each represented by a separate document in the ``chunks`` collection. +It also creates a document in the ``files`` collection that contains +a file ID, file name, and other file metadata. You can upload the file by passing +a stream to the {+driver-short+} to consume or by creating a new stream and writing to it +directly. + +The following diagram shows how GridFS splits files when they are +uploaded to a bucket: + +.. figure:: /includes/figures/GridFS-upload.png + :alt: A diagram that shows how GridFS uploads a file to a bucket + +When retrieving files, GridFS fetches the metadata from the ``files`` +collection in the specified bucket and uses the information to reconstruct +the file from documents in the ``chunks`` collection. You can read the file +by writing its contents to an existing stream or by creating a new stream that points +to the file. + +.. _gridfs-create-bucket: + +Create a GridFS Bucket +---------------------- + +To begin using GridFS to store or retrieve files, create a new instance of the +``GridFSBucket`` class, passing in an ``IMongoDatabase`` object that represents your +database. This method accesses an existing bucket or creates +a new bucket if one does not exist. + +The following example creates a new instance of the ``GridFSBucket`` class for the +``db`` database: + +.. literalinclude:: /includes/code-examples/GridFS.cs + :language: csharp + :dedent: + :start-after: // start-create-bucket + :end-before: // end-create-bucket + +.. _gridfs-create-custom-bucket: + +Customize the Bucket +~~~~~~~~~~~~~~~~~~~~ + +You can customize the GridFS bucket configuration by passing an instance +of the ``GridFSBucketOptions class`` class to +the ``GridFSBucket()`` constructor. The following table describes the properties in the +``GridFSBucketOptions`` class: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Field + - Description + + * - ``BucketName`` + - | The bucket name to use as a prefix for the files and chunks collections. + The default value is ``"fs"``. + | **Data type**: {+string-data-type+} + + * - ``ChunkSizeBytes`` + - | The chunk size that GridFS splits files into. The default value is ``261120``. + | **Data type**: {+int-data-type+} + + * - ``ReadConcern`` + - | The read concern to use for bucket operations. The default value is the + database's read concern. + | **Data type**: `ReadConcern <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ReadConcern.html>`__ + + * - ``ReadPreference`` + - | The read preference to use for bucket operations. The default value is the + database's read preference. + | **Data type**: `ReadPreference <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ReadPreference.html>`__ + + * - ``WriteConcern`` + - | The write concern to use for bucket operations. The default value is the + database's write concern. + | **Data type**: `WriteConcern <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.WriteConcern.html>`__ + +The following example creates a bucket named ``"myCustomBucket"`` by passing an instance +of the ``GridFSBucketOptions`` class to the ``GridFSBucket()`` constructor: + +.. literalinclude:: /includes/code-examples/GridFS.cs + :language: csharp + :dedent: + :start-after: // start-create-custom-bucket + :end-before: // end-create-custom-bucket + +.. _gridfs-upload-files: + +Upload Files +------------ + +You can upload files to a GridFS bucket by using the following methods: + +- :ref:`open_upload_stream() `: Opens a new upload stream to which + you can write file contents +- :ref:`upload_from_stream() `: Uploads the contents of an existing + stream to a GridFS file + +.. _gridfs-open-upload-stream: + +Write to an Upload Stream +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Use the ``open_upload_stream()`` method to create an upload stream for a given +file name. The ``open_upload_stream()`` method allows you to specify configuration +information in an ``options::gridfs::upload`` instance, which you can pass as a +parameter. + +This example uses an upload stream to perform the following +actions: + +- Sets the ``chunk_size_bytes`` field of an options instance +- Opens a writable stream for a new GridFS file named ``"my_file"`` + and applies the ``chunk_size_bytes`` option +- Calls the ``write()`` method to write data to ``my_file``, which the stream points to +- Calls the ``close()`` method to close the stream pointing to ``my_file`` + +.. literalinclude:: /includes/write/gridfs.cpp + :language: cpp + :dedent: + :start-after: start-open-upload-stream + :end-before: end-open-upload-stream + +.. _gridfs-upload-from-stream: + +Upload an Existing Stream +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Use the ``upload_from_stream()`` method to upload the contents of a stream to +a new GridFS file. The ``upload_from_stream()`` method allows you to specify configuration +information in an ``options::gridfs::upload`` instance, which you can pass as a +parameter. + +This example performs the following actions: + +- Opens a file located at ``/path/to/input_file`` as a stream in binary read mode +- Calls the ``upload_from_stream()`` method to upload the contents of the stream + to a GridFS file named ``"new_file"`` + +.. literalinclude:: /includes/write/gridfs.cpp + :language: cpp + :dedent: + :start-after: start-upload-from-stream + :end-before: end-upload-from-stream + +.. _gridfs-retrieve-file-info: + +Retrieve File Information +------------------------- + +In this section, you can learn how to retrieve file metadata stored in the +``files`` collection of the GridFS bucket. The metadata contains information +about the file it refers to, including: + +- The ``_id`` of the file +- The name of the file +- The length/size of the file +- The upload date and time +- A ``metadata`` document in which you can store other information + +To retrieve files from a GridFS bucket, call the ``mongocxx::gridfs::bucket::find()`` +method on your bucket. The method returns a ``mongocxx::cursor`` instance from +which you can access the results. To learn more about cursors, see the +:ref:`` guide. + +Example +~~~~~~~ + +The following code example shows how to retrieve and print file metadata +from files in a GridFS bucket. It uses a ``for`` loop to iterate through +the returned cursor and display the contents of the files uploaded in the +:ref:`gridfs-upload-files` examples: + +.. io-code-block:: + :copyable: + + .. input:: /includes/write/gridfs.cpp + :start-after: start-retrieve-file-info + :end-before: end-retrieve-file-info + :language: cpp + :dedent: + + .. output:: + :visible: false + + { "_id" : { "$oid" : "..." }, "length" : 13, "chunkSize" : 261120, "uploadDate" : + { "$date" : ... }, "filename" : "new_file" } + { "_id" : { "$oid" : "..." }, "length" : 50, "chunkSize" : 1048576, "uploadDate" : + { "$date" : ... }, "filename" : "my_file" } + +The ``find()`` method accepts various query specifications. You can use its +``mongocxx::options::find`` parameter to specify the sort order, maximum number of +documents to return, and the number of documents to skip before returning. To +view a list of available options, see the `API documentation <{+api+}/classmongocxx_1_1v__noabi_1_1options_1_1find.html>`__. + +.. _gridfs-download-files: + +Download Files +-------------- + +You can download files from a GridFS bucket by using the following methods: + +- :ref:`open_download_stream() `: Opens a new download stream + from which you can read the file contents +- :ref:`download_to_stream() `: Writes the entire file to an + existing download stream + +.. _gridfs-open-download-stream: + +Read From a Download Stream +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can download files from your MongoDB database by using the +``open_download_stream()`` method to create a download stream. + +This example uses a download stream to perform the following actions: + +- Retrieves the ``_id`` value of the GridFS file named ``"new_file"`` +- Passes the ``_id`` value to the ``open_download_stream()`` method to + open the file as a readable stream +- Creates a ``buffer`` vector to store the file contents +- Calls the ``read()`` method to read the file contents from the ``downloader`` + stream into the vector + +.. literalinclude:: /includes/write/gridfs.cpp + :language: cpp + :dedent: + :start-after: start-open-download-stream + :end-before: end-open-download-stream + +.. _gridfs-download_to_stream: + +Download to an Existing Stream +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can download the contents of a GridFS file to an existing stream +by calling the ``download_to_stream()`` method on your bucket. + +This example performs the following actions: + +- Opens a file located at ``/path/to/output_file`` as a stream in binary write + mode +- Retrieves the ``_id`` value of the GridFS file named ``"new_file"`` +- Passes the ``_id`` value to ``download_to_stream()`` to download the file + to the stream + +.. literalinclude:: /includes/write/gridfs.cpp + :language: cpp + :dedent: + :start-after: start-download-to-stream + :end-before: end-download-to-stream + +.. _gridfs-delete-files: + +Delete Files +------------ + +Use the ``delete_file()`` method to remove a file's collection document +and associated chunks from your bucket. This effectively deletes the file. +You must specify the file by its ``_id`` field rather than its file name. + +The following example shows how to delete a file named ``"my_file"`` by +passing its ``_id`` value to ``delete_file()``: + +.. literalinclude:: /includes/write/gridfs.cpp + :language: cpp + :dedent: + :start-after: start-delete-files + :end-before: end-delete-files + +.. note:: File Revisions + + The ``delete_file()`` method supports deleting only one file at a time. If + you want to delete each file revision, or files with different upload + times that share the same file name, collect the ``_id`` values of each revision. + Then, pass each ``_id`` value in separate calls to the ``delete_file()`` method. + +API Documentation +----------------- + +To learn more about using the {+driver-short+} to store and retrieve large files, +see the following API documentation: + +- `gridfs_bucket() <{+api+}/classmongocxx_1_1v__noabi_1_1database.html#afe549c42c37bfbf67d77a1ac1eaec422>`__ +- `mongocxx::options::gridfs::bucket <{+api+}/classmongocxx_1_1v__noabi_1_1options_1_1gridfs_1_1bucket.html>`__ +- `open_upload_stream() <{+api+}/classmongocxx_1_1v__noabi_1_1gridfs_1_1bucket.html#ad1f2b7ea5ee9068a9e2c0424ad3b3673>`__ +- `upload_from_stream() <{+api+}/classmongocxx_1_1v__noabi_1_1gridfs_1_1bucket.html#ad8fa27fb5be7c209211bdb071c5cca44>`__ +- `find() <{+api+}/classmongocxx_1_1v__noabi_1_1gridfs_1_1bucket.html#acd33e4ce5db96ec7bc50edf498a174c4>`__ +- `open_download_stream() <{+api+}/classmongocxx_1_1v__noabi_1_1gridfs_1_1bucket.html#a0ba68864a0cbaf60baf3fc1ef864858a>`__ +- `download_to_stream() <{+api+}/classmongocxx_1_1v__noabi_1_1gridfs_1_1bucket.html#ab6e51f650e11c5c6e8aea8f71a6ba04f>`__ +- `delete_file() <{+api+}/classmongocxx_1_1v__noabi_1_1gridfs_1_1bucket.html#a3c231ffa4ed1b1f278ca1f3ea2ca044d>`__ diff --git a/source/includes/code-examples/GridFS.cs b/source/includes/code-examples/GridFS.cs new file mode 100644 index 00000000..b29ac969 --- /dev/null +++ b/source/includes/code-examples/GridFS.cs @@ -0,0 +1,100 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using MongoDB.Bson; +using MongoDB.Driver; +using MongoDB.Driver.GridFS; + +class Program +{ + static async Task Main(string[] args) + { + // Initialize MongoDB client + // start-create-bucket + var client = new MongoClient(""); + var database = client.GetDatabase("db"); + + // Creates a GridFS bucket or references an existing one + var bucket = new GridFSBucket(database); + // end-create-bucket + + // Creates or references a GridFS bucket with a custom name + // start-create-custom-bucket + var options = new GridFSBucketOptions { BucketName = "myCustomBucket" }; + var customBucket = new GridFSBucket(database, options); + // end-create-custom-bucket + + // Uploads a file called "my_file" to the GridFS bucket and writes data to it + { + var options = new GridFSUploadOptions + { + ChunkSizeBytes = 1048576 // 1 MB + }; + using (var uploader = bucket.OpenUploadStream("my_file", options)) + { + // ASCII for "HelloWorld" + byte[] bytes = { 72, 101, 108, 108, 111, 87, 111, 114, 108, 100 }; + + for (int i = 0; i < 5; i++) + { + await uploader.WriteAsync(bytes, 0, bytes.Length); + } + + await uploader.CloseAsync(); + } + } + + // Uploads data to a stream, then writes the stream to a GridFS file + { + using (var fileStream = new FileStream("/path/to/input_file", FileMode.Open, FileAccess.Read)) + { + await bucket.UploadFromStreamAsync("new_file", fileStream); + } + } + + // Prints information about each file in the bucket + { + var filter = Builders.Filter.Empty; + var files = await bucket.FindAsync(filter); + await files.ForEachAsync(file => + { + Console.WriteLine(file.ToJson()); + }); + } + + // Downloads a file from the GridFS bucket by referencing its ObjectId value + { + var filter = Builders.Filter.Eq("filename", "new_file"); + var doc = await database.GetCollection("fs.files").Find(filter).FirstOrDefaultAsync(); + var id = doc["_id"].AsObjectId; + + using (var downloader = bucket.OpenDownloadStream(id)) + { + var buffer = new byte[downloader.FileLength]; + await downloader.ReadAsync(buffer, 0, buffer.Length); + // Process the buffer as needed + } + } + + // Downloads an entire GridFS file to a download stream + { + using (var outputFile = new FileStream("/path/to/output_file", FileMode.Create, FileAccess.Write)) + { + var filter = Builders.Filter.Eq("filename", "new_file"); + var doc = await database.GetCollection("fs.files").Find(filter).FirstOrDefaultAsync(); + var id = doc["_id"].AsObjectId; + + await bucket.DownloadToStreamAsync(id, outputFile); + } + } + + // Deletes a file from the GridFS bucket with the specified ObjectId + { + var filter = Builders.Filter.Eq("filename", "my_file"); + var doc = await database.GetCollection("fs.files").Find(filter).FirstOrDefaultAsync(); + var id = doc["_id"].AsObjectId; + + await bucket.DeleteAsync(id); + } + } +} diff --git a/source/includes/figures/GridFS-upload.png b/source/includes/figures/GridFS-upload.png new file mode 100644 index 0000000000000000000000000000000000000000..2207752bc6f9010ed0117b9d2fe7e92c97e5f3ea GIT binary patch literal 9225 zcmbt)hgTC_(6A9f}11%@*l`B^mo<7kszH;R% z?8+4ii)&Xe5%Fs?X_wPA=tF~tSFTjV(4E>*Uh4mN8S7|XK@W1TUMlR*^-UjNTwJgg zo65<_jn86L?agyq%3xu^7A;{_@9sNYxx#zpsn$bN#555#W4hFVImeKJ{Hm46vOP+sjCi2DR)5YWo_c{SJT`wKo=^+ z?@{A_EMX?S?0-gl^Up-}+a`4^tg)px)4^1;XD&oB7F4NO7e~dZZ`X%@sWX*bv1eQT zp|oB^s+S_xGr0je%Oa8v1@Vkej@rFFzcLd`sC`Lug#mTNZFlqye0A5W9fcT;QXGWR zJW$XS|1|(6yWx74SUzvxrRS0*V6@Bi(=AgbZSUFMb?@prjUj#5nc8D<;@5B5xK4ew zEnRFyI4WVX&_SF&PfR`=|K{(PDo^6LeGVI4pG{-K7v(dnTk6RuC?wLO-*7bwrH7lo zCC62ki2sbsD^G+i%eJYxQ31l@EuKW;LK;-fNZ|43Dsncxm@KB!uamoaof$*j;5%-K z;t-OWr2x)b`iS@1ik`sV^nO8-hM&=Za&d*b^$cDy@nw%#^E~7006vWLC|nsf%3r;k z@Sqnf5;CO*>GrKCW6$ox8%OGb_KGmuRv)D(5ml*am0ln4?;m|A&k$p!i})QwcZQEz z`JM>Y@TI&rn9zZCK*VhN2y~owiuHhL07(Mj6XdCUI#f7j#lPc+s(_%OMKc}I4aZ-- zO>Cn8?hn{{R+@An=?fIw^N-x>@dM2~xBr=es9rdV$}R(TwPfaRIHNQ&JMB=lN3+RE zz;gMYtefE|szuBb>#$rANq>xJ6o;Dd(uyiZLQ)k%yxUyiBY6hSKGKV{lr8@@xR8&Q zjr}wu5iD$`IN;PR*_>alx14@J{62t-f)juAF4V6D(OO{~V4{LQqnD8X>a}R_2rmqo zmP+*oed8K5WXRas9h1*e1N35!Yf3dL`00W(_8T z1P8pm{J%>59k^1=Ed3O#w$d!gltrzYBV41ahj}DA#@#T&Nu=+&aeGqD`OU|tZRosZ z`i~qREK$n;MvaVubUsU$%Z7uyb)oNaqreR}<2$-QKvsDYjD@J%HWix3nhf??t_VD1 zU7XCq>-+n{+ONV??M@!!CUP8``lsf8>q~ohyg9I)Y#M~G{epYhoIYLR@oe@|f`p=^ zi3ofLP0S8xv9@Lb6J1kmHX1+;TTFQu-_dVfnXBS8P;a0yc^OTB;29|C-^eo%76pL{OM7Wc9$XuGqEYx-)B=|@hppmo zTGEosxn=fExG}GzMw@4*g81tiPwwi*QU_HJRmhY4w`0CZA^N-__!FWPu9j9>tHbL~ zm?K9PHrk0+KEo+bZ-_XqBdq$yGSfsai*=i=XLrOtA!@*B?X{r8Ic%`T=_Adr3zgeXY|M3|P)sa6@NWP)+n*n2*ckq^jR++6RZ-Mtq zp(UM-^@7#oPQmP&fAFdV97bMKLT6?0-|P}DT1-X%2FBBa*V!$(L_P$?OsqT$2Vk{x zo3Z24XdU7qLx=Ve@d!ugr^Be^{NozOm zo>HTeoc#)^7Af=cKdqvTS^l;omVB<8-QtLX+7=o!e|lAzAENJAV5_==4J?~$Z%1ga zT06nk7`j}G$hM73$A(dnbd&moimjkOpXEp4QZ_yekvpTob4>x=#nn6bD-R_RN<(`yV$y>MG9XDJWZ=;el_1xX8e8V{zSP|K2`n0bnnSAKWS&L8KfZ zQ$V(j2RM}c7q~FNQlor*MFlq5cK{qQc45*{;F&KM#+TPs9j*@r2X|0d%9%Dk6I@fdul zGvUmZ7M4TgH#x{?$mN~k;4Z#*U&n8pvxK5X&QP35R0c&F!jE?0kOR05 z_|Q%6dQgs{;w+pSB&?z%nGiCMZiRK>*jMz<@`!a0+CFHqa4A4k{h znob_~UW+HUP49nV_-74r2JUb6uXWkM7uLI$7tg>OPd?ntf=(;~EFB@#=8BuBXO#IF z3ZLbVBpCmSya;S2CqI;eha&us8hg`J#*&FNfkkA~{)Bj!bfNFlYyG3qzw6K$MMqqumn4Z)J>p1j5we66OO+a{Y#{7qA>J^+Vt-&WW8(dC=O zPDJkR8xl;ej_YHkM0ss&;yl!N*|r&s_|r< z*CC3Pc=~6;d$|Layj;H&w1ncF&al=eB}E_lM-je*@D4YV)EMR2_ul;^X4(56z8{`s zF0m9C*9x;|Z-ZJ;3s^)9^-RZSV(ojg7N2JweO}E~+D_RO!NYd9v3!t82@NHaf3i+b zu8T?#qk_}|yq@zBF5yzAo`OY-P1K?!?Z}D8wdRvkgtFQcpUoEh$MfO;`3RwabMN5D(jw857YB36y@rI&B51+=k5N|~O(!7llV5R>u?9?{h|W+JkQ zXZv`mK)U*d8=^n~P+iyO;x=~)@`{(v5v#k#pl#IFR;97)6#|E_#t-i*)@_vZmQ1QO zj{`M9{{E#U$8AZ)lwh_1sJ5$Ao%$f-5!!O=X0ze&4MUB2?uC)8lc^y-4 zOhOJO4pC7E-!&B^6_Lb*-?(Dk?({SxQ^8kI>!W?hOR6CYq;OO+1M{LVk3_HtPpG=C^G01l0+j*&r)7TN~| zhlERm%f}$tH1RObT;5Cs<8gZow4I?alyqS+Akf)&6K0TZ6$HN^$+;6f&RxwgAR0cZ)$aVz1Exo-}cX$~T@ns4~M=|XQHdS+tOR|dU| zv@|oE-LG?U4gX4wr2zVEz={xI-|y&+d{|%|g}TB{V~+e4m=^oo9Uw!^x!;X-r3Q%q z8`Omid764-L_tNwA1D zzhX?ucL(B+y^8ty?PFvn8k2kpuET#y+!bIZ4zD@!9-B=*hE=^RGR{UJw~WDf%M#%j z3jfCe?-|`+y}wn;S^JV#iSbBMJ%~+lW$4Y@@969xi++lpYl7dVXT}}iS?EOdRrD}S zTR08Hvx2eSGG@YC!V~df0k93m2@d?$Ql}ZewGWK5TW{}_v=mmq)>1s=QuYhIm(yUg zYG_{kf>Tx8Te~2YfQmycZEf58Snxqy6if?32xp%Kt9e+k19B1!w3bJouBb)SJ6VwxP;#_R82HSciD3_bG*~2)Izf^nFSR+`;I5 zPEp&zeEFPmwhfd=vMql#e}1b-xCehlT7#l2??A1F7ohVXW#h>Y47I9UYW+& z%3!%{5ERRS-%CJ^Tn-gtz&u?0au{H9-Y`?xG(o`p=U<7p=i#Ci8IX zf|g=x#Zb287O~tG>Rk{=IO_{`$OYb>4Jrl|WE1f3Ug#x2*OuY0u&27g{8^lM=LNW2 zYk*ZpA1^|-VQhfBa&_)yE`UE}l{raUU z-+`x$46(u4BI9c~RYH?P1nTR++`!kqY46t@FiyGMT?FDDvg?g2;#G;#H{!O+t|#$j zJG!ryhA}iBJJiYf&6=o{@NwhL3dLhN;b&2xwD*$8((l{Nlo6KD!X zc3X1xVw3r7G(biDQJM zTJjN;rpis8!|yTAG+o6w_TzA3?HzB}8k|pv+jP~Q>$Rt5u$M#fFSlw>74&`(-F#+p zgV?yYfMb@ew-g*06iEp~GoVTx{?>R(2xA!wvLtl{LNa(UOhS|I7*bF(LS7di;v1Pj zcwjI{boX^WQ7i6_!Dy;-0r5^ru@0v)f7>Y%BKx+|8e%&vwD=L{hfe&K?C@X&yCYD3 ze;ghP`ug>b2W(-Halbtf7s6DvpIuHj&pezz2A1^Y-{ zlDn`=IHhhIIFRi#{wlu_!P2oGssC@dQZdQ)`q@ECNUBUeKX7~Km4k=7q{i;AEUd$| zmVlxH_Vd=Owvl7G{{QM7%Z{mfO_j+|t1{OcbloU)e`Ko@wghred7XrJK;o@_(gyj? z$$-BU@BtaGb~hQIuRsGAZs5K<1Aka}AH3Ac-=w?>+*r$u4K%k9g#Wk|aHeFiIecG( zzVJ@IFK7X_nQ?$P{$uG==QzJ?8t97mQGA84RMK~Aa(q&O42-XE=)MPJY9Uv=YLPejdoiVD@etl3$LG2gIS5m>I4A7}OUr!?95Zr*g57sG^1n#FfX0ttm`9hGWPTb>1 z5yu{3S09ShpiOsWaZdlX-dTOkD?RL|)T0;@QLI`Z$-8c`;HW1E z`_fH*47>)1PoLmz;9X06=F(Lq&0+E5&!(=e_A$0C%(4*0IGLPv<152RMce={0J21sB#}Pvp+MIN zYCq&NivzQs{whtX#Mmc#s2G#u+9m*ClNwD36S_LsDnB;x0O9J$f3 z(Kp+Wvxvzndq~vZgD98U&ooKzcU7R-Q7P}k;=OofWoAW#c%rxFKJ4DGah4} zbF(5>7vb^Phw|UIVTOXlH&#pmy=b13_@A{2Ic`Mav*hplkl^q%dtmP?<<)tAW!USA z;`8^Q9YFnJ+{*}Sf!`vU=78v#Us-3Ci`)-I4L~Y>Rxqz?F?VB!Mlw}*$H<3Md83AX z%o#r2$&@7~u<$*?6 z%-ps5kI=5_O@@KPgEpcPMg-?3qJ)-gMOx3@$YNQ}K5)ALEP$20>M!-H>af<=U@t@pr<^E_RbPI1ObQOp2|P?r^B9 z+@EOm)ilwAf2pc83DVzB$WJCbwX=Y_`_*(i%8%l!c1*fvW`QaBLGy26I|4A;RZ@o6 zhHm|}wQ>_Rrx7jqD{kl?dAH{I#)*?)i_Zp;!z1L_c_qc*bcJIfACP_sqaof$Cl{3n z178$bipmHTml8&ZHrg0v!FS`*PDZ+LxyOmahI;1mC9I~~z#&z}vZyeZg|Nt%i{*K` zt(f93Bo#*7av7`Wwe;sqE$c7$mPx-)jXRscxfmBdVhJd7rRj5U@I(i>A!Sb4gq2g; zU42ry;eywN6YujvyfOI34X=Q*Xo5&eLPKJM<^3MoOLtch_@asrn`H*^Swis&)m za}Fw%3;w^4yf<~5zid!}VXyHc_+p!E!+MF;_gsKIFHklJZq+-gNeuNxj_v!y=APqPc{tTynBV4-h$9z+>ZNzlJcoNY`B8anXnLhN@-|?WJkc50Q$n zs(jMtOY&lC@h9uQONxOTS+1vspAz%Xm#!MoB$ZOuSpT~~s*mF-dMt6Vd#{kV88j@{ z0QlGZRuVqO2XCMrdQB^_M32UQV|+aUrQTV;wmb-48tXloFd1##VR9WMPh5 z^zjv~@0$X%on;Hdenk<~M-OPioPzJzH_fy-;sV2D`_K(=Ip_2DaQQ?rz}iQ zdO? z0003=stkii5bg1QKAn5ixU~|&6U5&rM&SA$OH{K=p=qV*_Fx2jqUsBSU_a9%#TU)i z-v@vacv9uOcFQTQWPwV!5io!q8_V8b?tAND-vk(4Dpkfk6lB9ha0tQ)LsyAeXMcJ8xhOj z_|?k!*7n*zAMg~Dm@%jBTByZ~%AXhr)M8xxGB76X7i1&~Bv#)7kXpZ{8x| z7Ij(6hJg$D;k{_jzbL;=bksfEz=MYSid6N}{Fo#+JDUa2Q65HLe*lxMZr^nO_uxBY z+_{xY-4QM+snXibV_W}0DI8|IB69C!h?8oL#TlO4x8s*htYk2Bt^Tf3J!b@awKs6u zBz>8{`iq5znbYkU`K=;IO0pPCij&2k&82&;9b^1bm|N_e5y9-L4V$7ngvb)b&B*tA z=qUL1An#mO&FAHJ>YHb+SI8{@8ty$AL`uWod|Bq{NH*^*76C3L0WuclH6ceXpG(?B z24^WCrew%iJVT>v;brkC3}9#)@2}$1#^lII&s+N!AK=jF9k>1W9ad{77G6xPA2h~Z zVA7Zj`G?}tVSj}tq-G3Ir;~E39R<$Q!9G-0%V4SL{Xu60+>|WG_St|Q7d@P+*mGHC zL8Tg#*_2b$#I8G|F0pX^ortoN(+|PGEaTNVP&=S79@rH`8hH2%T{!2gUi4;uj`bHh zZB9CP{%!hXA|FNpQ3rCoEazBIV;Fpsajq3WL=yK8knNaBKj=n%7!%oW8Gn{F#rYF+ z3$e`9wYw~jfNY|{b6{0ST_D3Ba9<-vYOaE9PCmHlB#&K|iflDQXvIuUru`2Y_3!_P zgG1rJ&;xU&!8d$95z)-XvW>-=c#cZf2)Ju@uVnUCSceX-;yXW@6dZzzSzfxwFWso>{2D9!1Ud>NIA0%}Wj&nJyPSKFP|DY5)0( z@zp(E%%eZg_QnsmV!{3oVZRu8f#-riwadl^UmV!KitgP_tKKhO9}oPcH-U}hVqt582K92N{;9;T-{?x6e@ZhbH?57+2U0RJJBJOwYij5?^TIS+^ zV-y=D?q?M9iE$8Cno0LJ#~T)ygrYCfg#|joum5WJ*m`7sZwyhTDBB8e_bntr!G zZR7BehjAr~RqFvkls+RV1*e&f>-5?8-ov|=q_h1;UN|Xc`m0*b?#2zx#xi_3K~Mhj zeZs#`KyUrjPtiOLl^t+^-3-LqwPz_Zjq!zZC;4?RuQETs8rP5PD>V6NJxP8Fh#kem zR?Z6uCdq(V2Khm|clp#7ci(0rV+s4LILoys3!eum8NRMKmplo6T08f6`>DsIYmp2F zS1By}qK6bxx&8%v)9tI!GwVCV!x**tIfIVzgbP^VIESDpLoey2enM7M0YCrE3h{=x zbj!dIu43Yk6+lDV|m-C?n{!P6I`Ng(fwMD6I{>fONx`u7``-}-PzE4ETw?|W@4ySk74wa z*;Ugt0j4br`O?vU83j2HFeW1Q5|~vvO;}ASyia%dynoPPdI!y%7|)_doqYr`&3;OQe$h3wNh#j7@;H3{`s|~JFj9be44YTJN2JTrO9Y$G zDwME;8;MgM^aIa`R=C_|#XW^4w-cfd?*gvkm?wvK*Yn5RM~SJ#fr;x`EIgiF2Chk2(}*+)za0;Gz(=6#X&Ig8 zV^a8swGW_{^&U0pu80a%$Dv0WmU1-aqj^>5=~+h>iZ7$e6TDOOf_T)ne3iaIxe!@z zR48%ZmBG9PjU*Up14P V9DT{TC;T7J)5nHdXieMD{|6(4qLu&v literal 0 HcmV?d00001 From 2801f95787d566f8fcd97d8f56fdb2007cd0e4f9 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Thu, 7 Nov 2024 16:54:38 -0600 Subject: [PATCH 14/35] wip --- source/fundamentals/gridfs.txt | 84 +++++++++++--- source/includes/code-examples/GridFS.cs | 141 +++++++++++++++--------- 2 files changed, 154 insertions(+), 71 deletions(-) diff --git a/source/fundamentals/gridfs.txt b/source/fundamentals/gridfs.txt index e7cd8d79..f059635c 100644 --- a/source/fundamentals/gridfs.txt +++ b/source/fundamentals/gridfs.txt @@ -148,36 +148,84 @@ Upload Files You can upload files to a GridFS bucket by using the following methods: -- :ref:`open_upload_stream() `: Opens a new upload stream to which - you can write file contents -- :ref:`upload_from_stream() `: Uploads the contents of an existing - stream to a GridFS file +- ``OpenUploadStream()``: Opens a new upload stream to which you can write file contents +- ``UploadFromStream()``: Uploads the contents of an existing stream to a GridFS file + +The following sections describe these methods in more detail. .. _gridfs-open-upload-stream: Write to an Upload Stream ~~~~~~~~~~~~~~~~~~~~~~~~~ -Use the ``open_upload_stream()`` method to create an upload stream for a given -file name. The ``open_upload_stream()`` method allows you to specify configuration -information in an ``options::gridfs::upload`` instance, which you can pass as a -parameter. +Use the ``OpenUploadStream()`` method to create an upload stream for a given +file name. This method accepts the following parameters: -This example uses an upload stream to perform the following -actions: +.. list-table:: -- Sets the ``chunk_size_bytes`` field of an options instance -- Opens a writable stream for a new GridFS file named ``"my_file"`` - and applies the ``chunk_size_bytes`` option -- Calls the ``write()`` method to write data to ``my_file``, which the stream points to -- Calls the ``close()`` method to close the stream pointing to ``my_file`` - -.. literalinclude:: /includes/write/gridfs.cpp - :language: cpp + * - Parameter + - Description + * - ``filename`` + - | The name of the file to upload. + | + | **Data type**: {+string-data-type+} + * - ``options`` + - | *Optional.* An instance of the ``GridFSUploadOptions`` class that specifies the + configuration for the upload stream. The default value is ``null``. + | + | **Data type**: `GridFSUploadOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.OpenUploadStream.html>`__ + * - ``cancellationToken`` + - | *Optional.* A token that you can use to cancel the operation. + | + | **Data type**: `CancellationToken `__ + +The following code example demonstrates how to open an upload stream by performing the +following steps: + +- Calls the ``OpenUploadStream()`` method to open a writable GridFS stream for a new file + named ``"my_file"`` +- Calls the ``Write()`` method to write data to ``my_file`` +- Calls the ``Close()`` method to close the stream that points to ``my_file`` + +.. literalinclude:: /includes/code-examples/GridFS.cs + :language: csharp :dedent: :start-after: start-open-upload-stream :end-before: end-open-upload-stream +To customize the upload stream configuration, pass an instance of the +``GridFSUploadOptions`` class to the ``OpenUploadStream()`` method. The ``GridFSUploadOptions`` +class contains the following properties: + +.. list-table:: + + * - Property + - Description + * - ``BatchSize`` + - | The number of chunks to upload in each batch. The default value is ``16777216`` + divided by the value of the following property, ``ChunkSizeBytes``. + | + | **Data type**: ``int?`` + + * - ``ChunkSizeBytes`` + - | The maximum size of each chunk. + | + | **Data type**: ``int?`` + + * - ``Metadata`` + - | Metadata to store with the file. The default value is ``null``. + | + | **Data type**: `BsonDocument <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonDocument.html>`__ + +The following example performs the same steps as the preceding example, but also uses +the ``ChunkSizeBytes`` option to specify the maximum size of each chunk: + +.. literalinclude:: /includes/code-examples/GridFS.cs + :language: csharp + :dedent: + :start-after: start-open-upload-stream-with-options + :end-before: end-open-upload-stream-with-options + .. _gridfs-upload-from-stream: Upload an Existing Stream diff --git a/source/includes/code-examples/GridFS.cs b/source/includes/code-examples/GridFS.cs index b29ac969..1694c09e 100644 --- a/source/includes/code-examples/GridFS.cs +++ b/source/includes/code-examples/GridFS.cs @@ -8,6 +8,9 @@ class Program { static async Task Main(string[] args) + { } + + static void CreateBucket() { // Initialize MongoDB client // start-create-bucket @@ -17,84 +20,116 @@ static async Task Main(string[] args) // Creates a GridFS bucket or references an existing one var bucket = new GridFSBucket(database); // end-create-bucket + } + + static void CreateCustomBucket() + { + // Initialize MongoDB client + var client = new MongoClient(""); + var database = client.GetDatabase("db"); // Creates or references a GridFS bucket with a custom name // start-create-custom-bucket var options = new GridFSBucketOptions { BucketName = "myCustomBucket" }; var customBucket = new GridFSBucket(database, options); // end-create-custom-bucket + } + static void UploadFile() + { // Uploads a file called "my_file" to the GridFS bucket and writes data to it + // start-open-upload-stream + using (var uploader = bucket.OpenUploadStream("my_file", options)) { - var options = new GridFSUploadOptions - { - ChunkSizeBytes = 1048576 // 1 MB - }; - using (var uploader = bucket.OpenUploadStream("my_file", options)) - { - // ASCII for "HelloWorld" - byte[] bytes = { 72, 101, 108, 108, 111, 87, 111, 114, 108, 100 }; - - for (int i = 0; i < 5; i++) - { - await uploader.WriteAsync(bytes, 0, bytes.Length); - } - - await uploader.CloseAsync(); - } - } + // ASCII for "HelloWorld" + byte[] bytes = { 72, 101, 108, 108, 111, 87, 111, 114, 108, 100 }; - // Uploads data to a stream, then writes the stream to a GridFS file - { - using (var fileStream = new FileStream("/path/to/input_file", FileMode.Open, FileAccess.Read)) + for (int i = 0; i < 5; i++) { - await bucket.UploadFromStreamAsync("new_file", fileStream); + uploader.Write(bytes, 0, bytes.Length); } + + uploader.Close(); } + // end-open-upload-stream + } - // Prints information about each file in the bucket + static void UploadFileWithOptions() + { + // Uploads a file called "my_file" to the GridFS bucket and writes data to it + // start-open-upload-stream-with-options + var options = new GridFSUploadOptions { - var filter = Builders.Filter.Empty; - var files = await bucket.FindAsync(filter); - await files.ForEachAsync(file => - { - Console.WriteLine(file.ToJson()); - }); - } + ChunkSizeBytes = 1048576 // 1 MB + }; - // Downloads a file from the GridFS bucket by referencing its ObjectId value + using (var uploader = bucket.OpenUploadStream("my_file", options)) { - var filter = Builders.Filter.Eq("filename", "new_file"); - var doc = await database.GetCollection("fs.files").Find(filter).FirstOrDefaultAsync(); - var id = doc["_id"].AsObjectId; + // ASCII for "HelloWorld" + byte[] bytes = { 72, 101, 108, 108, 111, 87, 111, 114, 108, 100 }; - using (var downloader = bucket.OpenDownloadStream(id)) + for (int i = 0; i < 5; i++) { - var buffer = new byte[downloader.FileLength]; - await downloader.ReadAsync(buffer, 0, buffer.Length); - // Process the buffer as needed + uploader.Write(bytes, 0, bytes.Length); } + + uploader.Close(); } + // end-open-upload-stream-with-options + } - // Downloads an entire GridFS file to a download stream + static void UploadStream() + { + // Uploads data to a stream, then writes the stream to a GridFS file + using (var fileStream = new FileStream("/path/to/input_file", FileMode.Open, FileAccess.Read)) { - using (var outputFile = new FileStream("/path/to/output_file", FileMode.Create, FileAccess.Write)) - { - var filter = Builders.Filter.Eq("filename", "new_file"); - var doc = await database.GetCollection("fs.files").Find(filter).FirstOrDefaultAsync(); - var id = doc["_id"].AsObjectId; - - await bucket.DownloadToStreamAsync(id, outputFile); - } + bucket.UploadFromStream("new_file", fileStream); } + } - // Deletes a file from the GridFS bucket with the specified ObjectId - { - var filter = Builders.Filter.Eq("filename", "my_file"); - var doc = await database.GetCollection("fs.files").Find(filter).FirstOrDefaultAsync(); - var id = doc["_id"].AsObjectId; +// Prints information about each file in the bucket +{ + var filter = Builders.Filter.Empty; + var files = await bucket.FindAsync(filter); + await files.ForEachAsync(file => + { + Console.WriteLine(file.ToJson()); + }); +} - await bucket.DeleteAsync(id); - } +// Downloads a file from the GridFS bucket by referencing its ObjectId value +{ + var filter = Builders.Filter.Eq("filename", "new_file"); + var doc = await database.GetCollection("fs.files").Find(filter).FirstOrDefaultAsync(); + var id = doc["_id"].AsObjectId; + + using (var downloader = bucket.OpenDownloadStream(id)) + { + var buffer = new byte[downloader.FileLength]; + await downloader.ReadAsync(buffer, 0, buffer.Length); + // Process the buffer as needed + } +} + +// Downloads an entire GridFS file to a download stream +{ + using (var outputFile = new FileStream("/path/to/output_file", FileMode.Create, FileAccess.Write)) + { + var filter = Builders.Filter.Eq("filename", "new_file"); + var doc = await database.GetCollection("fs.files").Find(filter).FirstOrDefaultAsync(); + var id = doc["_id"].AsObjectId; + + await bucket.DownloadToStreamAsync(id, outputFile); + } +} + +// Deletes a file from the GridFS bucket with the specified ObjectId +{ + var filter = Builders.Filter.Eq("filename", "my_file"); + var doc = await database.GetCollection("fs.files").Find(filter).FirstOrDefaultAsync(); + var id = doc["_id"].AsObjectId; + + await bucket.DeleteAsync(id); +} } } From bdb866d0a8faee252cf18ea249a59cec80ff582b Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Fri, 8 Nov 2024 16:40:08 -0600 Subject: [PATCH 15/35] wip --- source/fundamentals/gridfs.txt | 138 ++++++++++++++++-------- source/includes/code-examples/GridFS.cs | 48 ++++++--- 2 files changed, 127 insertions(+), 59 deletions(-) diff --git a/source/fundamentals/gridfs.txt b/source/fundamentals/gridfs.txt index f059635c..67062f8d 100644 --- a/source/fundamentals/gridfs.txt +++ b/source/fundamentals/gridfs.txt @@ -213,10 +213,18 @@ class contains the following properties: | **Data type**: ``int?`` * - ``Metadata`` - - | Metadata to store with the file. The default value is ``null``. + - | Metadata to store with the file, including the following elements: + + | - The ``_id`` of the file + - The name of the file + - The length and size of the file + - The upload date and time + - A ``metadata`` document in which you can store other information + + | The default value is ``null``. | | **Data type**: `BsonDocument <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonDocument.html>`__ - + The following example performs the same steps as the preceding example, but also uses the ``ChunkSizeBytes`` option to specify the maximum size of each chunk: @@ -231,58 +239,95 @@ the ``ChunkSizeBytes`` option to specify the maximum size of each chunk: Upload an Existing Stream ~~~~~~~~~~~~~~~~~~~~~~~~~ -Use the ``upload_from_stream()`` method to upload the contents of a stream to -a new GridFS file. The ``upload_from_stream()`` method allows you to specify configuration -information in an ``options::gridfs::upload`` instance, which you can pass as a -parameter. +Use the ``UploadFromStream()`` method to upload the contents of a stream to a new GridFS +file. This method accepts the following parameters: -This example performs the following actions: +.. list-table:: + + * - Parameter + - Description + + * - ``filename`` + - | The name of the file to upload. + | + | **Data type**: {+string-data-type+} + + * - ``source`` + - | The stream from which to read the file contents. + | + | **Data type**: `Stream `__ + + * - ``options`` + - | *Optional.* An instance of the ``GridFSUploadOptions`` class that specifies the + configuration for the upload stream. The default value is ``null``. + | + | **Data type**: `GridFSUploadOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.OpenUploadStream.html>`__ + + * - ``cancellationToken`` + - | *Optional.* A token that you can use to cancel the operation. + | + | **Data type**: `CancellationToken `__ + +The following code example demonstrates how to open an upload stream by performing the +following steps: - Opens a file located at ``/path/to/input_file`` as a stream in binary read mode -- Calls the ``upload_from_stream()`` method to upload the contents of the stream - to a GridFS file named ``"new_file"`` +- Calls the ``UploadFromStream()`` method to write the contents of the stream to a GridFS + file named ``"new_file"`` -.. literalinclude:: /includes/write/gridfs.cpp - :language: cpp +.. literalinclude:: /includes/code-examples/GridFS.cs + :language: csharp :dedent: - :start-after: start-upload-from-stream - :end-before: end-upload-from-stream + :start-after: //start-upload-from-stream + :end-before: //end-upload-from-stream .. _gridfs-retrieve-file-info: Retrieve File Information ------------------------- -In this section, you can learn how to retrieve file metadata stored in the -``files`` collection of the GridFS bucket. The metadata contains information -about the file it refers to, including: +To retrieve files from a GridFS bucket, call the ``Find()`` method on your ``GridFSBucket`` +instance. This method accepts the following parameters: + +.. list-table:: + + * - Parameter + - Description + + * - ``filter`` + - | A query filter that specifies the entries to match in the ``files`` collection. + | **Data type**: `FilterDefinition <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.FilterDefinition-1.html>`__<`GridFSFileInfo <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSFileInfo.html>`__> -- The ``_id`` of the file -- The name of the file -- The length/size of the file -- The upload date and time -- A ``metadata`` document in which you can store other information + * - ``source`` + - | The stream from which to read the file contents. + | + | **Data type**: `Stream `__ -To retrieve files from a GridFS bucket, call the ``mongocxx::gridfs::bucket::find()`` -method on your bucket. The method returns a ``mongocxx::cursor`` instance from -which you can access the results. To learn more about cursors, see the -:ref:`` guide. + * - ``options`` + - | *Optional.* An instance of the ``GridFSFindOptions`` class that specifies the + configuration for the find operation. The default value is ``null``. + | + | **Data type**: `GridFSFindOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSFindOptions.html>`__ -Example -~~~~~~~ + * - ``cancellationToken`` + - | *Optional.* A token that you can use to cancel the operation. + | + | **Data type**: `CancellationToken `__ The following code example shows how to retrieve and print file metadata -from files in a GridFS bucket. It uses a ``for`` loop to iterate through +from files in a GridFS bucket. The ``Find()`` method returns an +``IAsyncCursor`` instance from +which you can access the results.It uses a ``foreach`` loop to iterate through the returned cursor and display the contents of the files uploaded in the -:ref:`gridfs-upload-files` examples: +:ref:`gridfs-upload-files` examples. .. io-code-block:: :copyable: - .. input:: /includes/write/gridfs.cpp - :start-after: start-retrieve-file-info - :end-before: end-retrieve-file-info - :language: cpp + .. input:: /includes/code-examples/GridFS.cs + :start-after: start-find + :end-before: end-find + :language: csharp :dedent: .. output:: @@ -293,10 +338,20 @@ the returned cursor and display the contents of the files uploaded in the { "_id" : { "$oid" : "..." }, "length" : 50, "chunkSize" : 1048576, "uploadDate" : { "$date" : ... }, "filename" : "my_file" } -The ``find()`` method accepts various query specifications. You can use its -``mongocxx::options::find`` parameter to specify the sort order, maximum number of -documents to return, and the number of documents to skip before returning. To -view a list of available options, see the `API documentation <{+api+}/classmongocxx_1_1v__noabi_1_1options_1_1find.html>`__. +To customize the find operation, pass an instance of the +``GridFSFindOptions`` class to the ``Find()`` method. The ``GridFSFindOptions`` +class contains the following properties: + +.. list-table:: + + * - Property + - Description + + * - ``Sort`` + - | The sort order of the results. If you don't specify a sort order, the ``Find()`` + method returns the results in the order in which they were inserted. + | + | **Data type**: `SortDefinition <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSFindOptions.Sort.html#MongoDB_Driver_GridFS_GridFSFindOptions_Sort>`__<`GridFSFileInfo <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSFileInfo.html>`__> .. _gridfs-download-files: @@ -385,12 +440,3 @@ API Documentation To learn more about using the {+driver-short+} to store and retrieve large files, see the following API documentation: - -- `gridfs_bucket() <{+api+}/classmongocxx_1_1v__noabi_1_1database.html#afe549c42c37bfbf67d77a1ac1eaec422>`__ -- `mongocxx::options::gridfs::bucket <{+api+}/classmongocxx_1_1v__noabi_1_1options_1_1gridfs_1_1bucket.html>`__ -- `open_upload_stream() <{+api+}/classmongocxx_1_1v__noabi_1_1gridfs_1_1bucket.html#ad1f2b7ea5ee9068a9e2c0424ad3b3673>`__ -- `upload_from_stream() <{+api+}/classmongocxx_1_1v__noabi_1_1gridfs_1_1bucket.html#ad8fa27fb5be7c209211bdb071c5cca44>`__ -- `find() <{+api+}/classmongocxx_1_1v__noabi_1_1gridfs_1_1bucket.html#acd33e4ce5db96ec7bc50edf498a174c4>`__ -- `open_download_stream() <{+api+}/classmongocxx_1_1v__noabi_1_1gridfs_1_1bucket.html#a0ba68864a0cbaf60baf3fc1ef864858a>`__ -- `download_to_stream() <{+api+}/classmongocxx_1_1v__noabi_1_1gridfs_1_1bucket.html#ab6e51f650e11c5c6e8aea8f71a6ba04f>`__ -- `delete_file() <{+api+}/classmongocxx_1_1v__noabi_1_1gridfs_1_1bucket.html#a3c231ffa4ed1b1f278ca1f3ea2ca044d>`__ diff --git a/source/includes/code-examples/GridFS.cs b/source/includes/code-examples/GridFS.cs index 1694c09e..c5311db9 100644 --- a/source/includes/code-examples/GridFS.cs +++ b/source/includes/code-examples/GridFS.cs @@ -81,21 +81,43 @@ static void UploadFileWithOptions() static void UploadStream() { // Uploads data to a stream, then writes the stream to a GridFS file + //start-upload-from-stream using (var fileStream = new FileStream("/path/to/input_file", FileMode.Open, FileAccess.Read)) { bucket.UploadFromStream("new_file", fileStream); } + //end-upload-from-stream } -// Prints information about each file in the bucket -{ - var filter = Builders.Filter.Empty; - var files = await bucket.FindAsync(filter); - await files.ForEachAsync(file => + static void Find() { - Console.WriteLine(file.ToJson()); - }); -} + // Prints information about each file in the bucket + // start-find + var filter = Builders.Filter.Empty; + + var files = bucket.Find(filter); + + foreach (var file in files.ToList()) + { + Console.WriteLine(file.ToJson()); + } + // end-find + } + + static void FindAsync() + { + // Prints information about each file in the bucket + // start-find-async + var filter = Builders.Filter.Empty; + + var files = await bucket.FindAsync(filter); + + await files.ForEachAsync(file => + { + Console.WriteLine(file.ToJson()); + }); + // end-find-async + } // Downloads a file from the GridFS bucket by referencing its ObjectId value { @@ -104,11 +126,11 @@ await files.ForEachAsync(file => var id = doc["_id"].AsObjectId; using (var downloader = bucket.OpenDownloadStream(id)) - { - var buffer = new byte[downloader.FileLength]; - await downloader.ReadAsync(buffer, 0, buffer.Length); - // Process the buffer as needed - } +{ + var buffer = new byte[downloader.FileLength]; + await downloader.ReadAsync(buffer, 0, buffer.Length); + // Process the buffer as needed +} } // Downloads an entire GridFS file to a download stream From bda8067ec8f6fd3da581dce3182e21dd7716b911 Mon Sep 17 00:00:00 2001 From: Jordan Smith <45415425+jordan-smith721@users.noreply.github.com> Date: Mon, 11 Nov 2024 06:22:42 -0800 Subject: [PATCH 16/35] DOCSP-39979 Add example for ElemMatch builder (#288) (cherry picked from commit 051e6ca7839b975bae9937e569e420e4077b853f) --- source/fundamentals/builders.txt | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/source/fundamentals/builders.txt b/source/fundamentals/builders.txt index 88adf7a9..a3309e66 100644 --- a/source/fundamentals/builders.txt +++ b/source/fundamentals/builders.txt @@ -105,7 +105,19 @@ Use builders to check which documents in the collection have a var builder = Builders.Filter; var filter = builder.AnyEq(f => f.Season, "winter"); -.. TODO for a complete list of expressions, see the Query page? +You can also call the ``ElemMatch()`` method to find documents that have an +array field that contains at least one element that matches a specified search +criteria. The following example returns documents that contain the value +``"Summer"`` in their ``Season`` array: + +.. code-block:: csharp + :copyable: true + + var builder = Builders.Filter; + var filter = builder.ElemMatch(f => f.Season, s => s == "Summer"); + +To learn more about array operators, see the :manual:`Array Query Operators +` guide in the {+mdb-server+} manual. .. _csharp-builders-projection: From 118c066319183c7a8641522022d8143075dc8654 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Mon, 11 Nov 2024 12:26:10 -0600 Subject: [PATCH 17/35] wip --- source/fundamentals/gridfs.txt | 181 ++++++++++++++++-------- source/includes/code-examples/GridFS.cs | 50 ++++--- 2 files changed, 158 insertions(+), 73 deletions(-) diff --git a/source/fundamentals/gridfs.txt b/source/fundamentals/gridfs.txt index 67062f8d..00a764bd 100644 --- a/source/fundamentals/gridfs.txt +++ b/source/fundamentals/gridfs.txt @@ -281,6 +281,130 @@ following steps: :start-after: //start-upload-from-stream :end-before: //end-upload-from-stream +.. _gridfs-download-files: + +Download Files +-------------- + +You can download files from a GridFS bucket by using the following methods: + +- ``OpenDownloadStream()``: Opens a new download stream from which you can read file contents +- ``DownloadToStream()``: Writes the contents of a GridFS file to an existing stream + +The following sections describe these methods in more detail. + +.. _gridfs-open-download-stream: + +Read From a Download Stream +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Use the ``OpenDownloadStream()`` method to create a download stream. +This method accepts the following parameters: + +.. list-table:: + + * - Parameter + - Description + * - ``id`` + - | The ``_id`` value of the file to download. + | + | **Data type**: `BsonValue <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonValue.html>`__ + * - ``options`` + - | *Optional.* An instance of the ``GridFSDownloadOptions`` class that specifies the + configuration for the download stream. The default value is ``null``. + | + | **Data type**: `GridFSDownloadOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSDownloadOptions.html>`__ + * - ``cancellationToken`` + - | *Optional.* A token that you can use to cancel the operation. + | + | **Data type**: `CancellationToken `__ + +The following code example demonstrates how to open a download stream by performing the +following steps: + +- Retrieves the ``_id`` value of the GridFS file named ``"new_file"`` +- Calls the ``OpenDownloadStream()`` method and passes the ``_id`` value to open the + file as a readable GridFS stream +- Creates a ``buffer`` vector to store the file contents +- Calls the ``Read()`` method to read the file contents from the ``downloader`` + stream into the vector + +.. literalinclude:: /includes/code-examples/GridFS.cs + :language: csharp + :dedent: + :start-after: // start-open-download-stream + :end-before: // end-open-download-stream + +To customize the download stream configuration, pass an instance of the +``GridFSDownloadOptions`` class to the ``OpenDownloadStream()`` method. The +``GridFSDownloadOptions`` class contains the following properties: + +.. list-table:: + + * - Property + - Description + * - ``Seekable`` + - | Indicates whether the stream supports *seeking*, the ability to query and + change the current position in a stream. The default value is ``false``. + | + | **Data type**: ``bool?`` + +The following example performs the same steps as the preceding example, but also sets +the ``Seekable`` option to ``true`` to specify that the stream is seekable: + +.. literalinclude:: /includes/code-examples/GridFS.cs + :language: csharp + :dedent: + :start-after: start-open-download-stream-with-options + :end-before: end-open-download-stream-with-options + +.. _gridfs-download_to_stream: + +Download to an Existing Stream +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Use the ``DownloadToStream()`` method to download the contents of a GridFS file to an +existing stream. This method accepts the following parameters: + +.. list-table:: + + * - Parameter + - Description + * - ``id`` + - | The ``_id`` value of the file to download. + | + | **Data type**: `BsonValue <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonValue.html>`__ + * - ``destination`` + - | The stream that the {+driver-short+} downloads the GridFS file to. This property's + | value must be an object that implements the ``Stream`` class. + | + | **Data type**: `Stream `__ + * - ``options`` + - | *Optional.* An instance of the ``GridFSDownloadOptions`` class that specifies the + configuration for the download stream. The default value is ``null``. + | + | **Data type**: `GridFSDownloadOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSDownloadOptions.html>`__ + * - ``cancellationToken`` + - | *Optional.* A token that you can use to cancel the operation. + | + | **Data type**: `CancellationToken `__ + +The following code example demonstrates how to download to an existing stream by +performing the following actions: + +- Opens a file located at ``/path/to/output_file`` as a stream in binary write + mode + +- Retrieves the ``_id`` value of the GridFS file named ``"new_file"`` +- Calls the ``DownloadToStream()`` method and passes the ``_id`` value to download + the contents of ``"new_file"`` to a stream + +.. literalinclude:: /includes/write/gridfs.cpp + :language: cpp + :dedent: + :start-after: start-download-to-stream + :end-before: end-download-to-stream + .. _gridfs-retrieve-file-info: Retrieve File Information @@ -353,63 +477,6 @@ class contains the following properties: | | **Data type**: `SortDefinition <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSFindOptions.Sort.html#MongoDB_Driver_GridFS_GridFSFindOptions_Sort>`__<`GridFSFileInfo <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSFileInfo.html>`__> -.. _gridfs-download-files: - -Download Files --------------- - -You can download files from a GridFS bucket by using the following methods: - -- :ref:`open_download_stream() `: Opens a new download stream - from which you can read the file contents -- :ref:`download_to_stream() `: Writes the entire file to an - existing download stream - -.. _gridfs-open-download-stream: - -Read From a Download Stream -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You can download files from your MongoDB database by using the -``open_download_stream()`` method to create a download stream. - -This example uses a download stream to perform the following actions: - -- Retrieves the ``_id`` value of the GridFS file named ``"new_file"`` -- Passes the ``_id`` value to the ``open_download_stream()`` method to - open the file as a readable stream -- Creates a ``buffer`` vector to store the file contents -- Calls the ``read()`` method to read the file contents from the ``downloader`` - stream into the vector - -.. literalinclude:: /includes/write/gridfs.cpp - :language: cpp - :dedent: - :start-after: start-open-download-stream - :end-before: end-open-download-stream - -.. _gridfs-download_to_stream: - -Download to an Existing Stream -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You can download the contents of a GridFS file to an existing stream -by calling the ``download_to_stream()`` method on your bucket. - -This example performs the following actions: - -- Opens a file located at ``/path/to/output_file`` as a stream in binary write - mode -- Retrieves the ``_id`` value of the GridFS file named ``"new_file"`` -- Passes the ``_id`` value to ``download_to_stream()`` to download the file - to the stream - -.. literalinclude:: /includes/write/gridfs.cpp - :language: cpp - :dedent: - :start-after: start-download-to-stream - :end-before: end-download-to-stream - .. _gridfs-delete-files: Delete Files diff --git a/source/includes/code-examples/GridFS.cs b/source/includes/code-examples/GridFS.cs index c5311db9..386aa5b0 100644 --- a/source/includes/code-examples/GridFS.cs +++ b/source/includes/code-examples/GridFS.cs @@ -119,30 +119,48 @@ await files.ForEachAsync(file => // end-find-async } -// Downloads a file from the GridFS bucket by referencing its ObjectId value -{ - var filter = Builders.Filter.Eq("filename", "new_file"); - var doc = await database.GetCollection("fs.files").Find(filter).FirstOrDefaultAsync(); - var id = doc["_id"].AsObjectId; + static async Task DownloadFile() + { + // Downloads a file from the GridFS bucket by referencing its ObjectId value + // start-open-download-stream + var filter = Builders.Filter.Eq("filename", "new_file"); + var doc = await database.GetCollection("fs.files").Find(filter).FirstOrDefaultAsync(); + var id = doc["_id"].AsObjectId; - using (var downloader = bucket.OpenDownloadStream(id)) -{ - var buffer = new byte[downloader.FileLength]; - await downloader.ReadAsync(buffer, 0, buffer.Length); - // Process the buffer as needed -} -} + using (var downloader = bucket.OpenDownloadStream(id)) + { + var buffer = new byte[downloader.FileLength]; + await downloader.ReadAsync(buffer, 0, buffer.Length); + // Process the buffer as needed + } + // end-open-download-stream + } -// Downloads an entire GridFS file to a download stream -{ - using (var outputFile = new FileStream("/path/to/output_file", FileMode.Create, FileAccess.Write)) + static DownloadFile() + // Downloads a file from the GridFS bucket by referencing its ObjectId value { var filter = Builders.Filter.Eq("filename", "new_file"); var doc = await database.GetCollection("fs.files").Find(filter).FirstOrDefaultAsync(); var id = doc["_id"].AsObjectId; - await bucket.DownloadToStreamAsync(id, outputFile); + using (var downloader = bucket.OpenDownloadStream(id)) + { + var buffer = new byte[downloader.FileLength]; + await downloader.ReadAsync(buffer, 0, buffer.Length); + // Process the buffer as needed + } } + +// Downloads an entire GridFS file to a download stream +{ + using (var outputFile = new FileStream("/path/to/output_file", FileMode.Create, FileAccess.Write)) + { + var filter = Builders.Filter.Eq("filename", "new_file"); + var doc = await database.GetCollection("fs.files").Find(filter).FirstOrDefaultAsync(); + var id = doc["_id"].AsObjectId; + + await bucket.DownloadToStreamAsync(id, outputFile); +} } // Deletes a file from the GridFS bucket with the specified ObjectId From 8a1f17304916fb080254aa73f7c31248073b07b3 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Tue, 12 Nov 2024 08:22:36 -0600 Subject: [PATCH 18/35] wip --- source/fundamentals/gridfs.txt | 37 +++++++++++++++++++++---- source/includes/code-examples/GridFS.cs | 14 ++++++++-- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/source/fundamentals/gridfs.txt b/source/fundamentals/gridfs.txt index 00a764bd..4761d737 100644 --- a/source/fundamentals/gridfs.txt +++ b/source/fundamentals/gridfs.txt @@ -482,13 +482,32 @@ class contains the following properties: Delete Files ------------ -Use the ``delete_file()`` method to remove a file's collection document -and associated chunks from your bucket. This effectively deletes the file. -You must specify the file by its ``_id`` field rather than its file name. +To delete files from a GridFS bucket, call the ``Delete()`` method on your ``GridFSBucket`` +instance. This method removes a file's collection document and its associated chunks from +your bucket. -The following example shows how to delete a file named ``"my_file"`` by +The ``Delete()`` method accepts the following parameters: + +.. list-table:: + + * - Parameter + - Description + * - ``id`` + - | The ``_id`` of the file to delete. + | + | **Data type**: `BsonValue <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonValue.html>`__ + * - ``cancellationToken`` + - | *Optional.* A token that you can use to cancel the operation. + | + | **Data type**: `CancellationToken `__ + +The following code example shows how to delete a file named ``"my_file"`` passing its ``_id`` value to ``delete_file()``: +- Uses the ``Builders`` class to create a filter that matches the file named ``"my_file"`` +- Uses the ``Find()`` method to find the file named ``"my_file"`` +- Passes the ``_id`` value of the file to the ``Delete()`` method to delete the file + .. literalinclude:: /includes/write/gridfs.cpp :language: cpp :dedent: @@ -497,13 +516,19 @@ passing its ``_id`` value to ``delete_file()``: .. note:: File Revisions - The ``delete_file()`` method supports deleting only one file at a time. If + The ``Delete()`` method supports deleting only one file at a time. If you want to delete each file revision, or files with different upload times that share the same file name, collect the ``_id`` values of each revision. - Then, pass each ``_id`` value in separate calls to the ``delete_file()`` method. + Then, pass each ``_id`` value in separate calls to the ``Delete()`` method. API Documentation ----------------- To learn more about using the {+driver-short+} to store and retrieve large files, see the following API documentation: + +- `GridFSBucket <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.html>`__ +- `GridFSBucketOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucketOptions.html>`__ +- `GridFSDownloadOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSDownloadOptions.html>`__ +- `GridFSFindOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSFindOptions.html>`__ +- `GridFSUploadOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSUploadOptions.html>`__ diff --git a/source/includes/code-examples/GridFS.cs b/source/includes/code-examples/GridFS.cs index 386aa5b0..69293971 100644 --- a/source/includes/code-examples/GridFS.cs +++ b/source/includes/code-examples/GridFS.cs @@ -163,7 +163,8 @@ static DownloadFile() } } -// Deletes a file from the GridFS bucket with the specified ObjectId + // Deletes a file from the GridFS bucket with the specified ObjectId + static async Task DeleteFile() { var filter = Builders.Filter.Eq("filename", "my_file"); var doc = await database.GetCollection("fs.files").Find(filter).FirstOrDefaultAsync(); @@ -171,5 +172,14 @@ static DownloadFile() await bucket.DeleteAsync(id); } - } + +// Deletes a file from the GridFS bucket with the specified ObjectId +static void DeleteFile() +{ + var filter = Builders.Filter.Eq("filename", "my_file"); + var doc = await database.GetCollection("fs.files").Find(filter).FirstOrDefault(); + var id = doc["_id"].AsObjectId; + + bucket.Delete(id); } +} \ No newline at end of file From 06f3c9cc697c5334460161bbddd3a4cf97794209 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Tue, 12 Nov 2024 13:19:18 -0600 Subject: [PATCH 19/35] wip --- source/fundamentals/gridfs.txt | 28 +-- source/includes/code-examples/GridFS.cs | 300 ++++++++++++++++++++---- 2 files changed, 266 insertions(+), 62 deletions(-) diff --git a/source/fundamentals/gridfs.txt b/source/fundamentals/gridfs.txt index 4761d737..1df86ce1 100644 --- a/source/fundamentals/gridfs.txt +++ b/source/fundamentals/gridfs.txt @@ -231,8 +231,8 @@ the ``ChunkSizeBytes`` option to specify the maximum size of each chunk: .. literalinclude:: /includes/code-examples/GridFS.cs :language: csharp :dedent: - :start-after: start-open-upload-stream-with-options - :end-before: end-open-upload-stream-with-options + :start-after: // start-open-upload-stream-with-options + :end-before: // end-open-upload-stream-with-options .. _gridfs-upload-from-stream: @@ -278,8 +278,8 @@ following steps: .. literalinclude:: /includes/code-examples/GridFS.cs :language: csharp :dedent: - :start-after: //start-upload-from-stream - :end-before: //end-upload-from-stream + :start-after: // start-upload-from-stream + :end-before: // end-upload-from-stream .. _gridfs-download-files: @@ -355,8 +355,8 @@ the ``Seekable`` option to ``true`` to specify that the stream is seekable: .. literalinclude:: /includes/code-examples/GridFS.cs :language: csharp :dedent: - :start-after: start-open-download-stream-with-options - :end-before: end-open-download-stream-with-options + :start-after: // start-open-download-stream-with-options + :end-before: // end-open-download-stream-with-options .. _gridfs-download_to_stream: @@ -399,11 +399,11 @@ performing the following actions: - Calls the ``DownloadToStream()`` method and passes the ``_id`` value to download the contents of ``"new_file"`` to a stream -.. literalinclude:: /includes/write/gridfs.cpp - :language: cpp +.. literalinclude:: /includes/code-examples/GridFS.cs + :language: csharp :dedent: - :start-after: start-download-to-stream - :end-before: end-download-to-stream + :start-after: // start-download-to-stream + :end-before: // end-download-to-stream .. _gridfs-retrieve-file-info: @@ -508,11 +508,11 @@ passing its ``_id`` value to ``delete_file()``: - Uses the ``Find()`` method to find the file named ``"my_file"`` - Passes the ``_id`` value of the file to the ``Delete()`` method to delete the file -.. literalinclude:: /includes/write/gridfs.cpp - :language: cpp +.. literalinclude:: /includes/code-examples/GridFS.cs + :language: csharp :dedent: - :start-after: start-delete-files - :end-before: end-delete-files + :start-after: // start-delete-file + :end-before: // end-delete-file .. note:: File Revisions diff --git a/source/includes/code-examples/GridFS.cs b/source/includes/code-examples/GridFS.cs index 69293971..56a6975f 100644 --- a/source/includes/code-examples/GridFS.cs +++ b/source/includes/code-examples/GridFS.cs @@ -1,15 +1,11 @@ -using System; -using System.IO; -using System.Threading.Tasks; using MongoDB.Bson; using MongoDB.Driver; using MongoDB.Driver.GridFS; -class Program -{ - static async Task Main(string[] args) - { } +namespace Fundamentals; +class GridFS +{ static void CreateBucket() { // Initialize MongoDB client @@ -37,9 +33,16 @@ static void CreateCustomBucket() static void UploadFile() { + // Initialize MongoDB client + var client = new MongoClient(""); + var database = client.GetDatabase("db"); + + // Creates a GridFS bucket or references an existing one + var bucket = new GridFSBucket(database); + // Uploads a file called "my_file" to the GridFS bucket and writes data to it // start-open-upload-stream - using (var uploader = bucket.OpenUploadStream("my_file", options)) + using (var uploader = bucket.OpenUploadStream("my_file")) { // ASCII for "HelloWorld" byte[] bytes = { 72, 101, 108, 108, 111, 87, 111, 114, 108, 100 }; @@ -54,8 +57,46 @@ static void UploadFile() // end-open-upload-stream } + static async Task UploadFileWithOptionsAsync() + { + // Initialize MongoDB client + var client = new MongoClient(""); + var database = client.GetDatabase("db"); + + // Creates a GridFS bucket or references an existing one + var bucket = new GridFSBucket(database); + + // Uploads a file called "my_file" to the GridFS bucket and writes data to it + // start-open-upload-stream-with-options-async + var options = new GridFSUploadOptions + { + ChunkSizeBytes = 1048576 // 1 MB + }; + + using (var uploader = await bucket.OpenUploadStreamAsync("my_file", options)) + { + // ASCII for "HelloWorld" + byte[] bytes = { 72, 101, 108, 108, 111, 87, 111, 114, 108, 100 }; + + for (int i = 0; i < 5; i++) + { + await uploader.WriteAsync(bytes, 0, bytes.Length); + } + + await uploader.CloseAsync(); + } + // end-open-upload-stream-with-options-async + } + static void UploadFileWithOptions() { + // Initialize MongoDB client + var client = new MongoClient(""); + var database = client.GetDatabase("db"); + + // Creates a GridFS bucket or references an existing one + var bucket = new GridFSBucket(database); + // Uploads a file called "my_file" to the GridFS bucket and writes data to it // start-open-upload-stream-with-options var options = new GridFSUploadOptions @@ -78,108 +119,271 @@ static void UploadFileWithOptions() // end-open-upload-stream-with-options } + static async Task UploadStreamAsync() + { + // Initialize MongoDB client + var client = new MongoClient(""); + var database = client.GetDatabase("db"); + + // Creates a GridFS bucket or references an existing one + var bucket = new GridFSBucket(database); + + // Uploads data to a stream, then writes the stream to a GridFS file + // start-upload-from-stream-async + using (var fileStream = new FileStream("/path/to/input_file", FileMode.Open, FileAccess.Read)) + { + await bucket.UploadFromStreamAsync("new_file", fileStream); + } + // end-upload-from-stream-async + } + static void UploadStream() { + // Initialize MongoDB client + var client = new MongoClient(""); + var database = client.GetDatabase("db"); + + // Creates a GridFS bucket or references an existing one + var bucket = new GridFSBucket(database); + // Uploads data to a stream, then writes the stream to a GridFS file - //start-upload-from-stream + // start-upload-from-stream using (var fileStream = new FileStream("/path/to/input_file", FileMode.Open, FileAccess.Read)) { bucket.UploadFromStream("new_file", fileStream); } - //end-upload-from-stream + // end-upload-from-stream } static void Find() { + // Initialize MongoDB client + var client = new MongoClient(""); + var database = client.GetDatabase("db"); + + // Creates a GridFS bucket or references an existing one + var bucket = new GridFSBucket(database); + // Prints information about each file in the bucket // start-find var filter = Builders.Filter.Empty; var files = bucket.Find(filter); - foreach (var file in files.ToList()) + foreach (var file in files.ToEnumerable()) { Console.WriteLine(file.ToJson()); } // end-find } - static void FindAsync() + static async Task FindAsync() { + // Initialize MongoDB client + var client = new MongoClient(""); + var database = client.GetDatabase("db"); + + // Creates a GridFS bucket or references an existing one + var bucket = new GridFSBucket(database); + // Prints information about each file in the bucket // start-find-async var filter = Builders.Filter.Empty; var files = await bucket.FindAsync(filter); - await files.ForEachAsync(file => - { - Console.WriteLine(file.ToJson()); - }); + await files.ForEachAsync(file => { Console.WriteLine(file.ToJson()); }); // end-find-async } - static async Task DownloadFile() + static async Task DownloadFileAsync() { + // Initialize MongoDB client + var client = new MongoClient(""); + var database = client.GetDatabase("db"); + + // Creates a GridFS bucket or references an existing one + var bucket = new GridFSBucket(database); + // Downloads a file from the GridFS bucket by referencing its ObjectId value - // start-open-download-stream + // start-open-download-stream-async var filter = Builders.Filter.Eq("filename", "new_file"); var doc = await database.GetCollection("fs.files").Find(filter).FirstOrDefaultAsync(); var id = doc["_id"].AsObjectId; - using (var downloader = bucket.OpenDownloadStream(id)) + using (var downloader = await bucket.OpenDownloadStreamAsync(id)) { - var buffer = new byte[downloader.FileLength]; + var buffer = new byte[downloader.Length]; await downloader.ReadAsync(buffer, 0, buffer.Length); + + // Process the buffer as needed + } + // end-open-download-stream-async + } + + static void DownloadFile() + { + // Initialize MongoDB client + var client = new MongoClient(""); + var database = client.GetDatabase("db"); + + // Creates a GridFS bucket or references an existing one + var bucket = new GridFSBucket(database); + + // Downloads a file from the GridFS bucket by referencing its ObjectId value + // start-open-download-stream + var filter = Builders.Filter.Eq("filename", "new_file"); + var doc = database.GetCollection("fs.files").Find(filter).FirstOrDefault(); + var id = doc["_id"].AsObjectId; + + using (var downloader = bucket.OpenDownloadStream(id)) + { + var buffer = new byte[downloader.Length]; + downloader.Read(buffer, 0, buffer.Length); + // Process the buffer as needed } // end-open-download-stream } - static DownloadFile() - // Downloads a file from the GridFS bucket by referencing its ObjectId value + static async Task DownloadFileWithOptionsAsync() { + // Initialize MongoDB client + var client = new MongoClient(""); + var database = client.GetDatabase("db"); + + // Creates a GridFS bucket or references an existing one + var bucket = new GridFSBucket(database); + + // Downloads a file from the GridFS bucket by referencing its ObjectId value + // start-open-download-stream-async var filter = Builders.Filter.Eq("filename", "new_file"); var doc = await database.GetCollection("fs.files").Find(filter).FirstOrDefaultAsync(); var id = doc["_id"].AsObjectId; - using (var downloader = bucket.OpenDownloadStream(id)) + var options = new GridFSDownloadOptions { - var buffer = new byte[downloader.FileLength]; + Seekable = true + }; + + using (var downloader = await bucket.OpenDownloadStreamAsync(id, options)) + { + var buffer = new byte[downloader.Length]; await downloader.ReadAsync(buffer, 0, buffer.Length); + // Process the buffer as needed } + // end-open-download-stream-async } -// Downloads an entire GridFS file to a download stream -{ - using (var outputFile = new FileStream("/path/to/output_file", FileMode.Create, FileAccess.Write)) + static void DownloadFileWithOptions() { + // Initialize MongoDB client + var client = new MongoClient(""); + var database = client.GetDatabase("db"); + + // Creates a GridFS bucket or references an existing one + var bucket = new GridFSBucket(database); + + // Downloads a file from the GridFS bucket by referencing its ObjectId value + // start-open-download-stream-with-options var filter = Builders.Filter.Eq("filename", "new_file"); - var doc = await database.GetCollection("fs.files").Find(filter).FirstOrDefaultAsync(); - var id = doc["_id"].AsObjectId; + var doc = database.GetCollection("fs.files").Find(filter).FirstOrDefault(); + var id = doc["_id"].AsObjectId; - await bucket.DownloadToStreamAsync(id, outputFile); -} -} + var options = new GridFSDownloadOptions + { + Seekable = true + }; - // Deletes a file from the GridFS bucket with the specified ObjectId - static async Task DeleteFile() -{ - var filter = Builders.Filter.Eq("filename", "my_file"); - var doc = await database.GetCollection("fs.files").Find(filter).FirstOrDefaultAsync(); - var id = doc["_id"].AsObjectId; + using (var downloader = bucket.OpenDownloadStream(id, options)) + { + var buffer = new byte[downloader.Length]; + downloader.Read(buffer, 0, buffer.Length); + + // Process the buffer as needed + } + // end-open-download-stream-with-options + } + static async Task DownloadStreamAsync() + { + // Initialize MongoDB client + var client = new MongoClient(""); + var database = client.GetDatabase("db"); - await bucket.DeleteAsync(id); -} + // Creates a GridFS bucket or references an existing one + var bucket = new GridFSBucket(database); -// Deletes a file from the GridFS bucket with the specified ObjectId -static void DeleteFile() -{ - var filter = Builders.Filter.Eq("filename", "my_file"); - var doc = await database.GetCollection("fs.files").Find(filter).FirstOrDefault(); - var id = doc["_id"].AsObjectId; + // Downloads an entire GridFS file to a download stream + // start-download-to-stream-async + using (var outputFile = new FileStream("/path/to/output_file", FileMode.Create, FileAccess.Write)) + { + var filter = Builders.Filter.Eq("filename", "new_file"); + var doc = await database.GetCollection("fs.files").Find(filter).FirstOrDefaultAsync(); + var id = doc["_id"].AsObjectId; + + await bucket.DownloadToStreamAsync(id, outputFile); + } + // end-download-to-stream-async + } + + static void DownloadStream() + { + // Initialize MongoDB client + var client = new MongoClient(""); + var database = client.GetDatabase("db"); + + // Creates a GridFS bucket or references an existing one + var bucket = new GridFSBucket(database); - bucket.Delete(id); -} + // Downloads an entire GridFS file to a download stream + // start-download-to-stream + using (var outputFile = new FileStream("/path/to/output_file", FileMode.Create, FileAccess.Write)) + { + var filter = Builders.Filter.Eq("filename", "new_file"); + var doc = database.GetCollection("fs.files").Find(filter).FirstOrDefault(); + var id = doc["_id"].AsObjectId; + + bucket.DownloadToStream(id, outputFile); + // end-download-to-stream + } + } + + static async Task DeleteFileAsync() + { + // Initialize MongoDB client + var client = new MongoClient(""); + var database = client.GetDatabase("db"); + + // Creates a GridFS bucket or references an existing one + var bucket = new GridFSBucket(database); + + // Deletes a file from the GridFS bucket with the specified ObjectId + // start-delete-file-async + var filter = Builders.Filter.Eq("filename", "my_file"); + var doc = await database.GetCollection("fs.files").Find(filter).FirstOrDefaultAsync(); + var id = doc["_id"].AsObjectId; + + await bucket.DeleteAsync(id); + // end-delete-file-async + } + + static void DeleteFile() + { + // Initialize MongoDB client + var client = new MongoClient(""); + var database = client.GetDatabase("db"); + + // Creates a GridFS bucket or references an existing one + var bucket = new GridFSBucket(database); + + // Deletes a file from the GridFS bucket with the specified ObjectId + // start-delete-file + var filter = Builders.Filter.Eq("filename", "my_file"); + var doc = database.GetCollection("fs.files").Find(filter).FirstOrDefault(); + var id = doc["_id"].AsObjectId; + + bucket.Delete(id); + // end-delete-file + } } \ No newline at end of file From 3027991cf886fcf890ceac46e68ed16248888ff7 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Tue, 12 Nov 2024 13:23:21 -0600 Subject: [PATCH 20/35] revert compat --- source/compatibility.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/compatibility.txt b/source/compatibility.txt index ec543b32..ce124f4b 100644 --- a/source/compatibility.txt +++ b/source/compatibility.txt @@ -29,7 +29,7 @@ The first column lists the driver version. .. sharedinclude:: dbx/compatibility-table-legend.rst -.. sharedinclude:: dbx/mongodb-compatibility-table-csharp.rst +.. include:: /includes/mongodb-compatibility-table-csharp.rst Language Compatibility ---------------------- @@ -39,7 +39,7 @@ The following compatibility table specifies the recommended version of the The first column lists the driver version. -.. sharedinclude:: dbx/language-compatibility-table-csharp.rst +.. include:: /includes/language-compatibility-table-csharp.rst For more information on how to read the compatibility tables, see our guide on :ref:`MongoDB Compatibility Tables. ` From 5609b6ede348985455e239e8e528d16f1efc17b2 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Tue, 12 Nov 2024 14:59:23 -0600 Subject: [PATCH 21/35] fixes --- source/fundamentals/gridfs.txt | 332 ++++++++++++++++++------ source/includes/code-examples/GridFS.cs | 30 ++- 2 files changed, 278 insertions(+), 84 deletions(-) diff --git a/source/fundamentals/gridfs.txt b/source/fundamentals/gridfs.txt index 1df86ce1..2806f86e 100644 --- a/source/fundamentals/gridfs.txt +++ b/source/fundamentals/gridfs.txt @@ -90,7 +90,7 @@ The following example creates a new instance of the ``GridFSBucket`` class for t :dedent: :start-after: // start-create-bucket :end-before: // end-create-bucket - + .. _gridfs-create-custom-bucket: Customize the Bucket @@ -135,6 +135,7 @@ the ``GridFSBucket()`` constructor. The following table describes the properties The following example creates a bucket named ``"myCustomBucket"`` by passing an instance of the ``GridFSBucketOptions`` class to the ``GridFSBucket()`` constructor: + .. literalinclude:: /includes/code-examples/GridFS.cs :language: csharp :dedent: @@ -148,8 +149,10 @@ Upload Files You can upload files to a GridFS bucket by using the following methods: -- ``OpenUploadStream()``: Opens a new upload stream to which you can write file contents -- ``UploadFromStream()``: Uploads the contents of an existing stream to a GridFS file +- ``OpenUploadStreamAsync()`` or ``OpenUploadStream()``: Opens a new upload stream to which + you can write file contents +- ``UploadFromStreamAsync()`` or ``UploadFromStream()``: Uploads the contents of an existing + stream to a GridFS file The following sections describe these methods in more detail. @@ -158,8 +161,8 @@ The following sections describe these methods in more detail. Write to an Upload Stream ~~~~~~~~~~~~~~~~~~~~~~~~~ -Use the ``OpenUploadStream()`` method to create an upload stream for a given -file name. This method accepts the following parameters: +Use the ``OpenUploadStreamAsync()`` or ``OpenUploadStream()`` method to create an upload +stream for a given file name. These methods accept the following parameters: .. list-table:: @@ -173,7 +176,7 @@ file name. This method accepts the following parameters: - | *Optional.* An instance of the ``GridFSUploadOptions`` class that specifies the configuration for the upload stream. The default value is ``null``. | - | **Data type**: `GridFSUploadOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.OpenUploadStream.html>`__ + | **Data type**: `GridFSUploadOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.GridFSUploadOptions.html>`__ * - ``cancellationToken`` - | *Optional.* A token that you can use to cancel the operation. | @@ -187,15 +190,32 @@ following steps: - Calls the ``Write()`` method to write data to ``my_file`` - Calls the ``Close()`` method to close the stream that points to ``my_file`` -.. literalinclude:: /includes/code-examples/GridFS.cs - :language: csharp - :dedent: - :start-after: start-open-upload-stream - :end-before: end-open-upload-stream +Select the :guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the corresponding +code: + +.. tabs:: + + .. tab:: Asynchronous + :tabid: open-upload-stream-async + + .. literalinclude:: /includes/code-examples/GridFS.cs + :language: csharp + :dedent: + :start-after: // start-open-upload-stream-async + :end-before: // end-open-upload-stream-async + + .. tab:: Synchronous + :tabid: open-upload-stream-sync + + .. literalinclude:: /includes/code-examples/GridFS.cs + :language: csharp + :dedent: + :start-after: // start-open-upload-stream + :end-before: // end-open-upload-stream To customize the upload stream configuration, pass an instance of the -``GridFSUploadOptions`` class to the ``OpenUploadStream()`` method. The ``GridFSUploadOptions`` -class contains the following properties: +``GridFSUploadOptions`` class to the ``OpenUploadStreamAsync()`` or ``OpenUploadStream()`` +method. The ``GridFSUploadOptions`` class contains the following properties: .. list-table:: @@ -226,21 +246,37 @@ class contains the following properties: | **Data type**: `BsonDocument <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonDocument.html>`__ The following example performs the same steps as the preceding example, but also uses -the ``ChunkSizeBytes`` option to specify the maximum size of each chunk: +the ``ChunkSizeBytes`` option to specify the maximum size of each chunk. Select the +:guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the corresponding +code. -.. literalinclude:: /includes/code-examples/GridFS.cs - :language: csharp - :dedent: - :start-after: // start-open-upload-stream-with-options - :end-before: // end-open-upload-stream-with-options +.. tabs:: + + .. tab:: Asynchronous + :tabid: open-upload-stream-with-options-async + + .. literalinclude:: /includes/code-examples/GridFS.cs + :language: csharp + :dedent: + :start-after: // start-open-upload-stream-with-options-async + :end-before: // end-open-upload-stream-with-options-async + + .. tab:: Synchronous + :tabid: open-upload-stream-with-options-sync + + .. literalinclude:: /includes/code-examples/GridFS.cs + :language: csharp + :dedent: + :start-after: // start-open-upload-stream-with-options + :end-before: // end-open-upload-stream-with-options .. _gridfs-upload-from-stream: Upload an Existing Stream ~~~~~~~~~~~~~~~~~~~~~~~~~ -Use the ``UploadFromStream()`` method to upload the contents of a stream to a new GridFS -file. This method accepts the following parameters: +Use the ``UploadFromStreamAsync()`` or ``UploadFromStream()`` method to upload the +contents of a stream to a new GridFS file. These methods accept the following parameters: .. list-table:: @@ -261,7 +297,7 @@ file. This method accepts the following parameters: - | *Optional.* An instance of the ``GridFSUploadOptions`` class that specifies the configuration for the upload stream. The default value is ``null``. | - | **Data type**: `GridFSUploadOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.OpenUploadStream.html>`__ + | **Data type**: `GridFSUploadOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.GridFSUploadOptions.html>`__ * - ``cancellationToken`` - | *Optional.* A token that you can use to cancel the operation. @@ -275,11 +311,28 @@ following steps: - Calls the ``UploadFromStream()`` method to write the contents of the stream to a GridFS file named ``"new_file"`` -.. literalinclude:: /includes/code-examples/GridFS.cs - :language: csharp - :dedent: - :start-after: // start-upload-from-stream - :end-before: // end-upload-from-stream +Select the :guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the corresponding +code. + +.. tabs:: + + .. tab:: Asynchronous + :tabid: upload-from-stream-async + + .. literalinclude:: /includes/code-examples/GridFS.cs + :language: csharp + :dedent: + :start-after: // start-upload-from-stream-async + :end-before: // end-upload-from-stream-async + + .. tab:: Synchronous + :tabid: upload-from-stream-sync + + .. literalinclude:: /includes/code-examples/GridFS.cs + :language: csharp + :dedent: + :start-after: // start-upload-from-stream + :end-before: // end-upload-from-stream .. _gridfs-download-files: @@ -288,8 +341,10 @@ Download Files You can download files from a GridFS bucket by using the following methods: -- ``OpenDownloadStream()``: Opens a new download stream from which you can read file contents -- ``DownloadToStream()``: Writes the contents of a GridFS file to an existing stream +- ``OpenDownloadStreamAsync()`` or ``OpenDownloadStream()``: Opens a new download stream + from which you can read file contents +- ``DownloadToStreamAsync()`` or ``DownloadToStream()``: Writes the contents of a GridFS + file to an existing stream The following sections describe these methods in more detail. @@ -298,8 +353,8 @@ The following sections describe these methods in more detail. Read From a Download Stream ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Use the ``OpenDownloadStream()`` method to create a download stream. -This method accepts the following parameters: +Use the ``OpenDownloadStreamAsync()`` or ``OpenDownloadStream()`` method to create a +download stream. These methods accept the following parameters: .. list-table:: @@ -329,11 +384,28 @@ following steps: - Calls the ``Read()`` method to read the file contents from the ``downloader`` stream into the vector -.. literalinclude:: /includes/code-examples/GridFS.cs - :language: csharp - :dedent: - :start-after: // start-open-download-stream - :end-before: // end-open-download-stream +Select the :guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the corresponding +code. + +.. tabs:: + + .. tab:: Asynchronous + :tabid: open-download-stream-async + + .. literalinclude:: /includes/code-examples/GridFS.cs + :language: csharp + :dedent: + :start-after: // start-open-download-stream-async + :end-before: // end-open-download-stream-async + + .. tab:: Synchronous + :tabid: open-download-stream-sync + + .. literalinclude:: /includes/code-examples/GridFS.cs + :language: csharp + :dedent: + :start-after: // start-open-download-stream + :end-before: // end-open-download-stream To customize the download stream configuration, pass an instance of the ``GridFSDownloadOptions`` class to the ``OpenDownloadStream()`` method. The @@ -350,21 +422,38 @@ To customize the download stream configuration, pass an instance of the | **Data type**: ``bool?`` The following example performs the same steps as the preceding example, but also sets -the ``Seekable`` option to ``true`` to specify that the stream is seekable: +the ``Seekable`` option to ``true`` to specify that the stream is seekable. -.. literalinclude:: /includes/code-examples/GridFS.cs - :language: csharp - :dedent: - :start-after: // start-open-download-stream-with-options - :end-before: // end-open-download-stream-with-options +Select the :guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the corresponding +code. + +.. tabs:: + + .. tab:: Asynchronous + :tabid: open-download-stream-with-options-async + .. literalinclude:: /includes/code-examples/GridFS.cs + :language: csharp + :dedent: + :start-after: // start-open-download-stream-with-options-async + :end-before: // end-open-download-stream-with-options-async + + .. tab:: Synchronous + :tabid: open-download-stream-with-options-sync + + .. literalinclude:: /includes/code-examples/GridFS.cs + :language: csharp + :dedent: + :start-after: // start-open-download-stream-with-options + :end-before: // end-open-download-stream-with-options + .. _gridfs-download_to_stream: Download to an Existing Stream ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Use the ``DownloadToStream()`` method to download the contents of a GridFS file to an -existing stream. This method accepts the following parameters: +existing stream. These methods accept the following parameters: .. list-table:: @@ -394,24 +483,40 @@ performing the following actions: - Opens a file located at ``/path/to/output_file`` as a stream in binary write mode - - Retrieves the ``_id`` value of the GridFS file named ``"new_file"`` - Calls the ``DownloadToStream()`` method and passes the ``_id`` value to download the contents of ``"new_file"`` to a stream -.. literalinclude:: /includes/code-examples/GridFS.cs - :language: csharp - :dedent: - :start-after: // start-download-to-stream - :end-before: // end-download-to-stream +Select the :guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the corresponding +code. + +.. tabs:: + + .. tab:: Asynchronous + :tabid: download-to-stream-async + + .. literalinclude:: /includes/code-examples/GridFS.cs + :language: csharp + :dedent: + :start-after: // start-download-to-stream-async + :end-before: // end-download-to-stream-async + + .. tab:: Synchronous + :tabid: download-to-stream-sync + + .. literalinclude:: /includes/code-examples/GridFS.cs + :language: csharp + :dedent: + :start-after: // start-download-to-stream + :end-before: // end-download-to-stream .. _gridfs-retrieve-file-info: Retrieve File Information ------------------------- -To retrieve files from a GridFS bucket, call the ``Find()`` method on your ``GridFSBucket`` -instance. This method accepts the following parameters: +To retrieve files from a GridFS bucket, call the ``FindAsync()`` or ``Find()`` method +on your ``GridFSBucket`` instance. These methods accept the following parameters: .. list-table:: @@ -420,7 +525,7 @@ instance. This method accepts the following parameters: * - ``filter`` - | A query filter that specifies the entries to match in the ``files`` collection. - | **Data type**: `FilterDefinition <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.FilterDefinition-1.html>`__<`GridFSFileInfo <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSFileInfo.html>`__> + | **Data type**: `FilterDefinition <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.FilterDefinition-1.html>`__ <`GridFSFileInfo <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSFileInfo.html>`__> * - ``source`` - | The stream from which to read the file contents. @@ -445,26 +550,54 @@ which you can access the results.It uses a ``foreach`` loop to iterate through the returned cursor and display the contents of the files uploaded in the :ref:`gridfs-upload-files` examples. -.. io-code-block:: - :copyable: +Select the :guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the corresponding +code. - .. input:: /includes/code-examples/GridFS.cs - :start-after: start-find - :end-before: end-find - :language: csharp - :dedent: +.. tabs:: - .. output:: - :visible: false + .. tab:: Asynchronous + :tabid: find-async - { "_id" : { "$oid" : "..." }, "length" : 13, "chunkSize" : 261120, "uploadDate" : - { "$date" : ... }, "filename" : "new_file" } - { "_id" : { "$oid" : "..." }, "length" : 50, "chunkSize" : 1048576, "uploadDate" : - { "$date" : ... }, "filename" : "my_file" } + .. io-code-block:: + :copyable: + + .. input:: /includes/code-examples/GridFS.cs + :start-after: // start-find-async + :end-before: // end-find-async + :language: csharp + :dedent: + + .. output:: + :visible: false + + { "_id" : { "$oid" : "..." }, "length" : 13, "chunkSize" : 261120, "uploadDate" : + { "$date" : ... }, "filename" : "new_file" } + { "_id" : { "$oid" : "..." }, "length" : 50, "chunkSize" : 1048576, "uploadDate" : + { "$date" : ... }, "filename" : "my_file" } + + .. tab:: Synchronous + :tabid: find-sync + + .. io-code-block:: + :copyable: + + .. input:: /includes/code-examples/GridFS.cs + :start-after: // start-find + :end-before: // end-find + :language: csharp + :dedent: + + .. output:: + :visible: false + + { "_id" : { "$oid" : "..." }, "length" : 13, "chunkSize" : 261120, "uploadDate" : + { "$date" : ... }, "filename" : "new_file" } + { "_id" : { "$oid" : "..." }, "length" : 50, "chunkSize" : 1048576, "uploadDate" : + { "$date" : ... }, "filename" : "my_file" } To customize the find operation, pass an instance of the -``GridFSFindOptions`` class to the ``Find()`` method. The ``GridFSFindOptions`` -class contains the following properties: +``GridFSFindOptions`` class to the ``FindAsync()`` or ``Find()`` method. The +``GridFSFindOptions`` class contains the following properties: .. list-table:: @@ -475,18 +608,18 @@ class contains the following properties: - | The sort order of the results. If you don't specify a sort order, the ``Find()`` method returns the results in the order in which they were inserted. | - | **Data type**: `SortDefinition <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSFindOptions.Sort.html#MongoDB_Driver_GridFS_GridFSFindOptions_Sort>`__<`GridFSFileInfo <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSFileInfo.html>`__> + | **Data type**: `SortDefinition <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSFindOptions.Sort.html#MongoDB_Driver_GridFS_GridFSFindOptions_Sort>`__ <`GridFSFileInfo <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSFileInfo.html>`__> .. _gridfs-delete-files: Delete Files ------------ -To delete files from a GridFS bucket, call the ``Delete()`` method on your ``GridFSBucket`` -instance. This method removes a file's collection document and its associated chunks from -your bucket. +To delete files from a GridFS bucket, call the ``DeleteAsync()`` or ``Delete()`` method +on your ``GridFSBucket`` instance. This method removes a file's collection document and +its associated chunks from your bucket. -The ``Delete()`` method accepts the following parameters: +The ``DeleteAsync`` and ``Delete()`` methods accept the following parameters: .. list-table:: @@ -508,27 +641,62 @@ passing its ``_id`` value to ``delete_file()``: - Uses the ``Find()`` method to find the file named ``"my_file"`` - Passes the ``_id`` value of the file to the ``Delete()`` method to delete the file -.. literalinclude:: /includes/code-examples/GridFS.cs - :language: csharp - :dedent: - :start-after: // start-delete-file - :end-before: // end-delete-file +Select the :guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the corresponding +code. + +.. tabs:: + + .. tab:: Asynchronous + :tabid: delete-file-async + + .. literalinclude:: /includes/code-examples/GridFS.cs + :language: csharp + :dedent: + :start-after: // start-delete-file-async + :end-before: // end-delete-file-async + + .. tab:: Synchronous + :tabid: download-to-stream-sync + + .. literalinclude:: /includes/code-examples/GridFS.cs + :language: csharp + :dedent: + :start-after: // start-delete-file + :end-before: // end-delete-file .. note:: File Revisions - The ``Delete()`` method supports deleting only one file at a time. If - you want to delete each file revision, or files with different upload + The ``DeleteAsync()`` and ``Delete()`` methods support deleting only one file at a time. + If you want to delete each file revision, or files with different upload times that share the same file name, collect the ``_id`` values of each revision. - Then, pass each ``_id`` value in separate calls to the ``Delete()`` method. + Then, pass each ``_id`` value in separate calls to the ``DeleteAsync()`` or ``Delete()`` + method. API Documentation ----------------- -To learn more about using the {+driver-short+} to store and retrieve large files, -see the following API documentation: +To learn more about the classes used on this page, see the following API documentation: - `GridFSBucket <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.html>`__ - `GridFSBucketOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucketOptions.html>`__ - `GridFSDownloadOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSDownloadOptions.html>`__ - `GridFSFindOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSFindOptions.html>`__ - `GridFSUploadOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSUploadOptions.html>`__ +- `GridFSFileInfo <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSFileInfo.html>`__ +- + +To learn more about the methods in the ``GridFSBucket`` class used on this page, see the +following API documentation: + +- `OpenUploadStreamAsync <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.OpenUploadStreamAsync.html>`__ +- `OpenUploadStream <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.OpenUploadStream.html>`__ +- `UploadFromStreamAsync <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.UploadFromStreamAsync.html>`__ +- `UploadFromStream <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.UploadFromStream.html>`__ +- `OpenDownloadStreamAsync <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.OpenDownloadStreamAsync.html>`__ +- `OpenDownloadStream <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.OpenDownloadStream.html>`__ +- `DownloadToStreamAsync <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.DownloadToStreamAsync.html>`__ +- `DownloadToStream <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.DownloadToStream.html>`__ +- `FindAsync <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.FindAsync.html>`__ +- `Find <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.Find.html>`__ +- `DeleteAsync <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.DeleteAsync.html>`__ +- `Delete <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.Delete.html>`__ \ No newline at end of file diff --git a/source/includes/code-examples/GridFS.cs b/source/includes/code-examples/GridFS.cs index 56a6975f..c2de975b 100644 --- a/source/includes/code-examples/GridFS.cs +++ b/source/includes/code-examples/GridFS.cs @@ -31,6 +31,32 @@ static void CreateCustomBucket() // end-create-custom-bucket } + static async Task UploadFileAsync() + { + // Initialize MongoDB client + var client = new MongoClient(""); + var database = client.GetDatabase("db"); + + // Creates a GridFS bucket or references an existing one + var bucket = new GridFSBucket(database); + + // Uploads a file called "my_file" to the GridFS bucket and writes data to it + // start-open-upload-stream-async + using (var uploader = await bucket.OpenUploadStreamAsync("my_file", options)) + { + // ASCII for "HelloWorld" + byte[] bytes = { 72, 101, 108, 108, 111, 87, 111, 114, 108, 100 }; + + for (int i = 0; i < 5; i++) + { + await uploader.WriteAsync(bytes, 0, bytes.Length); + } + + await uploader.CloseAsync(); + } + // end-open-upload-stream-async + } + static void UploadFile() { // Initialize MongoDB client @@ -256,7 +282,7 @@ static async Task DownloadFileWithOptionsAsync() var bucket = new GridFSBucket(database); // Downloads a file from the GridFS bucket by referencing its ObjectId value - // start-open-download-stream-async + // start-open-download-stream-with-options-async var filter = Builders.Filter.Eq("filename", "new_file"); var doc = await database.GetCollection("fs.files").Find(filter).FirstOrDefaultAsync(); var id = doc["_id"].AsObjectId; @@ -273,7 +299,7 @@ static async Task DownloadFileWithOptionsAsync() // Process the buffer as needed } - // end-open-download-stream-async + // end-open-download-stream-with-options-async } static void DownloadFileWithOptions() From c32922b1ed015ca4e69560f02f398ccc66ff52c6 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:19:28 -0600 Subject: [PATCH 22/35] fixes --- source/fundamentals/gridfs.txt | 46 ++++++++++++++----------- source/includes/code-examples/GridFS.cs | 2 +- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/source/fundamentals/gridfs.txt b/source/fundamentals/gridfs.txt index 2806f86e..45138bfc 100644 --- a/source/fundamentals/gridfs.txt +++ b/source/fundamentals/gridfs.txt @@ -234,14 +234,14 @@ method. The ``GridFSUploadOptions`` class contains the following properties: * - ``Metadata`` - | Metadata to store with the file, including the following elements: - + | | - The ``_id`` of the file - The name of the file - The length and size of the file - The upload date and time - A ``metadata`` document in which you can store other information - - | The default value is ``null``. + | + | The default value is ``null``. | | **Data type**: `BsonDocument <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonDocument.html>`__ @@ -452,8 +452,8 @@ code. Download to an Existing Stream ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Use the ``DownloadToStream()`` method to download the contents of a GridFS file to an -existing stream. These methods accept the following parameters: +Use the ``DownloadToStreamAsync()`` or ``DownloadToStream()`` method to download the +contents of a GridFS file to an existing stream. These methods accept the following parameters: .. list-table:: @@ -525,7 +525,10 @@ on your ``GridFSBucket`` instance. These methods accept the following parameters * - ``filter`` - | A query filter that specifies the entries to match in the ``files`` collection. - | **Data type**: `FilterDefinition <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.FilterDefinition-1.html>`__ <`GridFSFileInfo <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSFileInfo.html>`__> + | **Data type**: ``FilterDefinition``. For more information, see + the API documentation for the + `Find() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.Find.html>`__ + method. * - ``source`` - | The stream from which to read the file contents. @@ -605,10 +608,12 @@ To customize the find operation, pass an instance of the - Description * - ``Sort`` - - | The sort order of the results. If you don't specify a sort order, the ``Find()`` + - | The sort order of the results. If you don't specify a sort order, the method returns the results in the order in which they were inserted. | - | **Data type**: `SortDefinition <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSFindOptions.Sort.html#MongoDB_Driver_GridFS_GridFSFindOptions_Sort>`__ <`GridFSFileInfo <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSFileInfo.html>`__> + | **Data type**: ``SortDefinition``. For more information, see + the API documentation for the + `Sort <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSFindOptions.Sort.html>`__ property. .. _gridfs-delete-files: @@ -683,20 +688,19 @@ To learn more about the classes used on this page, see the following API documen - `GridFSFindOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSFindOptions.html>`__ - `GridFSUploadOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSUploadOptions.html>`__ - `GridFSFileInfo <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSFileInfo.html>`__ -- To learn more about the methods in the ``GridFSBucket`` class used on this page, see the following API documentation: -- `OpenUploadStreamAsync <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.OpenUploadStreamAsync.html>`__ -- `OpenUploadStream <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.OpenUploadStream.html>`__ -- `UploadFromStreamAsync <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.UploadFromStreamAsync.html>`__ -- `UploadFromStream <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.UploadFromStream.html>`__ -- `OpenDownloadStreamAsync <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.OpenDownloadStreamAsync.html>`__ -- `OpenDownloadStream <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.OpenDownloadStream.html>`__ -- `DownloadToStreamAsync <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.DownloadToStreamAsync.html>`__ -- `DownloadToStream <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.DownloadToStream.html>`__ -- `FindAsync <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.FindAsync.html>`__ -- `Find <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.Find.html>`__ -- `DeleteAsync <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.DeleteAsync.html>`__ -- `Delete <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.Delete.html>`__ \ No newline at end of file +- `OpenUploadStreamAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.OpenUploadStreamAsync.html>`__ +- `OpenUploadStream() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.OpenUploadStream.html>`__ +- `UploadFromStreamAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.UploadFromStreamAsync.html>`__ +- `UploadFromStream() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.UploadFromStream.html>`__ +- `OpenDownloadStreamAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.OpenDownloadStreamAsync.html>`__ +- `OpenDownloadStream() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.OpenDownloadStream.html>`__ +- `DownloadToStreamAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.DownloadToStreamAsync.html>`__ +- `DownloadToStream() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.DownloadToStream.html>`__ +- `FindAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.FindAsync.html>`__ +- `Find() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.Find.html>`__ +- `DeleteAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.DeleteAsync.html>`__ +- `Delete() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.Delete.html>`__ \ No newline at end of file diff --git a/source/includes/code-examples/GridFS.cs b/source/includes/code-examples/GridFS.cs index c2de975b..eaa6ed10 100644 --- a/source/includes/code-examples/GridFS.cs +++ b/source/includes/code-examples/GridFS.cs @@ -371,8 +371,8 @@ static void DownloadStream() var id = doc["_id"].AsObjectId; bucket.DownloadToStream(id, outputFile); - // end-download-to-stream } + // end-download-to-stream } static async Task DeleteFileAsync() From c2f55af6a56ba0e44f48d871cf2d00861a2fa348 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:40:12 -0600 Subject: [PATCH 23/35] fix list --- source/fundamentals/gridfs.txt | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/source/fundamentals/gridfs.txt b/source/fundamentals/gridfs.txt index 45138bfc..7c9ae65e 100644 --- a/source/fundamentals/gridfs.txt +++ b/source/fundamentals/gridfs.txt @@ -233,14 +233,14 @@ method. The ``GridFSUploadOptions`` class contains the following properties: | **Data type**: ``int?`` * - ``Metadata`` - - | Metadata to store with the file, including the following elements: - | - | - The ``_id`` of the file - - The name of the file - - The length and size of the file - - The upload date and time - - A ``metadata`` document in which you can store other information - | + - Metadata to store with the file, including the following elements: + + - The ``_id`` of the file + - The name of the file + - The length and size of the file + - The upload date and time + - A ``metadata`` document in which you can store other information + | The default value is ``null``. | | **Data type**: `BsonDocument <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonDocument.html>`__ @@ -525,6 +525,7 @@ on your ``GridFSBucket`` instance. These methods accept the following parameters * - ``filter`` - | A query filter that specifies the entries to match in the ``files`` collection. + | | **Data type**: ``FilterDefinition``. For more information, see the API documentation for the `Find() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.Find.html>`__ From 24595051d4633d8f6a3d6a0206b304a5a3e1e1b0 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:49:57 -0600 Subject: [PATCH 24/35] test --- source/fundamentals/gridfs.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/source/fundamentals/gridfs.txt b/source/fundamentals/gridfs.txt index 7c9ae65e..0ca65408 100644 --- a/source/fundamentals/gridfs.txt +++ b/source/fundamentals/gridfs.txt @@ -234,7 +234,6 @@ method. The ``GridFSUploadOptions`` class contains the following properties: * - ``Metadata`` - Metadata to store with the file, including the following elements: - - The ``_id`` of the file - The name of the file - The length and size of the file From 18f4e59f3b6702aed4c7e533740f02914ae7edaf Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Wed, 13 Nov 2024 08:48:14 -0600 Subject: [PATCH 25/35] test --- source/fundamentals/gridfs.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/fundamentals/gridfs.txt b/source/fundamentals/gridfs.txt index 0ca65408..7546b90d 100644 --- a/source/fundamentals/gridfs.txt +++ b/source/fundamentals/gridfs.txt @@ -234,12 +234,13 @@ method. The ``GridFSUploadOptions`` class contains the following properties: * - ``Metadata`` - Metadata to store with the file, including the following elements: + - The ``_id`` of the file - The name of the file - The length and size of the file - The upload date and time - A ``metadata`` document in which you can store other information - + | The default value is ``null``. | | **Data type**: `BsonDocument <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonDocument.html>`__ From b20dd5e962b16670f6f88404368480b111bc1321 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Wed, 13 Nov 2024 09:01:10 -0600 Subject: [PATCH 26/35] size limit note --- source/fundamentals/crud/write-operations/insert.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/fundamentals/crud/write-operations/insert.txt b/source/fundamentals/crud/write-operations/insert.txt index b49e3a13..ea080a82 100644 --- a/source/fundamentals/crud/write-operations/insert.txt +++ b/source/fundamentals/crud/write-operations/insert.txt @@ -23,6 +23,11 @@ Overview In this guide, you can learn how to use the {+driver-long+} to add documents to a MongoDB collection by performing insert operations. +.. note:: 16 MB Size Limit + + MongoDB limits BSON documents to 16 MB. If your document is larger than 16 MB, + use the :ref:`GridFS ` API instead. + An insert operation inserts one or more documents into a MongoDB collection. The {+driver-short+} provides the following methods to perform insert operations, each of which has an asynchronous and synchronous version: From 4132ad258977ac14e66a9838a62173b5cf31518b Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Wed, 13 Nov 2024 09:03:58 -0600 Subject: [PATCH 27/35] style --- source/fundamentals/gridfs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/fundamentals/gridfs.txt b/source/fundamentals/gridfs.txt index 7546b90d..d589b1ae 100644 --- a/source/fundamentals/gridfs.txt +++ b/source/fundamentals/gridfs.txt @@ -28,7 +28,7 @@ GridFS is an abstraction that manages the operations and organization of the file storage. Use GridFS if the size of your files exceeds the BSON document -size limit of 16MB. For more detailed information about whether GridFS is +size limit of 16 MB. For more detailed information about whether GridFS is suitable for your use case, see :manual:`GridFS ` in the {+mdb-server+} manual. From ea274602d5650c1f9b09e08c7e387c6a35c51047 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Thu, 14 Nov 2024 13:26:20 -0600 Subject: [PATCH 28/35] Apply suggestions from code review Co-authored-by: Rea Rustagi <85902999+rustagir@users.noreply.github.com> --- .../crud/write-operations/insert.txt | 2 +- source/fundamentals/gridfs.txt | 20 +++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/source/fundamentals/crud/write-operations/insert.txt b/source/fundamentals/crud/write-operations/insert.txt index ea080a82..be425c41 100644 --- a/source/fundamentals/crud/write-operations/insert.txt +++ b/source/fundamentals/crud/write-operations/insert.txt @@ -25,7 +25,7 @@ documents to a MongoDB collection by performing insert operations. .. note:: 16 MB Size Limit - MongoDB limits BSON documents to 16 MB. If your document is larger than 16 MB, + MongoDB limits individual BSON documents to 16 MB. If your document is larger than 16 MB, use the :ref:`GridFS ` API instead. An insert operation inserts one or more documents into a MongoDB collection. diff --git a/source/fundamentals/gridfs.txt b/source/fundamentals/gridfs.txt index d589b1ae..1610e964 100644 --- a/source/fundamentals/gridfs.txt +++ b/source/fundamentals/gridfs.txt @@ -27,7 +27,7 @@ and reassemble those files when retrieving them. The driver's implementation of GridFS is an abstraction that manages the operations and organization of the file storage. -Use GridFS if the size of your files exceeds the BSON document +Use GridFS if the size of any of your files exceeds the BSON document size limit of 16 MB. For more detailed information about whether GridFS is suitable for your use case, see :manual:`GridFS ` in the {+mdb-server+} manual. @@ -43,8 +43,8 @@ defined in the GridFS specification: - ``chunks``: Stores the binary file chunks - ``files``: Stores the file metadata -The driver creates the GridFS bucket, if it doesn't exist, when you first -write data to it. The bucket contains the preceding collections +The driver creates the GridFS bucket, if it doesn't already exist, when you first +write data to it. The bucket contains the ``chunks`` and ``files`` collections prefixed with the default bucket name ``fs``, unless you specify a different name. To ensure efficient retrieval of the files and related metadata, the driver creates an index on each collection. The driver ensures that these indexes exist @@ -97,7 +97,7 @@ Customize the Bucket ~~~~~~~~~~~~~~~~~~~~ You can customize the GridFS bucket configuration by passing an instance -of the ``GridFSBucketOptions class`` class to +of the ``GridFSBucketOptions`` class to the ``GridFSBucket()`` constructor. The following table describes the properties in the ``GridFSBucketOptions`` class: @@ -154,7 +154,7 @@ You can upload files to a GridFS bucket by using the following methods: - ``UploadFromStreamAsync()`` or ``UploadFromStream()``: Uploads the contents of an existing stream to a GridFS file -The following sections describe these methods in more detail. +The following sections describe how to use these methods. .. _gridfs-open-upload-stream: @@ -182,10 +182,10 @@ stream for a given file name. These methods accept the following parameters: | | **Data type**: `CancellationToken `__ -The following code example demonstrates how to open an upload stream by performing the +This code example demonstrates how to open an upload stream by performing the following steps: -- Calls the ``OpenUploadStream()`` method to open a writable GridFS stream for a new file +- Calls the ``OpenUploadStream()`` method to open a writable GridFS stream for a file named ``"my_file"`` - Calls the ``Write()`` method to write data to ``my_file`` - Calls the ``Close()`` method to close the stream that points to ``my_file`` @@ -223,7 +223,7 @@ method. The ``GridFSUploadOptions`` class contains the following properties: - Description * - ``BatchSize`` - | The number of chunks to upload in each batch. The default value is ``16777216`` - divided by the value of the following property, ``ChunkSizeBytes``. + divided by the value of the ``ChunkSizeBytes`` property. | | **Data type**: ``int?`` @@ -304,7 +304,7 @@ contents of a stream to a new GridFS file. These methods accept the following pa | | **Data type**: `CancellationToken `__ -The following code example demonstrates how to open an upload stream by performing the +This code example demonstrates how to open an upload stream by performing the following steps: - Opens a file located at ``/path/to/input_file`` as a stream in binary read mode @@ -550,7 +550,7 @@ on your ``GridFSBucket`` instance. These methods accept the following parameters The following code example shows how to retrieve and print file metadata from files in a GridFS bucket. The ``Find()`` method returns an ``IAsyncCursor`` instance from -which you can access the results.It uses a ``foreach`` loop to iterate through +which you can access the results. It uses a ``foreach`` loop to iterate through the returned cursor and display the contents of the files uploaded in the :ref:`gridfs-upload-files` examples. From 2cf2ba5f8cdded0ccb813a51056911273286c348 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Thu, 14 Nov 2024 13:26:40 -0600 Subject: [PATCH 29/35] feedback --- source/fundamentals/gridfs.txt | 265 +++++++++++++++++---------------- 1 file changed, 135 insertions(+), 130 deletions(-) diff --git a/source/fundamentals/gridfs.txt b/source/fundamentals/gridfs.txt index d589b1ae..db9a0c61 100644 --- a/source/fundamentals/gridfs.txt +++ b/source/fundamentals/gridfs.txt @@ -21,11 +21,10 @@ Overview -------- In this guide, you can learn how to store and retrieve large files in -MongoDB by using **GridFS**. GridFS is a specification implemented by -the {+driver-short+} that describes how to split files into chunks when storing them -and reassemble those files when retrieving them. The driver's implementation of -GridFS is an abstraction that manages the operations and organization of -the file storage. +MongoDB by using **GridFS**. The GridFS storage system +splits files into chunks when storing them and reassembles those files when retrieving them. +The driver's implementation of GridFS is an abstraction that manages the operations and +organization of the file storage. Use GridFS if the size of your files exceeds the BSON document size limit of 16 MB. For more detailed information about whether GridFS is @@ -37,13 +36,12 @@ How GridFS Works GridFS organizes files in a **bucket**, a group of MongoDB collections that contain the chunks of files and information describing them. The -bucket contains the following collections, named using the convention -defined in the GridFS specification: +bucket contains the following collections: - ``chunks``: Stores the binary file chunks - ``files``: Stores the file metadata -The driver creates the GridFS bucket, if it doesn't exist, when you first +The driver creates the GridFS bucket, if it doesn't already exist, when you first write data to it. The bucket contains the preceding collections prefixed with the default bucket name ``fs``, unless you specify a different name. To ensure efficient retrieval of the files and related metadata, the driver @@ -56,9 +54,7 @@ For more information about GridFS indexes, see :manual:`GridFS Indexes When using GridFS to store files, the driver splits the files into smaller chunks, each represented by a separate document in the ``chunks`` collection. It also creates a document in the ``files`` collection that contains -a file ID, file name, and other file metadata. You can upload the file by passing -a stream to the {+driver-short+} to consume or by creating a new stream and writing to it -directly. +a file ID, file name, and other file metadata. The following diagram shows how GridFS splits files when they are uploaded to a bucket: @@ -68,11 +64,9 @@ uploaded to a bucket: When retrieving files, GridFS fetches the metadata from the ``files`` collection in the specified bucket and uses the information to reconstruct -the file from documents in the ``chunks`` collection. You can read the file -by writing its contents to an existing stream or by creating a new stream that points -to the file. +the file from documents in the ``chunks`` collection. -.. _gridfs-create-bucket: +.. _csharp-gridfs-create-bucket: Create a GridFS Bucket ---------------------- @@ -91,7 +85,7 @@ The following example creates a new instance of the ``GridFSBucket`` class for t :start-after: // start-create-bucket :end-before: // end-create-bucket -.. _gridfs-create-custom-bucket: +.. _csharp-gridfs-create-custom-bucket: Customize the Bucket ~~~~~~~~~~~~~~~~~~~~ @@ -109,28 +103,33 @@ the ``GridFSBucket()`` constructor. The following table describes the properties - Description * - ``BucketName`` - - | The bucket name to use as a prefix for the files and chunks collections. - The default value is ``"fs"``. - | **Data type**: {+string-data-type+} + - The bucket name to use as a prefix for the files and chunks collections. + The default value is ``"fs"``. + + **Data type**: {+string-data-type+} * - ``ChunkSizeBytes`` - - | The chunk size that GridFS splits files into. The default value is ``261120``. - | **Data type**: {+int-data-type+} + - The chunk size that GridFS splits files into. The default value is ``261120``. + + **Data type**: {+int-data-type+} * - ``ReadConcern`` - - | The read concern to use for bucket operations. The default value is the - database's read concern. - | **Data type**: `ReadConcern <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ReadConcern.html>`__ + - The read concern to use for bucket operations. The default value is the + database's read concern. + + **Data type**: `ReadConcern <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ReadConcern.html>`__ * - ``ReadPreference`` - - | The read preference to use for bucket operations. The default value is the - database's read preference. - | **Data type**: `ReadPreference <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ReadPreference.html>`__ + - The read preference to use for bucket operations. The default value is the + database's read preference. + + **Data type**: `ReadPreference <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ReadPreference.html>`__ * - ``WriteConcern`` - - | The write concern to use for bucket operations. The default value is the - database's write concern. - | **Data type**: `WriteConcern <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.WriteConcern.html>`__ + - The write concern to use for bucket operations. The default value is the + database's write concern. + + **Data type**: `WriteConcern <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.WriteConcern.html>`__ The following example creates a bucket named ``"myCustomBucket"`` by passing an instance of the ``GridFSBucketOptions`` class to the ``GridFSBucket()`` constructor: @@ -142,7 +141,7 @@ of the ``GridFSBucketOptions`` class to the ``GridFSBucket()`` constructor: :start-after: // start-create-custom-bucket :end-before: // end-create-custom-bucket -.. _gridfs-upload-files: +.. _csharp-gridfs-upload-files: Upload Files ------------ @@ -156,7 +155,7 @@ You can upload files to a GridFS bucket by using the following methods: The following sections describe these methods in more detail. -.. _gridfs-open-upload-stream: +.. _csharp-gridfs-open-upload-stream: Write to an Upload Stream ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -165,22 +164,24 @@ Use the ``OpenUploadStreamAsync()`` or ``OpenUploadStream()`` method to create a stream for a given file name. These methods accept the following parameters: .. list-table:: + :widths: 30 70 + :header-rows: 1 * - Parameter - Description * - ``filename`` - - | The name of the file to upload. - | - | **Data type**: {+string-data-type+} + - The name of the file to upload. + + **Data type**: {+string-data-type+} * - ``options`` - - | *Optional.* An instance of the ``GridFSUploadOptions`` class that specifies the + - *Optional.* An instance of the ``GridFSUploadOptions`` class that specifies the configuration for the upload stream. The default value is ``null``. - | - | **Data type**: `GridFSUploadOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.GridFSUploadOptions.html>`__ + + **Data type**: `GridFSUploadOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSUploadOptions.html>`__ * - ``cancellationToken`` - - | *Optional.* A token that you can use to cancel the operation. - | - | **Data type**: `CancellationToken `__ + - *Optional.* A token that you can use to cancel the operation. + + **Data type**: `CancellationToken `__ The following code example demonstrates how to open an upload stream by performing the following steps: @@ -218,19 +219,21 @@ To customize the upload stream configuration, pass an instance of the method. The ``GridFSUploadOptions`` class contains the following properties: .. list-table:: + :widths: 30 70 + :header-rows: 1 * - Property - Description * - ``BatchSize`` - - | The number of chunks to upload in each batch. The default value is ``16777216`` - divided by the value of the following property, ``ChunkSizeBytes``. - | - | **Data type**: ``int?`` + - The number of chunks to upload in each batch. The default value is ``16777216`` + divided by the value of the following property, ``ChunkSizeBytes``. + + **Data type**: ``int?`` * - ``ChunkSizeBytes`` - - | The maximum size of each chunk. - | - | **Data type**: ``int?`` + - The maximum size of each chunk. + + **Data type**: ``int?`` * - ``Metadata`` - Metadata to store with the file, including the following elements: @@ -241,9 +244,9 @@ method. The ``GridFSUploadOptions`` class contains the following properties: - The upload date and time - A ``metadata`` document in which you can store other information - | The default value is ``null``. - | - | **Data type**: `BsonDocument <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonDocument.html>`__ + The default value is ``null``. + + **Data type**: `BsonDocument <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonDocument.html>`__ The following example performs the same steps as the preceding example, but also uses the ``ChunkSizeBytes`` option to specify the maximum size of each chunk. Select the @@ -270,7 +273,7 @@ code. :start-after: // start-open-upload-stream-with-options :end-before: // end-open-upload-stream-with-options -.. _gridfs-upload-from-stream: +.. _csharp-gridfs-upload-from-stream: Upload an Existing Stream ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -284,25 +287,25 @@ contents of a stream to a new GridFS file. These methods accept the following pa - Description * - ``filename`` - - | The name of the file to upload. - | - | **Data type**: {+string-data-type+} + - The name of the file to upload. + + **Data type**: {+string-data-type+} * - ``source`` - - | The stream from which to read the file contents. - | - | **Data type**: `Stream `__ + - The stream from which to read the file contents. + + **Data type**: `Stream `__ * - ``options`` - - | *Optional.* An instance of the ``GridFSUploadOptions`` class that specifies the - configuration for the upload stream. The default value is ``null``. - | - | **Data type**: `GridFSUploadOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.GridFSUploadOptions.html>`__ + - *Optional.* An instance of the ``GridFSUploadOptions`` class that specifies the + configuration for the upload stream. The default value is ``null``. + + **Data type**: `GridFSUploadOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.GridFSUploadOptions.html>`__ * - ``cancellationToken`` - - | *Optional.* A token that you can use to cancel the operation. - | - | **Data type**: `CancellationToken `__ + - *Optional.* A token that you can use to cancel the operation. + + **Data type**: `CancellationToken `__ The following code example demonstrates how to open an upload stream by performing the following steps: @@ -334,7 +337,7 @@ code. :start-after: // start-upload-from-stream :end-before: // end-upload-from-stream -.. _gridfs-download-files: +.. _csharp-gridfs-download-files: Download Files -------------- @@ -348,7 +351,7 @@ You can download files from a GridFS bucket by using the following methods: The following sections describe these methods in more detail. -.. _gridfs-open-download-stream: +.. _csharp-gridfs-open-download-stream: Read From a Download Stream ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -361,18 +364,18 @@ download stream. These methods accept the following parameters: * - Parameter - Description * - ``id`` - - | The ``_id`` value of the file to download. - | - | **Data type**: `BsonValue <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonValue.html>`__ + - The ``_id`` value of the file to download. + + **Data type**: `BsonValue <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonValue.html>`__ * - ``options`` - - | *Optional.* An instance of the ``GridFSDownloadOptions`` class that specifies the - configuration for the download stream. The default value is ``null``. - | - | **Data type**: `GridFSDownloadOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSDownloadOptions.html>`__ + - *Optional.* An instance of the ``GridFSDownloadOptions`` class that specifies the + configuration for the download stream. The default value is ``null``. + + **Data type**: `GridFSDownloadOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSDownloadOptions.html>`__ * - ``cancellationToken`` - - | *Optional.* A token that you can use to cancel the operation. - | - | **Data type**: `CancellationToken `__ + - *Optional.* A token that you can use to cancel the operation. + + **Data type**: `CancellationToken `__ The following code example demonstrates how to open a download stream by performing the following steps: @@ -416,10 +419,10 @@ To customize the download stream configuration, pass an instance of the * - Property - Description * - ``Seekable`` - - | Indicates whether the stream supports *seeking*, the ability to query and - change the current position in a stream. The default value is ``false``. - | - | **Data type**: ``bool?`` + - Indicates whether the stream supports *seeking*, the ability to query and + change the current position in a stream. The default value is ``false``. + + **Data type**: ``bool?`` The following example performs the same steps as the preceding example, but also sets the ``Seekable`` option to ``true`` to specify that the stream is seekable. @@ -447,7 +450,7 @@ code. :start-after: // start-open-download-stream-with-options :end-before: // end-open-download-stream-with-options -.. _gridfs-download_to_stream: +.. _csharp-gridfs-download_to_stream: Download to an Existing Stream ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -460,23 +463,23 @@ contents of a GridFS file to an existing stream. These methods accept the follow * - Parameter - Description * - ``id`` - - | The ``_id`` value of the file to download. - | - | **Data type**: `BsonValue <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonValue.html>`__ + - The ``_id`` value of the file to download. + + **Data type**: `BsonValue <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonValue.html>`__ * - ``destination`` - - | The stream that the {+driver-short+} downloads the GridFS file to. This property's - | value must be an object that implements the ``Stream`` class. - | - | **Data type**: `Stream `__ + - The stream that the {+driver-short+} downloads the GridFS file to. This property's + value must be an object that implements the ``Stream`` class. + + **Data type**: `Stream `__ * - ``options`` - - | *Optional.* An instance of the ``GridFSDownloadOptions`` class that specifies the - configuration for the download stream. The default value is ``null``. - | - | **Data type**: `GridFSDownloadOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSDownloadOptions.html>`__ + - *Optional.* An instance of the ``GridFSDownloadOptions`` class that specifies the + configuration for the download stream. The default value is ``null``. + + **Data type**: `GridFSDownloadOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSDownloadOptions.html>`__ * - ``cancellationToken`` - - | *Optional.* A token that you can use to cancel the operation. - | - | **Data type**: `CancellationToken `__ + - *Optional.* A token that you can use to cancel the operation. + + **Data type**: `CancellationToken `__ The following code example demonstrates how to download to an existing stream by performing the following actions: @@ -510,10 +513,10 @@ code. :start-after: // start-download-to-stream :end-before: // end-download-to-stream -.. _gridfs-retrieve-file-info: +.. _csharp-gridfs-retrieve-file-info: -Retrieve File Information -------------------------- +Retrieve Files +-------------- To retrieve files from a GridFS bucket, call the ``FindAsync()`` or ``Find()`` method on your ``GridFSBucket`` instance. These methods accept the following parameters: @@ -524,35 +527,35 @@ on your ``GridFSBucket`` instance. These methods accept the following parameters - Description * - ``filter`` - - | A query filter that specifies the entries to match in the ``files`` collection. - | - | **Data type**: ``FilterDefinition``. For more information, see - the API documentation for the - `Find() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.Find.html>`__ - method. + - A query filter that specifies the entries to match in the ``files`` collection. + + **Data type**: ``FilterDefinition``. For more information, see + the API documentation for the + `Find() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.Find.html>`__ + method. * - ``source`` - - | The stream from which to read the file contents. - | - | **Data type**: `Stream `__ + - The stream from which to read the file contents. + + **Data type**: `Stream `__ * - ``options`` - - | *Optional.* An instance of the ``GridFSFindOptions`` class that specifies the - configuration for the find operation. The default value is ``null``. - | - | **Data type**: `GridFSFindOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSFindOptions.html>`__ + - *Optional.* An instance of the ``GridFSFindOptions`` class that specifies the + configuration for the find operation. The default value is ``null``. + + **Data type**: `GridFSFindOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSFindOptions.html>`__ * - ``cancellationToken`` - - | *Optional.* A token that you can use to cancel the operation. - | - | **Data type**: `CancellationToken `__ + - *Optional.* A token that you can use to cancel the operation. + + **Data type**: `CancellationToken `__ The following code example shows how to retrieve and print file metadata from files in a GridFS bucket. The ``Find()`` method returns an ``IAsyncCursor`` instance from which you can access the results.It uses a ``foreach`` loop to iterate through the returned cursor and display the contents of the files uploaded in the -:ref:`gridfs-upload-files` examples. +:ref:`csharp-gridfs-upload-files` examples. Select the :guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the corresponding code. @@ -604,25 +607,27 @@ To customize the find operation, pass an instance of the ``GridFSFindOptions`` class contains the following properties: .. list-table:: + :widths: 30 70 + :header-rows: 1 * - Property - Description * - ``Sort`` - - | The sort order of the results. If you don't specify a sort order, the - method returns the results in the order in which they were inserted. - | - | **Data type**: ``SortDefinition``. For more information, see - the API documentation for the - `Sort <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSFindOptions.Sort.html>`__ property. + - The sort order of the results. If you don't specify a sort order, the + method returns the results in the order in which they were inserted. + + **Data type**: ``SortDefinition``. For more information, see + the API documentation for the + `Sort <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSFindOptions.Sort.html>`__ property. -.. _gridfs-delete-files: +.. _csharp-gridfs-delete-files: Delete Files ------------ To delete files from a GridFS bucket, call the ``DeleteAsync()`` or ``Delete()`` method -on your ``GridFSBucket`` instance. This method removes a file's collection document and +on your ``GridFSBucket`` instance. This method removes a file's metadata collection and its associated chunks from your bucket. The ``DeleteAsync`` and ``Delete()`` methods accept the following parameters: @@ -632,13 +637,13 @@ The ``DeleteAsync`` and ``Delete()`` methods accept the following parameters: * - Parameter - Description * - ``id`` - - | The ``_id`` of the file to delete. - | - | **Data type**: `BsonValue <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonValue.html>`__ + - The ``_id`` of the file to delete. + + **Data type**: `BsonValue <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonValue.html>`__ * - ``cancellationToken`` - - | *Optional.* A token that you can use to cancel the operation. - | - | **Data type**: `CancellationToken `__ + - *Optional.* A token that you can use to cancel the operation. + + **Data type**: `CancellationToken `__ The following code example shows how to delete a file named ``"my_file"`` passing its ``_id`` value to ``delete_file()``: From 53581c4789126ff7c830916d86af95d29253ec3f Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Thu, 14 Nov 2024 13:31:03 -0600 Subject: [PATCH 30/35] remove newlines --- source/fundamentals/gridfs.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/fundamentals/gridfs.txt b/source/fundamentals/gridfs.txt index c7ffa1b3..87530cc9 100644 --- a/source/fundamentals/gridfs.txt +++ b/source/fundamentals/gridfs.txt @@ -225,10 +225,10 @@ method. The ``GridFSUploadOptions`` class contains the following properties: * - Property - Description * - ``BatchSize`` - - | The number of chunks to upload in each batch. The default value is ``16777216`` - divided by the value of the ``ChunkSizeBytes`` property. - | - | **Data type**: ``int?`` + - The number of chunks to upload in each batch. The default value is ``16777216`` + divided by the value of the ``ChunkSizeBytes`` property. + + **Data type**: ``int?`` * - ``ChunkSizeBytes`` - The maximum size of each chunk. From 06a4ef978d5811ec42503bd6e7f4e32ee5983efa Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Thu, 14 Nov 2024 13:47:08 -0600 Subject: [PATCH 31/35] fixes --- source/fundamentals/gridfs.txt | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/source/fundamentals/gridfs.txt b/source/fundamentals/gridfs.txt index 87530cc9..ffa70a53 100644 --- a/source/fundamentals/gridfs.txt +++ b/source/fundamentals/gridfs.txt @@ -175,7 +175,7 @@ stream for a given file name. These methods accept the following parameters: **Data type**: {+string-data-type+} * - ``options`` - *Optional.* An instance of the ``GridFSUploadOptions`` class that specifies the - configuration for the upload stream. The default value is ``null``. + configuration for the upload stream. The default value is ``null``. **Data type**: `GridFSUploadOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSUploadOptions.html>`__ * - ``cancellationToken`` @@ -282,6 +282,8 @@ Use the ``UploadFromStreamAsync()`` or ``UploadFromStream()`` method to upload t contents of a stream to a new GridFS file. These methods accept the following parameters: .. list-table:: + :widths: 30 70 + :header-rows: 1 * - Parameter - Description @@ -290,18 +292,18 @@ contents of a stream to a new GridFS file. These methods accept the following pa - The name of the file to upload. **Data type**: {+string-data-type+} - + * - ``source`` - The stream from which to read the file contents. **Data type**: `Stream `__ - + * - ``options`` - *Optional.* An instance of the ``GridFSUploadOptions`` class that specifies the configuration for the upload stream. The default value is ``null``. **Data type**: `GridFSUploadOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.GridFSUploadOptions.html>`__ - + * - ``cancellationToken`` - *Optional.* A token that you can use to cancel the operation. @@ -360,6 +362,8 @@ Use the ``OpenDownloadStreamAsync()`` or ``OpenDownloadStream()`` method to crea download stream. These methods accept the following parameters: .. list-table:: + :widths: 30 70 + :header-rows: 1 * - Parameter - Description @@ -415,6 +419,8 @@ To customize the download stream configuration, pass an instance of the ``GridFSDownloadOptions`` class contains the following properties: .. list-table:: + :widths: 30 70 + :header-rows: 1 * - Property - Description @@ -459,6 +465,8 @@ Use the ``DownloadToStreamAsync()`` or ``DownloadToStream()`` method to download contents of a GridFS file to an existing stream. These methods accept the following parameters: .. list-table:: + :widths: 30 70 + :header-rows: 1 * - Parameter - Description @@ -522,6 +530,8 @@ To retrieve files from a GridFS bucket, call the ``FindAsync()`` or ``Find()`` m on your ``GridFSBucket`` instance. These methods accept the following parameters: .. list-table:: + :widths: 30 70 + :header-rows: 1 * - Parameter - Description @@ -633,6 +643,8 @@ its associated chunks from your bucket. The ``DeleteAsync`` and ``Delete()`` methods accept the following parameters: .. list-table:: + :widths: 30 70 + :header-rows: 1 * - Parameter - Description From f80753ff2db88ccf195594b9a8204e312fccd9e3 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Thu, 14 Nov 2024 14:51:42 -0600 Subject: [PATCH 32/35] feedback --- source/fundamentals/gridfs.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source/fundamentals/gridfs.txt b/source/fundamentals/gridfs.txt index ffa70a53..a883e5ad 100644 --- a/source/fundamentals/gridfs.txt +++ b/source/fundamentals/gridfs.txt @@ -134,7 +134,6 @@ the ``GridFSBucket()`` constructor. The following table describes the properties The following example creates a bucket named ``"myCustomBucket"`` by passing an instance of the ``GridFSBucketOptions`` class to the ``GridFSBucket()`` constructor: - .. literalinclude:: /includes/code-examples/GridFS.cs :language: csharp :dedent: @@ -302,7 +301,7 @@ contents of a stream to a new GridFS file. These methods accept the following pa - *Optional.* An instance of the ``GridFSUploadOptions`` class that specifies the configuration for the upload stream. The default value is ``null``. - **Data type**: `GridFSUploadOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.GridFSUploadOptions.html>`__ + **Data type**: `GridFSUploadOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSUploadOptions.html>`__ * - ``cancellationToken`` - *Optional.* A token that you can use to cancel the operation. @@ -416,7 +415,7 @@ code. To customize the download stream configuration, pass an instance of the ``GridFSDownloadOptions`` class to the ``OpenDownloadStream()`` method. The -``GridFSDownloadOptions`` class contains the following properties: +``GridFSDownloadOptions`` class contains the following property: .. list-table:: :widths: 30 70 From bf9744fd529ea71cd852b1a20422386d87179312 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Fri, 15 Nov 2024 12:21:37 -0600 Subject: [PATCH 33/35] feedback --- source/fundamentals/gridfs.txt | 203 ++++++++++++------------ source/includes/code-examples/GridFS.cs | 141 +++++++++------- 2 files changed, 184 insertions(+), 160 deletions(-) diff --git a/source/fundamentals/gridfs.txt b/source/fundamentals/gridfs.txt index a883e5ad..ea6e15b9 100644 --- a/source/fundamentals/gridfs.txt +++ b/source/fundamentals/gridfs.txt @@ -147,9 +147,9 @@ Upload Files You can upload files to a GridFS bucket by using the following methods: -- ``OpenUploadStreamAsync()`` or ``OpenUploadStream()``: Opens a new upload stream to which +- ``OpenUploadStream()`` or ``OpenUploadStreamAsync()``: Opens a new upload stream to which you can write file contents -- ``UploadFromStreamAsync()`` or ``UploadFromStream()``: Uploads the contents of an existing +- ``UploadFromStream()`` or ``UploadFromStreamAsync()``: Uploads the contents of an existing stream to a GridFS file The following sections describe how to use these methods. @@ -159,7 +159,7 @@ The following sections describe how to use these methods. Write to an Upload Stream ~~~~~~~~~~~~~~~~~~~~~~~~~ -Use the ``OpenUploadStreamAsync()`` or ``OpenUploadStream()`` method to create an upload +Use the ``OpenUploadStream()`` or ``OpenUploadStreamAsync()`` method to create an upload stream for a given file name. These methods accept the following parameters: .. list-table:: @@ -190,31 +190,31 @@ following steps: - Calls the ``Write()`` method to write data to ``my_file`` - Calls the ``Close()`` method to close the stream that points to ``my_file`` -Select the :guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the corresponding +Select the :guilabel:`Synchronous` or :guilabel:`Asynchronous` tab to see the corresponding code: .. tabs:: - .. tab:: Asynchronous - :tabid: open-upload-stream-async + .. tab:: Synchronous + :tabid: open-upload-stream-sync .. literalinclude:: /includes/code-examples/GridFS.cs :language: csharp :dedent: - :start-after: // start-open-upload-stream-async - :end-before: // end-open-upload-stream-async + :start-after: // start-open-upload-stream + :end-before: // end-open-upload-stream - .. tab:: Synchronous - :tabid: open-upload-stream-sync + .. tab:: Asynchronous + :tabid: open-upload-stream-async .. literalinclude:: /includes/code-examples/GridFS.cs :language: csharp :dedent: - :start-after: // start-open-upload-stream - :end-before: // end-open-upload-stream + :start-after: // start-open-upload-stream-async + :end-before: // end-open-upload-stream-async To customize the upload stream configuration, pass an instance of the -``GridFSUploadOptions`` class to the ``OpenUploadStreamAsync()`` or ``OpenUploadStream()`` +``GridFSUploadOptions`` class to the ``OpenUploadStream()`` or ``OpenUploadStreamAsync()`` method. The ``GridFSUploadOptions`` class contains the following properties: .. list-table:: @@ -230,7 +230,7 @@ method. The ``GridFSUploadOptions`` class contains the following properties: **Data type**: ``int?`` * - ``ChunkSizeBytes`` - - The maximum size of each chunk. + - The size of each chunk except the last, which is smaller. The default value is 255 KB. **Data type**: ``int?`` @@ -248,36 +248,36 @@ method. The ``GridFSUploadOptions`` class contains the following properties: **Data type**: `BsonDocument <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonDocument.html>`__ The following example performs the same steps as the preceding example, but also uses -the ``ChunkSizeBytes`` option to specify the maximum size of each chunk. Select the -:guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the corresponding +the ``ChunkSizeBytes`` option to specify the size of each chunk. Select the +:guilabel:`Synchronous` or :guilabel:`Asynchronous` tab to see the corresponding code. .. tabs:: - .. tab:: Asynchronous - :tabid: open-upload-stream-with-options-async + .. tab:: Synchronous + :tabid: open-upload-stream-with-options-sync .. literalinclude:: /includes/code-examples/GridFS.cs :language: csharp :dedent: - :start-after: // start-open-upload-stream-with-options-async - :end-before: // end-open-upload-stream-with-options-async + :start-after: // start-open-upload-stream-with-options + :end-before: // end-open-upload-stream-with-options - .. tab:: Synchronous - :tabid: open-upload-stream-with-options-sync + .. tab:: Asynchronous + :tabid: open-upload-stream-with-options-async .. literalinclude:: /includes/code-examples/GridFS.cs :language: csharp :dedent: - :start-after: // start-open-upload-stream-with-options - :end-before: // end-open-upload-stream-with-options + :start-after: // start-open-upload-stream-with-options-async + :end-before: // end-open-upload-stream-with-options-async .. _csharp-gridfs-upload-from-stream: Upload an Existing Stream ~~~~~~~~~~~~~~~~~~~~~~~~~ -Use the ``UploadFromStreamAsync()`` or ``UploadFromStream()`` method to upload the +Use the ``UploadFromStream()`` or ``UploadFromStreamAsync()`` method to upload the contents of a stream to a new GridFS file. These methods accept the following parameters: .. list-table:: @@ -315,28 +315,28 @@ following steps: - Calls the ``UploadFromStream()`` method to write the contents of the stream to a GridFS file named ``"new_file"`` -Select the :guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the corresponding +Select the :guilabel:`Synchronous` or :guilabel:`Asynchronous` tab to see the corresponding code. .. tabs:: - .. tab:: Asynchronous - :tabid: upload-from-stream-async + .. tab:: Synchronous + :tabid: upload-from-stream-sync .. literalinclude:: /includes/code-examples/GridFS.cs :language: csharp :dedent: - :start-after: // start-upload-from-stream-async - :end-before: // end-upload-from-stream-async + :start-after: // start-upload-from-stream + :end-before: // end-upload-from-stream - .. tab:: Synchronous - :tabid: upload-from-stream-sync + .. tab:: Asynchronous + :tabid: upload-from-stream-async .. literalinclude:: /includes/code-examples/GridFS.cs :language: csharp :dedent: - :start-after: // start-upload-from-stream - :end-before: // end-upload-from-stream + :start-after: // start-upload-from-stream-async + :end-before: // end-upload-from-stream-async .. _csharp-gridfs-download-files: @@ -345,9 +345,9 @@ Download Files You can download files from a GridFS bucket by using the following methods: -- ``OpenDownloadStreamAsync()`` or ``OpenDownloadStream()``: Opens a new download stream +- ``OpenDownloadStream()`` or ``OpenDownloadStreamAsync()``: Opens a new download stream from which you can read file contents -- ``DownloadToStreamAsync()`` or ``DownloadToStream()``: Writes the contents of a GridFS +- ``DownloadToStream()`` or ``DownloadToStreamAsync()``: Writes the contents of a GridFS file to an existing stream The following sections describe these methods in more detail. @@ -357,7 +357,7 @@ The following sections describe these methods in more detail. Read From a Download Stream ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Use the ``OpenDownloadStreamAsync()`` or ``OpenDownloadStream()`` method to create a +Use the ``OpenDownloadStream()`` or ``OpenDownloadStreamAsync()`` method to create a download stream. These methods accept the following parameters: .. list-table:: @@ -390,28 +390,28 @@ following steps: - Calls the ``Read()`` method to read the file contents from the ``downloader`` stream into the vector -Select the :guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the corresponding +Select the :guilabel:`Synchronous` or :guilabel:`Asynchronous` tab to see the corresponding code. .. tabs:: - .. tab:: Asynchronous - :tabid: open-download-stream-async + .. tab:: Synchronous + :tabid: open-download-stream-sync .. literalinclude:: /includes/code-examples/GridFS.cs :language: csharp :dedent: - :start-after: // start-open-download-stream-async - :end-before: // end-open-download-stream-async + :start-after: // start-open-download-stream + :end-before: // end-open-download-stream - .. tab:: Synchronous - :tabid: open-download-stream-sync + .. tab:: Asynchronous + :tabid: open-download-stream-async .. literalinclude:: /includes/code-examples/GridFS.cs :language: csharp :dedent: - :start-after: // start-open-download-stream - :end-before: // end-open-download-stream + :start-after: // start-open-download-stream-async + :end-before: // end-open-download-stream-async To customize the download stream configuration, pass an instance of the ``GridFSDownloadOptions`` class to the ``OpenDownloadStream()`` method. The @@ -432,20 +432,11 @@ To customize the download stream configuration, pass an instance of the The following example performs the same steps as the preceding example, but also sets the ``Seekable`` option to ``true`` to specify that the stream is seekable. -Select the :guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the corresponding +Select the :guilabel:`Synchronous` or :guilabel:`Asynchronous` tab to see the corresponding code. .. tabs:: - .. tab:: Asynchronous - :tabid: open-download-stream-with-options-async - - .. literalinclude:: /includes/code-examples/GridFS.cs - :language: csharp - :dedent: - :start-after: // start-open-download-stream-with-options-async - :end-before: // end-open-download-stream-with-options-async - .. tab:: Synchronous :tabid: open-download-stream-with-options-sync @@ -454,13 +445,22 @@ code. :dedent: :start-after: // start-open-download-stream-with-options :end-before: // end-open-download-stream-with-options - + + .. tab:: Asynchronous + :tabid: open-download-stream-with-options-async + + .. literalinclude:: /includes/code-examples/GridFS.cs + :language: csharp + :dedent: + :start-after: // start-open-download-stream-with-options-async + :end-before: // end-open-download-stream-with-options-async + .. _csharp-gridfs-download_to_stream: Download to an Existing Stream ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Use the ``DownloadToStreamAsync()`` or ``DownloadToStream()`` method to download the +Use the ``DownloadToStream()`` or ``DownloadToStreamAsync()`` method to download the contents of a GridFS file to an existing stream. These methods accept the following parameters: .. list-table:: @@ -497,35 +497,35 @@ performing the following actions: - Calls the ``DownloadToStream()`` method and passes the ``_id`` value to download the contents of ``"new_file"`` to a stream -Select the :guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the corresponding +Select the :guilabel:`Synchronous` or :guilabel:`Asynchronous` tab to see the corresponding code. .. tabs:: - .. tab:: Asynchronous - :tabid: download-to-stream-async + .. tab:: Synchronous + :tabid: download-to-stream-sync .. literalinclude:: /includes/code-examples/GridFS.cs :language: csharp :dedent: - :start-after: // start-download-to-stream-async - :end-before: // end-download-to-stream-async + :start-after: // start-download-to-stream + :end-before: // end-download-to-stream - .. tab:: Synchronous - :tabid: download-to-stream-sync + .. tab:: Asynchronous + :tabid: download-to-stream-async .. literalinclude:: /includes/code-examples/GridFS.cs :language: csharp :dedent: - :start-after: // start-download-to-stream - :end-before: // end-download-to-stream + :start-after: // start-download-to-stream-async + :end-before: // end-download-to-stream-async .. _csharp-gridfs-retrieve-file-info: -Retrieve Files --------------- +Find Files +---------- -To retrieve files from a GridFS bucket, call the ``FindAsync()`` or ``Find()`` method +To retrieve files from a GridFS bucket, call the ``Find()`` or ``FindAsync()`` method on your ``GridFSBucket`` instance. These methods accept the following parameters: .. list-table:: @@ -566,20 +566,20 @@ which you can access the results. It uses a ``foreach`` loop to iterate through the returned cursor and display the contents of the files uploaded in the :ref:`csharp-gridfs-upload-files` examples. -Select the :guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the corresponding +Select the :guilabel:`Synchronous` or :guilabel:`Asynchronous` tab to see the corresponding code. .. tabs:: - .. tab:: Asynchronous - :tabid: find-async + .. tab:: Synchronous + :tabid: find-sync .. io-code-block:: :copyable: .. input:: /includes/code-examples/GridFS.cs - :start-after: // start-find-async - :end-before: // end-find-async + :start-after: // start-find + :end-before: // end-find :language: csharp :dedent: @@ -591,15 +591,15 @@ code. { "_id" : { "$oid" : "..." }, "length" : 50, "chunkSize" : 1048576, "uploadDate" : { "$date" : ... }, "filename" : "my_file" } - .. tab:: Synchronous - :tabid: find-sync + .. tab:: Asynchronous + :tabid: find-async .. io-code-block:: :copyable: .. input:: /includes/code-examples/GridFS.cs - :start-after: // start-find - :end-before: // end-find + :start-after: // start-find-async + :end-before: // end-find-async :language: csharp :dedent: @@ -612,7 +612,7 @@ code. { "$date" : ... }, "filename" : "my_file" } To customize the find operation, pass an instance of the -``GridFSFindOptions`` class to the ``FindAsync()`` or ``Find()`` method. The +``GridFSFindOptions`` class to the ``Find()`` or ``FindAsync()`` method. The ``GridFSFindOptions`` class contains the following properties: .. list-table:: @@ -628,18 +628,19 @@ To customize the find operation, pass an instance of the **Data type**: ``SortDefinition``. For more information, see the API documentation for the - `Sort <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSFindOptions.Sort.html>`__ property. + `Sort <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSFindOptions.Sort.html>`__ + property. .. _csharp-gridfs-delete-files: Delete Files ------------ -To delete files from a GridFS bucket, call the ``DeleteAsync()`` or ``Delete()`` method +To delete files from a GridFS bucket, call the ``Delete()`` or ``DeleteAsync()`` method on your ``GridFSBucket`` instance. This method removes a file's metadata collection and its associated chunks from your bucket. -The ``DeleteAsync`` and ``Delete()`` methods accept the following parameters: +The ``Delete`` and ``DeleteAsync()`` methods accept the following parameters: .. list-table:: :widths: 30 70 @@ -663,35 +664,35 @@ passing its ``_id`` value to ``delete_file()``: - Uses the ``Find()`` method to find the file named ``"my_file"`` - Passes the ``_id`` value of the file to the ``Delete()`` method to delete the file -Select the :guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the corresponding +Select the :guilabel:`Synchronous` or :guilabel:`Asynchronous` tab to see the corresponding code. .. tabs:: - .. tab:: Asynchronous - :tabid: delete-file-async + .. tab:: Synchronous + :tabid: download-to-stream-sync .. literalinclude:: /includes/code-examples/GridFS.cs :language: csharp :dedent: - :start-after: // start-delete-file-async - :end-before: // end-delete-file-async + :start-after: // start-delete-file + :end-before: // end-delete-file - .. tab:: Synchronous - :tabid: download-to-stream-sync + .. tab:: Asynchronous + :tabid: delete-file-async .. literalinclude:: /includes/code-examples/GridFS.cs :language: csharp :dedent: - :start-after: // start-delete-file - :end-before: // end-delete-file + :start-after: // start-delete-file-async + :end-before: // end-delete-file-async .. note:: File Revisions - The ``DeleteAsync()`` and ``Delete()`` methods support deleting only one file at a time. + The ``Delete()`` and ``DeleteAsync()`` methods support deleting only one file at a time. If you want to delete each file revision, or files with different upload times that share the same file name, collect the ``_id`` values of each revision. - Then, pass each ``_id`` value in separate calls to the ``DeleteAsync()`` or ``Delete()`` + Then, pass each ``_id`` value in separate calls to the ``Delete()`` or ``DeleteAsync()`` method. API Documentation @@ -709,15 +710,15 @@ To learn more about the classes used on this page, see the following API documen To learn more about the methods in the ``GridFSBucket`` class used on this page, see the following API documentation: -- `OpenUploadStreamAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.OpenUploadStreamAsync.html>`__ - `OpenUploadStream() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.OpenUploadStream.html>`__ -- `UploadFromStreamAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.UploadFromStreamAsync.html>`__ +- `OpenUploadStreamAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.OpenUploadStreamAsync.html>`__ - `UploadFromStream() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.UploadFromStream.html>`__ -- `OpenDownloadStreamAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.OpenDownloadStreamAsync.html>`__ +- `UploadFromStreamAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.UploadFromStreamAsync.html>`__ - `OpenDownloadStream() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.OpenDownloadStream.html>`__ -- `DownloadToStreamAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.DownloadToStreamAsync.html>`__ +- `OpenDownloadStreamAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.OpenDownloadStreamAsync.html>`__ - `DownloadToStream() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.DownloadToStream.html>`__ -- `FindAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.FindAsync.html>`__ +- `DownloadToStreamAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.DownloadToStreamAsync.html>`__ - `Find() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.Find.html>`__ -- `DeleteAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.DeleteAsync.html>`__ -- `Delete() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.Delete.html>`__ \ No newline at end of file +- `FindAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.FindAsync.html>`__ +- `Delete() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.Delete.html>`__ +- `DeleteAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GridFS.GridFSBucket.DeleteAsync.html>`__ \ No newline at end of file diff --git a/source/includes/code-examples/GridFS.cs b/source/includes/code-examples/GridFS.cs index eaa6ed10..b42d4b91 100644 --- a/source/includes/code-examples/GridFS.cs +++ b/source/includes/code-examples/GridFS.cs @@ -215,9 +215,7 @@ static async Task FindAsync() // Prints information about each file in the bucket // start-find-async var filter = Builders.Filter.Empty; - var files = await bucket.FindAsync(filter); - await files.ForEachAsync(file => { Console.WriteLine(file.ToJson()); }); // end-find-async } @@ -233,16 +231,20 @@ static async Task DownloadFileAsync() // Downloads a file from the GridFS bucket by referencing its ObjectId value // start-open-download-stream-async - var filter = Builders.Filter.Eq("filename", "new_file"); - var doc = await database.GetCollection("fs.files").Find(filter).FirstOrDefaultAsync(); - var id = doc["_id"].AsObjectId; + var filter = Builders.Filter.Eq(x => x.Filename, "new_file"); + var cursor = await bucket.FindAsync(filter); + var fileInfoList = await cursor.ToListAsync(); + var doc = fileInfoList.FirstOrDefault(); - using (var downloader = await bucket.OpenDownloadStreamAsync(id)) + if (doc != null) { - var buffer = new byte[downloader.Length]; - await downloader.ReadAsync(buffer, 0, buffer.Length); + using (var downloader = await bucket.OpenDownloadStreamAsync(doc.Id)) + { + var buffer = new byte[downloader.Length]; + await downloader.ReadAsync(buffer, 0, buffer.Length); - // Process the buffer as needed + // Process the buffer as needed + } } // end-open-download-stream-async } @@ -258,16 +260,18 @@ static void DownloadFile() // Downloads a file from the GridFS bucket by referencing its ObjectId value // start-open-download-stream - var filter = Builders.Filter.Eq("filename", "new_file"); - var doc = database.GetCollection("fs.files").Find(filter).FirstOrDefault(); - var id = doc["_id"].AsObjectId; + var filter = Builders.Filter.Eq(x => x.Filename, "new_file"); + var doc = bucket.Find(filter).FirstOrDefault(); - using (var downloader = bucket.OpenDownloadStream(id)) + if (doc != null) { - var buffer = new byte[downloader.Length]; - downloader.Read(buffer, 0, buffer.Length); + using (var downloader = bucket.OpenDownloadStream(doc.Id)) + { + var buffer = new byte[downloader.Length]; + downloader.Read(buffer, 0, buffer.Length); - // Process the buffer as needed + // Process the buffer as needed + } } // end-open-download-stream } @@ -283,23 +287,27 @@ static async Task DownloadFileWithOptionsAsync() // Downloads a file from the GridFS bucket by referencing its ObjectId value // start-open-download-stream-with-options-async - var filter = Builders.Filter.Eq("filename", "new_file"); - var doc = await database.GetCollection("fs.files").Find(filter).FirstOrDefaultAsync(); - var id = doc["_id"].AsObjectId; + var filter = Builders.Filter.Eq(x => x.Filename, "new_file"); + var cursor = await bucket.FindAsync(filter); + var fileInfoList = await cursor.ToListAsync(); + var doc = fileInfoList.FirstOrDefault(); - var options = new GridFSDownloadOptions + if (doc != null) { - Seekable = true - }; + var options = new GridFSDownloadOptions + { + Seekable = true + }; - using (var downloader = await bucket.OpenDownloadStreamAsync(id, options)) - { - var buffer = new byte[downloader.Length]; - await downloader.ReadAsync(buffer, 0, buffer.Length); + using (var downloader = await bucket.OpenDownloadStreamAsync(doc.Id, options)) + { + var buffer = new byte[downloader.Length]; + await downloader.ReadAsync(buffer, 0, buffer.Length); - // Process the buffer as needed + // Process the buffer as needed + } } - // end-open-download-stream-with-options-async + // end-open-download-stream-with-options-async } static void DownloadFileWithOptions() @@ -313,24 +321,27 @@ static void DownloadFileWithOptions() // Downloads a file from the GridFS bucket by referencing its ObjectId value // start-open-download-stream-with-options - var filter = Builders.Filter.Eq("filename", "new_file"); - var doc = database.GetCollection("fs.files").Find(filter).FirstOrDefault(); - var id = doc["_id"].AsObjectId; + var filter = Builders.Filter.Eq(x => x.Filename, "new_file"); + var doc = bucket.Find(filter).FirstOrDefault(); - var options = new GridFSDownloadOptions + if (doc != null) { - Seekable = true - }; + var options = new GridFSDownloadOptions + { + Seekable = true + }; - using (var downloader = bucket.OpenDownloadStream(id, options)) - { - var buffer = new byte[downloader.Length]; - downloader.Read(buffer, 0, buffer.Length); + using (var downloader = bucket.OpenDownloadStream(id, options)) + { + var buffer = new byte[downloader.Length]; + downloader.Read(buffer, 0, buffer.Length); - // Process the buffer as needed + // Process the buffer as needed + } } // end-open-download-stream-with-options } + static async Task DownloadStreamAsync() { // Initialize MongoDB client @@ -342,13 +353,17 @@ static async Task DownloadStreamAsync() // Downloads an entire GridFS file to a download stream // start-download-to-stream-async - using (var outputFile = new FileStream("/path/to/output_file", FileMode.Create, FileAccess.Write)) - { - var filter = Builders.Filter.Eq("filename", "new_file"); - var doc = await database.GetCollection("fs.files").Find(filter).FirstOrDefaultAsync(); - var id = doc["_id"].AsObjectId; + var filter = Builders.Filter.Eq(x => x.Filename, "new_file"); + var cursor = await bucket.FindAsync(filter); + var fileInfoList = await cursor.ToListAsync(); + var doc = fileInfoList.FirstOrDefault(); - await bucket.DownloadToStreamAsync(id, outputFile); + if (doc != null) + { + using (var outputFile = new FileStream("/path/to/output_file", FileMode.Create, FileAccess.Write)) + { + await bucket.DownloadToStreamAsync(doc.Id, outputFile); + } } // end-download-to-stream-async } @@ -364,13 +379,15 @@ static void DownloadStream() // Downloads an entire GridFS file to a download stream // start-download-to-stream - using (var outputFile = new FileStream("/path/to/output_file", FileMode.Create, FileAccess.Write)) - { - var filter = Builders.Filter.Eq("filename", "new_file"); - var doc = database.GetCollection("fs.files").Find(filter).FirstOrDefault(); - var id = doc["_id"].AsObjectId; + var filter = Builders.Filter.Eq(x => x.Filename, "new_file"); + var doc = bucket.Find(filter).FirstOrDefault(); - bucket.DownloadToStream(id, outputFile); + if (doc != null) + { + using (var outputFile = new FileStream("/path/to/output_file", FileMode.Create, FileAccess.Write)) + { + bucket.DownloadToStream(doc.Id, outputFile); + } } // end-download-to-stream } @@ -386,11 +403,15 @@ static async Task DeleteFileAsync() // Deletes a file from the GridFS bucket with the specified ObjectId // start-delete-file-async - var filter = Builders.Filter.Eq("filename", "my_file"); - var doc = await database.GetCollection("fs.files").Find(filter).FirstOrDefaultAsync(); - var id = doc["_id"].AsObjectId; + var filter = Builders.Filter.Eq(x => x.Filename, "new_file"); + var cursor = await bucket.FindAsync(filter); + var fileInfoList = await cursor.ToListAsync(); + var doc = fileInfoList.FirstOrDefault(); - await bucket.DeleteAsync(id); + if (doc != null) + { + await bucket.DeleteAsync(doc.Id); + } // end-delete-file-async } @@ -405,11 +426,13 @@ static void DeleteFile() // Deletes a file from the GridFS bucket with the specified ObjectId // start-delete-file - var filter = Builders.Filter.Eq("filename", "my_file"); - var doc = database.GetCollection("fs.files").Find(filter).FirstOrDefault(); - var id = doc["_id"].AsObjectId; + var filter = Builders.Filter.Eq(x => x.Filename, "new_file"); + var doc = bucket.Find(filter).FirstOrDefault(); - bucket.Delete(id); + if (doc != null) + { + bucket.Delete(doc.Id); + } // end-delete-file } } \ No newline at end of file From 2a42c9e504d09ff1ea9ee750d98195e742127847 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Tue, 19 Nov 2024 08:25:07 -0600 Subject: [PATCH 34/35] rs feedback --- source/fundamentals/gridfs.txt | 4 ++-- source/includes/code-examples/GridFS.cs | 26 +++++-------------------- 2 files changed, 7 insertions(+), 23 deletions(-) diff --git a/source/fundamentals/gridfs.txt b/source/fundamentals/gridfs.txt index ea6e15b9..4f62c2b5 100644 --- a/source/fundamentals/gridfs.txt +++ b/source/fundamentals/gridfs.txt @@ -109,7 +109,7 @@ the ``GridFSBucket()`` constructor. The following table describes the properties **Data type**: {+string-data-type+} * - ``ChunkSizeBytes`` - - The chunk size that GridFS splits files into. The default value is ``261120``. + - The chunk size that GridFS splits files into. The default value is 255 KB. **Data type**: {+int-data-type+} @@ -224,7 +224,7 @@ method. The ``GridFSUploadOptions`` class contains the following properties: * - Property - Description * - ``BatchSize`` - - The number of chunks to upload in each batch. The default value is ``16777216`` + - The number of chunks to upload in each batch. The default value is 16 MB divided by the value of the ``ChunkSizeBytes`` property. **Data type**: ``int?`` diff --git a/source/includes/code-examples/GridFS.cs b/source/includes/code-examples/GridFS.cs index b42d4b91..b9f7624c 100644 --- a/source/includes/code-examples/GridFS.cs +++ b/source/includes/code-examples/GridFS.cs @@ -47,11 +47,7 @@ static async Task UploadFileAsync() // ASCII for "HelloWorld" byte[] bytes = { 72, 101, 108, 108, 111, 87, 111, 114, 108, 100 }; - for (int i = 0; i < 5; i++) - { - await uploader.WriteAsync(bytes, 0, bytes.Length); - } - + await uploader.WriteAsync(bytes, 0, bytes.Length); await uploader.CloseAsync(); } // end-open-upload-stream-async @@ -73,11 +69,7 @@ static void UploadFile() // ASCII for "HelloWorld" byte[] bytes = { 72, 101, 108, 108, 111, 87, 111, 114, 108, 100 }; - for (int i = 0; i < 5; i++) - { - uploader.Write(bytes, 0, bytes.Length); - } - + uploader.Write(bytes, 0, bytes.Length); uploader.Close(); } // end-open-upload-stream @@ -104,11 +96,7 @@ static async Task UploadFileWithOptionsAsync() // ASCII for "HelloWorld" byte[] bytes = { 72, 101, 108, 108, 111, 87, 111, 114, 108, 100 }; - for (int i = 0; i < 5; i++) - { - await uploader.WriteAsync(bytes, 0, bytes.Length); - } - + await uploader.WriteAsync(bytes, 0, bytes.Length); await uploader.CloseAsync(); } // end-open-upload-stream-with-options-async @@ -135,11 +123,7 @@ static void UploadFileWithOptions() // ASCII for "HelloWorld" byte[] bytes = { 72, 101, 108, 108, 111, 87, 111, 114, 108, 100 }; - for (int i = 0; i < 5; i++) - { - uploader.Write(bytes, 0, bytes.Length); - } - + uploader.Write(bytes, 0, bytes.Length); uploader.Close(); } // end-open-upload-stream-with-options @@ -216,7 +200,7 @@ static async Task FindAsync() // start-find-async var filter = Builders.Filter.Empty; var files = await bucket.FindAsync(filter); - await files.ForEachAsync(file => { Console.WriteLine(file.ToJson()); }); + await files.ForEachAsync(file => Console.Out.WriteLineAsync(file.ToJson())) // end-find-async } From b4219cb8c2c1baf5da8fb328e71659e93d742e8d Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Wed, 27 Nov 2024 10:55:49 -0600 Subject: [PATCH 35/35] feedback --- source/fundamentals/gridfs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/fundamentals/gridfs.txt b/source/fundamentals/gridfs.txt index 4f62c2b5..c5906346 100644 --- a/source/fundamentals/gridfs.txt +++ b/source/fundamentals/gridfs.txt @@ -525,7 +525,7 @@ code. Find Files ---------- -To retrieve files from a GridFS bucket, call the ``Find()`` or ``FindAsync()`` method +To find files in a GridFS bucket, call the ``Find()`` or ``FindAsync()`` method on your ``GridFSBucket`` instance. These methods accept the following parameters: .. list-table::