From b44d8e7799d72f883cb19547349fd5a1fbe7ba7a Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Fri, 10 Jan 2025 11:50:47 -0600 Subject: [PATCH 01/35] TOC Reorg - Get Started (#407) --- snooty.toml | 3 +- source/fundamentals/aggregation.txt | 2 +- source/fundamentals/builders.txt | 2 +- .../crud/read-operations/change-streams.txt | 2 +- .../crud/read-operations/distinct.txt | 2 +- .../crud/read-operations/project.txt | 2 +- .../crud/read-operations/retrieve.txt | 2 +- .../crud/write-operations/bulk-write.txt | 2 +- .../crud/write-operations/delete.txt | 2 +- .../crud/write-operations/insert.txt | 2 +- .../databases-collections/run-command.txt | 2 +- source/fundamentals/geo.txt | 2 +- source/fundamentals/indexes.txt | 2 +- source/fundamentals/linq.txt | 4 +- source/fundamentals/odata.txt | 2 +- source/get-started.txt | 44 ++++++ .../get-started/create-connection-string.txt | 86 +++++++++++ source/get-started/deploy-cluster.txt | 29 ++++ source/get-started/download-driver.txt | 34 +++++ source/get-started/run-sample-query.txt | 49 +++++++ source/includes/atlas-sample-data.rst | 2 +- .../figures/atlas_connection_copy_string.png | Bin 0 -> 227623 bytes .../atlas_connection_select_cluster.png | Bin 0 -> 35481 bytes .../get-started/quickstart-troubleshoot.rst | 6 + source/includes/quick-start/Program.cs | 2 +- source/index.txt | 8 +- source/quick-start.txt | 134 ------------------ source/usage-examples.txt | 2 +- source/whats-new.txt | 2 +- 29 files changed, 273 insertions(+), 158 deletions(-) create mode 100644 source/get-started.txt create mode 100644 source/get-started/create-connection-string.txt create mode 100644 source/get-started/deploy-cluster.txt create mode 100644 source/get-started/download-driver.txt create mode 100644 source/get-started/run-sample-query.txt create mode 100644 source/includes/figures/atlas_connection_copy_string.png create mode 100644 source/includes/figures/atlas_connection_select_cluster.png create mode 100644 source/includes/get-started/quickstart-troubleshoot.rst delete mode 100644 source/quick-start.txt diff --git a/snooty.toml b/snooty.toml index de02167f..085ef4b7 100644 --- a/snooty.toml +++ b/snooty.toml @@ -8,7 +8,8 @@ toc_landing_pages = [ "/fundamentals/crud/write-operations/update-many", "/fundamentals/authentication", "/upgrade", - "/fundamentals/database-collection" + "/fundamentals/database-collection", + "/get-started" ] name = "csharp" title = "C#/.NET" diff --git a/source/fundamentals/aggregation.txt b/source/fundamentals/aggregation.txt index 735210f7..96169dd5 100644 --- a/source/fundamentals/aggregation.txt +++ b/source/fundamentals/aggregation.txt @@ -100,7 +100,7 @@ To perform an aggregation, pass a list of aggregation stages to the This example uses 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 :ref:`csharp-quickstart`. + free MongoDB Atlas cluster and load the sample datasets, see :ref:`csharp-get-started`. The following code example produces a count of the number of bakeries in each borough of New York City. To do so, it uses an aggregation pipeline that contains the following stages: diff --git a/source/fundamentals/builders.txt b/source/fundamentals/builders.txt index 0f2cdcc5..1876e831 100644 --- a/source/fundamentals/builders.txt +++ b/source/fundamentals/builders.txt @@ -434,7 +434,7 @@ have a defined Atlas Vector Search index before you can perform a vector search .. tip:: - To obtain the sample dataset used in the following example, see :ref:`csharp-quickstart`. + To obtain the sample dataset used in the following example, see :ref:`csharp-get-started`. To create the sample Atlas Vector Search index used in the following example, see :atlas:`Create an Atlas Vector Search Index ` in the Atlas manual. diff --git a/source/fundamentals/crud/read-operations/change-streams.txt b/source/fundamentals/crud/read-operations/change-streams.txt index d30f55a2..e2fcc359 100644 --- a/source/fundamentals/crud/read-operations/change-streams.txt +++ b/source/fundamentals/crud/read-operations/change-streams.txt @@ -30,7 +30,7 @@ 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:``. +free MongoDB Atlas cluster and load the sample datasets, see the :ref:``. The examples on this page use the following ``Restaurant``, ``Address``, and ``GradeEntry`` classes as models: diff --git a/source/fundamentals/crud/read-operations/distinct.txt b/source/fundamentals/crud/read-operations/distinct.txt index 743609ae..a3af7165 100644 --- a/source/fundamentals/crud/read-operations/distinct.txt +++ b/source/fundamentals/crud/read-operations/distinct.txt @@ -34,7 +34,7 @@ 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:``. +free MongoDB Atlas cluster and load the sample datasets, see the :ref:``. The examples on this page uses the following ``Restaurant`` class to model the documents in the collection: diff --git a/source/fundamentals/crud/read-operations/project.txt b/source/fundamentals/crud/read-operations/project.txt index fb64294e..6ad03656 100644 --- a/source/fundamentals/crud/read-operations/project.txt +++ b/source/fundamentals/crud/read-operations/project.txt @@ -29,7 +29,7 @@ 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:``. +free MongoDB Atlas cluster and load the sample datasets, see the :ref:``. Projection Types ---------------- diff --git a/source/fundamentals/crud/read-operations/retrieve.txt b/source/fundamentals/crud/read-operations/retrieve.txt index abd171f6..396b0580 100644 --- a/source/fundamentals/crud/read-operations/retrieve.txt +++ b/source/fundamentals/crud/read-operations/retrieve.txt @@ -39,7 +39,7 @@ 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:``. +free MongoDB Atlas cluster and load the sample datasets, see the :ref:``. The examples on this page use the following ``Restaurant``, ``Address``, and ``GradeEntry`` classes as models: diff --git a/source/fundamentals/crud/write-operations/bulk-write.txt b/source/fundamentals/crud/write-operations/bulk-write.txt index 37346e76..fb7a0963 100644 --- a/source/fundamentals/crud/write-operations/bulk-write.txt +++ b/source/fundamentals/crud/write-operations/bulk-write.txt @@ -32,7 +32,7 @@ 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. +:ref:`` tutorial. Define the Write Operations --------------------------- diff --git a/source/fundamentals/crud/write-operations/delete.txt b/source/fundamentals/crud/write-operations/delete.txt index 5d26c3c1..0b5605fe 100644 --- a/source/fundamentals/crud/write-operations/delete.txt +++ b/source/fundamentals/crud/write-operations/delete.txt @@ -44,7 +44,7 @@ classes as models: .. include:: /includes/convention-pack-note.rst This collection is from the :atlas:`sample datasets ` provided -by Atlas. See the :ref:`` to learn how to create a free MongoDB cluster +by Atlas. See the :ref:`` to learn how to create a free MongoDB cluster and load this sample data. Delete Operations diff --git a/source/fundamentals/crud/write-operations/insert.txt b/source/fundamentals/crud/write-operations/insert.txt index be425c41..3ead0ef9 100644 --- a/source/fundamentals/crud/write-operations/insert.txt +++ b/source/fundamentals/crud/write-operations/insert.txt @@ -71,7 +71,7 @@ classes as models: .. include:: /includes/convention-pack-note.rst This collection is from the :atlas:`sample datasets ` provided -by Atlas. See the :ref:`` to learn how to create a free MongoDB cluster +by Atlas. See the :ref:`` to learn how to create a free MongoDB cluster and load this sample data. The ``_id`` Field diff --git a/source/fundamentals/databases-collections/run-command.txt b/source/fundamentals/databases-collections/run-command.txt index fbf020a8..f1c936ce 100644 --- a/source/fundamentals/databases-collections/run-command.txt +++ b/source/fundamentals/databases-collections/run-command.txt @@ -45,7 +45,7 @@ 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:``. +free MongoDB Atlas cluster and load the sample datasets, see the :ref:``. Execute a Command diff --git a/source/fundamentals/geo.txt b/source/fundamentals/geo.txt index 951e3246..d5a91551 100644 --- a/source/fundamentals/geo.txt +++ b/source/fundamentals/geo.txt @@ -187,7 +187,7 @@ Examples -------- The following examples uses the MongoDB Atlas sample dataset. To obtain this sample -dataset, see :ref:`csharp-quickstart`. +dataset, see :ref:`csharp-get-started`. The examples use the ``theaters`` collection in the ``sample_mflix`` database from the sample dataset. The ``theaters`` collection contains a ``2dsphere`` index diff --git a/source/fundamentals/indexes.txt b/source/fundamentals/indexes.txt index a2542b3c..01643254 100644 --- a/source/fundamentals/indexes.txt +++ b/source/fundamentals/indexes.txt @@ -77,7 +77,7 @@ and provide sample code for creating each index type. These example uses the ``sample_mflix.movies`` and ``sample_mflix.theaters`` collections from the :atlas:`Atlas sample datasets `. To learn how to create a - free MongoDB Atlas cluster and load the sample datasets, see :ref:`csharp-quickstart`. + free MongoDB Atlas cluster and load the sample datasets, see :ref:`csharp-get-started`. Single Field Indexes ~~~~~~~~~~~~~~~~~~~~ diff --git a/source/fundamentals/linq.txt b/source/fundamentals/linq.txt index 1831c7a5..2e72709d 100644 --- a/source/fundamentals/linq.txt +++ b/source/fundamentals/linq.txt @@ -36,7 +36,7 @@ The {+driver-short+} automatically translates LINQ queries into The examples in this guide use the ``restaurants`` collection in the ``sample_restaurants`` database provided in the :atlas:`Atlas sample datasets `. To learn how to create a free MongoDB Atlas cluster and load the sample datasets, -see the :ref:``. +see the :ref:``. The following ``Restaurant``, ``Address`` and ``GradeEntry`` classes model the documents in this collection: @@ -635,7 +635,7 @@ defined Atlas Vector Search index before you can perform a vector search on your .. tip:: - To obtain the sample dataset used in the following example, see :ref:`csharp-quickstart`. + To obtain the sample dataset used in the following example, see :ref:`csharp-get-started`. To create the sample Atlas Vector Search index used in the following example, see :atlas:`Create an Atlas Vector Search Index ` in the Atlas manual. diff --git a/source/fundamentals/odata.txt b/source/fundamentals/odata.txt index 7154b581..ede2c4cd 100644 --- a/source/fundamentals/odata.txt +++ b/source/fundamentals/odata.txt @@ -32,7 +32,7 @@ Sample Data This tutorial uses 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:``. +free MongoDB Atlas cluster and load the sample datasets, see the :ref:``. Tutorial -------- diff --git a/source/get-started.txt b/source/get-started.txt new file mode 100644 index 00000000..bab7ee64 --- /dev/null +++ b/source/get-started.txt @@ -0,0 +1,44 @@ +.. _csharp-get-started: + +=================================== +Get Started with the {+driver-short+} +=================================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: tutorial + +.. meta:: + :description: Learn how to create an app to connect to MongoDB deployment by using the .NET/C# driver. + :keywords: quick start, tutorial, basics + +.. toctree:: + + Download the Driver + Deploy a Cluster + Create a Connection String + Run a Sample Query + +Overview +-------- + +The {+driver-short+} is a NuGet package that you can use to connect +to and communicate with MongoDB. This guide shows you how to create an +application that uses the {+driver-short+} to connect to a MongoDB cluster hosted on +MongoDB Atlas. + +.. tip:: + + MongoDB Atlas is a fully managed cloud database service that hosts your MongoDB + deployments. You can create your own free (no credit card required) MongoDB Atlas + deployment by following the steps in this guide. + +Follow this guide to connect a sample {+language+} application to a MongoDB Atlas +deployment. If you prefer to connect to MongoDB using a different driver or +programming language, see our :driver:`list of official drivers <>`. diff --git a/source/get-started/create-connection-string.txt b/source/get-started/create-connection-string.txt new file mode 100644 index 00000000..1a3524c5 --- /dev/null +++ b/source/get-started/create-connection-string.txt @@ -0,0 +1,86 @@ +.. _csharp-get-started-connection-string: + +========================== +Create a Connection String +========================== + +You can connect to your MongoDB deployment by providing a +**connection URI**, also called a *connection string*, which +instructs the driver on how to connect to a MongoDB deployment +and how to behave while connected. + +The connection string includes the hostname or IP address and +port of your deployment, the authentication mechanism, user credentials +when applicable, and connection options. + +.. tip:: + + To connect to a self-managed (non-Atlas) deployment, see + :ref:`csharp-connect-to-mongodb`. + +.. procedure:: + :style: connected + + .. step:: Find your MongoDB Atlas Connection String + + To retrieve your connection string for the deployment that + you created in the :ref:`previous step `, + log into your Atlas account and navigate to the + :guilabel:`Database` section and click the :guilabel:`Connect` button + for your new deployment. + + .. figure:: /includes/figures/atlas_connection_select_cluster.png + :alt: The connect button in the clusters section of the Atlas UI + + Proceed to the :guilabel:`Connect your application` section and select + "C# / .NET" from the :guilabel:`Driver` selection menu and the version + that best matches the version you installed from the :guilabel:`Version` + selection menu. + + Select the :guilabel:`Password (SCRAM)` authentication mechanism. + + Deselect the :guilabel:`Include full driver code example` option to view + the connection string. + + .. step:: Copy your Connection String + + Click the button on the right of the connection string to copy it to + your clipboard as shown in the following screenshot: + + .. figure:: /includes/figures/atlas_connection_copy_string.png + :alt: The connection string copy button in the Atlas UI + + .. step:: Update the Placeholders + + Paste this connection string into a file in your preferred text editor + and replace the ```` and ```` placeholders with + your database user's username and password. + + Save this file to a safe location for use in the next step. + + .. step:: Set an Environment Variable + + In your shell, run the following code to save your MongoDB + :ref:`connection string ` to an + environment variable. Replace ```` with the connection + string that you saved to a file in the previous step. + + .. code-block:: bash + + export MONGODB_URI="" + + .. note:: PowerShell + + If you're using Microsoft PowerShell, run the following command instead: + + .. code-block:: bash + + set MONGODB_URI="" + + Storing your credentials in an environment variable is safer than hardcoding them + in your source code. + +After completing these steps, you have a connection string that +contains your database username and password. + +.. include:: /includes/get-started/quickstart-troubleshoot.rst \ No newline at end of file diff --git a/source/get-started/deploy-cluster.txt b/source/get-started/deploy-cluster.txt new file mode 100644 index 00000000..f3849975 --- /dev/null +++ b/source/get-started/deploy-cluster.txt @@ -0,0 +1,29 @@ +.. _csharp-get-started-deploy-cluster: + +============================== +Deploy a MongoDB Atlas Cluster +============================== + +You can create a free tier MongoDB deployment on MongoDB Atlas +to store and manage your data. MongoDB Atlas hosts and manages +your MongoDB database in the cloud. + +.. procedure:: + :style: connected + + .. step:: Create a Free MongoDB Deployment on Atlas + + Complete the :atlas:`Get Started with Atlas ` + guide to set up a new Atlas account and load sample data into a new free + tier MongoDB deployment. + + .. step:: Save your Credentials + + After you create your database user, save that user's + username and password to a safe location for use in an upcoming step. + +After you complete these steps, you have a new free tier MongoDB +deployment on Atlas, database user credentials, and sample data loaded +in your database. + +.. include:: /includes/get-started/quickstart-troubleshoot.rst \ No newline at end of file diff --git a/source/get-started/download-driver.txt b/source/get-started/download-driver.txt new file mode 100644 index 00000000..66aebe51 --- /dev/null +++ b/source/get-started/download-driver.txt @@ -0,0 +1,34 @@ +.. _csharp-get-started-download-driver: + +=========================== +Download the {+driver-short+} +=========================== + +.. procedure:: + :style: connected + + .. step:: Create a Project Directory + + In your shell, run the following commands to create a + directory called ``csharp-quickstart`` and initialize a {+framework+} project for + a new console application: + + .. code-block:: bash + + mkdir csharp-quickstart + cd csharp-quickstart + dotnet new console + + .. step:: Install the {+driver-short+} + + Run the following command to install the current version of the {+driver-short+} + as a dependency of your project: + + .. code-block:: bash + + dotnet add package MongoDB.Driver + +After you complete these steps, you have a new {+framework+} project +and the {+driver-short+} installed. + +.. include:: /includes/get-started/quickstart-troubleshoot.rst \ No newline at end of file diff --git a/source/get-started/run-sample-query.txt b/source/get-started/run-sample-query.txt new file mode 100644 index 00000000..0a79e9d3 --- /dev/null +++ b/source/get-started/run-sample-query.txt @@ -0,0 +1,49 @@ +.. _csharp-get-started-run-sample-query: + +================== +Run a Sample Query +================== + +.. procedure:: + :style: connected + + .. step:: Create your {+lang-framework+} Application + + Copy and paste the following code into the ``Program.cs`` file in your application: + + .. literalinclude:: /includes/quick-start/Program.cs + :language: csharp + :dedent: + + .. step:: Run your Application + + In your shell, run the following command to start this application: + + .. code-block:: sh + + dotnet run csharp-quickstart.csproj + + The output includes details of the retrieved movie document: + + .. code-block:: none + + { + _id: ..., + plot: 'A young man is accidentally sent 30 years into the past...', + genres: [ 'Adventure', 'Comedy', 'Sci-Fi' ], + ... + title: 'Back to the Future', + ... + } + + .. tip:: + + If you encounter an error or see no output, ensure that you specified the + proper connection string, and that you loaded the + sample data. + +After you complete these steps, you have a working application that +uses the driver to connect to your MongoDB deployment, runs a query on +the sample data, and prints out the result. + +.. include:: /includes/get-started/quickstart-troubleshoot.rst diff --git a/source/includes/atlas-sample-data.rst b/source/includes/atlas-sample-data.rst index 46d24320..bc1588a1 100644 --- a/source/includes/atlas-sample-data.rst +++ b/source/includes/atlas-sample-data.rst @@ -24,5 +24,5 @@ classes as models: .. include:: /includes/convention-pack-note.rst This collection is from the :atlas:`sample datasets ` provided -by Atlas. See the :ref:`` to learn how to create a free MongoDB cluster +by Atlas. See the :ref:`` to learn how to create a free MongoDB cluster and load this sample data. \ No newline at end of file diff --git a/source/includes/figures/atlas_connection_copy_string.png b/source/includes/figures/atlas_connection_copy_string.png new file mode 100644 index 0000000000000000000000000000000000000000..22f1a910c4dc54d7c1015f993c3b57a621b50e75 GIT binary patch literal 227623 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 uine zq-c~hlcmex2PeC}pk9!S() z1spwQTqPE8+Xl%mbPOr)H?)cmdwcCHhN;tn0`9q=)HqMoN%c+9TY?FgZ`?AV6gxmpA3k+3o$ zIHdW(rk5vGW{X@k-LUcbd0-(DbG_SUQeLtb@Icx72^62jJjT+D_-1hz(&k$YvV~)V zr)wTra?K&HTy$OOF|F&A@>dcS`jMUpo;iqSRMYAomJsaao00i!<>TFX_7UzeOJdoL zmX!MUdx@{b1X$P{Z*|(&j0oLJ*Vey088vU9jhG0q7@s#Vt8-8I6_DCkq-m${ zK5I$F3xqIZv>D>DHE>}qnkgugC9gd`;A$6f4j+tOWQGG9wWX9fH+>f{xPGLkoA>!nw@7!spwVK(zBh`bUxL)9? zR8*6^PpjpFlyjTT86Dmcp3kRXYoR$*I(!FLDy#|UD@xw8TlY1g&#qo&O{GC{&Ef4k zvOjg~ua2b$qA^w#GcB2cBfHXVi(}ntcsZ~(;@;88^5RRr4WnV1oZE*gxcnilumGoq za`fj(Px4r&=YUh>ev63t+W~#zkG{P=Yk(Hwslyc%GEdMK;;%1{^oLCbEIB=LyKa|Xn$lvW(ef68En4U1 z78=UDT|a?$dGlA^%0$;tpB22kCk_ObTC3p3*Iv`w#AkjxacdtohNs5xS|aC!30ND!6524Vqp-rl&?Bu^E!vx zh*Wa&HYWekC_d!@<9Za>=yxO8khx2Dm?YmC_dF0Yu$o}1coy^vhbn*{(86B0t z&*m#$xUt6OlltM|={TFzk)8^O^-CGjTgtUpax!cQ@i?#B^$4EXgE5~>g;}L!woc#= z_bZx+sd`EHfYQJgoa21CL+dWj19CYQ3(|MOtB|Ct>mt$M8MCNNiZ6au()Ri?S?XuK z>!bx*7+io7(aWbast|kNe-P_FMmpB<8n(X)4|yBM3AbOn3*KefBX#rjp0g%UyF|d_ zZxea;p5lxEmQ6q*b=uKKh0#U~`^bUntCf>zcNM3*;fA-op{QiQ7yFtcjB6}ZC23@CY9 z(N}lgmkcy*3{Fpj9Ra?|`c>KJS3N$zF_NEtocJ2L?KNL?$1WH14!0td!+m|*qgRtl z#eqCNw%7c;)X#JSGMM`A)6ha%BG<~Ger2=uWSg;NUI~9V10U-Km1%9m#~n}r?^|p<7)CG| zzowV{JyzLVyqfxPX2Z$PBsKjCfcyvpGd!1>yCqU7*NXSfaA1{wLA7mY~{qkQ&}$|LUA2OpP4nIVs>Re@I`59%UG>BB;DnGiDb zzF4TdenG;lX;rG0*G^x-+rwMj$8#<+pw6h#sT-+@yD7V`!<0IUsdIBRVteE|bcf;q zl#7pZ`Kz*UHM%M5mCOg~j@J!8|5T1uF*79#c8=cadv^gDlt%GRF zDTjV9sZ_W#YxGv9!I8$=kql1oi{&IU79tTP?Ou49&aKS&Nq(kGll<5LF~w>S6;sfB zse(LrcYHdF>HCi zawf_@#0>f?ZFGp7#6#!FX3b;Tf;VfFr=BOsv9?ye~4T~E}Y<6KJDj0mNvsKlnV=X_eoW(=hMn2y*Q~i zwII2w8(aN4L-1uK(y#4Y%BJ1& z*KEo>aWP9pnW<6%jk(uma43NeK^-^fMopt`3V04> zVz?hbIir1kv^;{}PICbW z4sNR4dyu&*Bf-m&l877Q4g_<_JUpxLF{qv;rCy0%X087EDqCn-M8SeN+|^OZrR;b! zDW(06(%t@iW$eabfK~%U?)gCT#!G?sO6NgR12-*ksix8{CVYyZ6umkh*OL8S7OT|u z@E8eZABFac$VDOGDLAGA3^3d;@($9pi1P`%)is5T z@AMp8c)Z(8ztS2DmOU(sG^_~RsasFdFN;%(EMvAp+$do-gmFgR$XV05!|iCrIih|* z=zSJ=rfz=k$eqZzuh4IEw<=KHK3l+wS>-79e*0`=nqza|K9^@AuQIAgEhwd-^8Dw~ zC0u*x<-OHA={%|QGs@b1Pd^29cby8-)J5`dzEo%_1>9lrC%L(eMcVS4!F?@Q><|0ge0S_FSB3*$tretBLJZ#jg|^91-x0y?VqDLY~~3 z{fk%-c{{B4WO8VhwDho|(r6SF{R1v@o|5ShCYt%&nlBf%mCi*;S%n2Wh^X(ld%6@y z?yWfIqj1dIBjx%7^l`AuzlG8`o)Dp6m=oe>HLjeC&)o=>3$+^!=S2Ev98kaeXOxX>YUbm{XxbC;TTldn< z9J4YLaf&tg)~93=@r!DxjMC++56r-xHau+R>VjS2DnFRkemjw9*qO2*M_O1bb$+)= zSi=b*>Z5f0I<1HmCkvx}`lG>g$Bd6BUGI4%P@oX79mJU-&oKdJH807qSf|feAau6O zuUz>-=WMOTf0gh!D++-2Vu{8{WO=wp#(qU3wL)Uz)Y60_=@- z1y{Rm09FshBFaCY#SIZ>Pe1v*+i0Jqn%N9-n&sRdqylqeWZl}*fK_hi9n1>KbG70g ztrB)x2z7^uWY77vihK64Mzsa0kfwTx+N&dtw{LrYfaH5;C=uC9b8RyZ`pj2fMHu1K5byR>HW;(p z&usImWO|LiwYM7OfCUO6I^Qc9-mC3qt=3`?wHnmo_MUi{xjI@;+r`CvXf!I}!UrKI z$QDH&AZ}Spj^fX9`tRUTN%Mwyx}LX^XNW*9es^n-{u(99!;oBZ%Iaq zMkzX3iegE58|MV>DSvNp-2`m&KFG}X(IMMmbQbbb$jYA}1d>lI(4n&az4P@1dp*sM zm*Ovpy~}-b$*ks`w9R|X*SftakAZhq31x=JqJ``?8x@T}|! z@DQ57L}xE=Y@sl)3dnrU$XfWM$-RlVz=a`tkUr~CzLJJc>*d_@upzXqB0zBv-Mr}- z;4|N1)bvysv}-&c+>f5A!K`_2I9i`rJtGDj9LU(7dg`@(-Zh1c`7H41-Qdz0n$s6c zDMu)w*g0o&I3J8?aSoTaWQVww6lK!lVR#Up7_5t$^pm1G^>Ht(YMALbu0KRQ{`jzsFIaRkrVW-aAe{-|gs>x{pcEYsk|uzcTnBIR6oqf@7< z-7d;=>9jrHH#KYFqsDCFBQdd@M_hCI71{Ef1m*iJXF|vX22-h~&8T4Z37~AS;oCG1 zqh%$h44Sh!a=6_An|Q0d!q2BrIdAVvxfY&xD0K?l=N_zy&=(W-)=q5_`feorgA{zd z2|DETwZ2kWQJHr}PIRvFpjwMh604feh>K#sHNUwmTB5W zG~uyGwUCu_-9nakq*og&R$Jyawbv}jEqsBC?wF$T2fb*0U4dfssGjN1QKw^TmcmM4 zk?+%s%M%`YozTQa1*{0ER&VHzVt2~{+T5~9N$UP4g3It?psr3}LV$&eQhGLnZ-Nf9 z8G_nY^kI2+TdtgjjlP#muD@MLjL$o6yBnq>AaNJ-?uBY?>V;+m15#8b^W(xvGU-!K zKj_;V38fWpL0ysN!*cb2rz75aOLDzh=^{!#))!XPg*8`uH$A_d_imO4h3>O2>_7rU zPiODm`<6GE|AUT8L18K@KFOLrILgb??!>eY1*#4`aV;<~PE@4|`6=Gs zoQwWE;_kHXwvpLidH3{3nucI?l>+OnEB#Og0=4B=r8;+9?$7yv0M!UYIN$S=g7!G! z)BL&zbkaWc!v6S9-j%pl=yU771dVxRsYy%efE2J+9qHY=GSMSddGGC%il39xoUc=| zYfT4;%#(MLebun*7&23=66RSG&r4n9)&B66kW}!234L?KLlPcG2X=sIu zb%HyBovCpT9lpdSREfXaZSD6i^(J08%Q(B}pZp`3a1~-Sy97I|fcFELXBi*fczjJl zYD?5Ni?>jg9eZmKqyKau46A?60efJ8c-JYRY^`MlbPeY-nb4y3_DJt?-%zZvbU(zQ z$}EudhU1(CZw2!Bnmnf;_&i#QvsQfQ?P|8#bxL=m(Lo_36v0xLI!9v&bTb5Z9>d=e z#_tWMYY{WH7Pn8<2%umBCanxwPicY78BrFn0|_gC1D|kW)-A8vJ*k^yN^HURhR^d= z%Yoo?cai2dekubq@8%Ce%LPKfi9j9VAxYQN^as@{|&|A4^hSeAmc_tt2?;+4Neu}E6T}w)327l}U@6D9*!)Anwd!6Z6Z(OBu+&S#;n4UA z-p7;(bGmsf30i*O7t5N(FTM)Nhs*BWQ2fqLPrZ4?Jy*=UwK6B)1A}Rtadq!se}jIc zYnJ6UGR43Kn)Su4tyu+KPHlOC#aFInLXPuz;JYnZ5oKN{&2(fg1~O3t`M7 zycf|17GEXiP|h(%*!fv?y`r>RG09wxpvD~!iTX9Kq_Be}38g#OD%nOI0ZhxJ3)k1D z8)gR*hI(yTxB4^7D+LUNVGjJWHvPx-`%bM~%u;Tks=Yj|tGQmvA}hEXan6;wW6Fq~ zBAJT&TqsA_#nZawD}}LJ#5n9Ei)&8kj89cnC;0+dh2@+@iTmkMVJnwS;O=fd5!rGe zu7P2AY!}c7%rE>Lj)P@tLG*m!irbUdag^?cd6UD+^rwE@TeL~~xe;&D^dTF~xAlgz zynx)4&HV(*ucgj$S{EUfcWk!qkyKwiHyj`zY5s*lCmr>vEaNDri68gg#V+ZUf43;> zPMy}`qRhJj(X2qMGNE}_8pTsLqx5A&dHUFLCd%>Y#6k<#JA>66}I^`mZK8Q2*jQnK;(K2D}SO08GHl&25f z6tH}A?)sPP0~0;9NKL)#65S$>0Y&+?C#HL_2aU&y7SYJ~1+pJsfuf^|Ry zm{>NMzt&NxkLZZc)R{Bz(w-)`2g}p;UsZp(j*~8wi?w*+~ zhtg8Rfj=j;4GBceLtgVn^Da+wf&z4-ykaQi!zO9xvqKCsV9_N3;kv}a52HRR!N9Pi zI!DK(j((1DRQ3yALzn?7bA68}jb%s-oW~xG@qggDWkyTaTIZj~kvrzE)^62!GcLia zHQevGSug;(;3Z`vq85!d8hJLwNN0a*0zXHUE23#0tq0bKhKiIfa z7@|8S28XIHV_S@KG8w*MxyOjuJ4BLw(41Z@B=Xbu|A-ahtebOaA=BZw6+x zG22?8RnKwLA#+JO^0GculUc@cfWBS(T2O|_#Aki-#wTieT76&zQSMq$_3&As@l#14 z0JWS{R+q4`b{|Ejm5*9mk@=z&c5-vI>t@4Hqn~B`K-@N@*!^5Ayskw(a3~4=h9w|@>n_P7z~d085m0l=DR?8^Nt+f|d|Ve(=+QhI1JW2u64hqis;S|JE6|JD4E)LG~c5pNj&Qy zpf+a_IVRV|#j(&nVz5n^OmAs&QrVQs4Em{vOd~<#5xp~~q>AyG8lZ3aWG@S27tJL0 zG)vYY10F~o-Kd?mb-Mk+Q)bIz%Ra}8iba>|b1r?q{XCU?#-7R_vYxf8zBRC)ntK;51$KX(yHn|d!KOU$Veoza& zbJcVt{VH6+4GIPZY}G~z_w9{IPvb9*dy#Pf*I+i0&d3kJo-1DBa3Ju6CksL{d9ZkL zgZa5&-n~>i{h@^_KUt&p?R7t$Zqa7vri%SP(QE^)+)wG2zstet7Yv)?uj@-zw)yFc z@1WFQ8TcLT+Dh-E{VLV`!RQMCmN}Y+n8qK;I0?&(sl0)E^?2Y;+o-yAoa58E1|8>b zFMU0B@>O4BCpQ->fLPtot98g^GC7IFC2QShpu7G3FC2-KT9*_Vb6_q zK9sCns#Dv-f|ahgl~jwmdiBny>(oewxQkHNZgjn1UY*t z+>2JW3`^RGIue=>yzOB9%3ryzVfjkQ1ny#my7gCHuGt|Fr*2B>lMkdGq@4lapj(F7 zjMKuZrSDP;!OKm5c^_}Fv^V2K?hoRycwEl`2=cXl2=hx}eiPhxex(m^s9yYp;R)Xw zR%bH!#4iHNyJxbfuRaju@!ZY$#SnJs`7Cg(B_mBUAj>j86}oXU*I{hih)OOgnlx} ze-cXr03>C@?Vq`ltMfCaxg=Ebw3a3-vtB4|UrJTw*MCM~z(xpWi?Rg}T;st_LlG(F z()sNVADdU$qm}E`x_h=)U%n{G;r1=r2*_eMEX<~^6Poj^mO;^RyxyU0(Bv5Z+BGtN zuuJLQN9(R$R)IPJ0$i_T&A_A`8=nlht6wo0&zH|Y9T#J;vKzF2a`kKwQZ1~8ouPB4C7rLH>KVWp;U-E^wZI-?;?J++J}~JZYxT_ z&ZNSNG3nvRda!)DuXkO0&b;L)lJrvKJ-EL}`(#xhq?RZp8VnEa9r)7pzFD$EGhJd+jJY-gqTt>2+Eq$iYi%(3NM zw-iqNEp2|Jr=l}QCt5@oAR|SSwlQfq)J<-Di$4?})cATsDuf)K7RnmTvc?BFmTfQ@ zU1OG(df0q~HlNQbCWUTB`W#9nH82fYk#cjRitUDaJGMgBct2tX;C!h=&HEqHeU9n# zgGLs-g3Q4hO_2*{^E`@7H&`((&?i@3uqeT9)&X6#+RsQC6^@uiimcUcT{H*E<_0um zAVoH}^Q{+gf={Vb{J@44*DI9Ph|!#LwV=}Hf^{*22R2h1YyL$cmce8f)XJe={SjWx z+pq&wyAP_jng!BwS>K2F;%(O*>;hU8q!>Ddld$#1#ue}A*_6Dgi=h^}%RiHi{WGhB za3V=NvZHOiB9cwhb7EOkpETt%bF%HrE2%B5sz=ej&LN7}Ni9ntfqbdqt#{B%L&AKi ze`_NFENqDAzg!+P?5+`=bxKx>57 zhkabBdTxt-n7`4wDGfuf0&@oguwb}0{hKuj$N$b;$<0#?J~_jgs}#)A2!v*=@+k*`y%*P~suGH*krJZt(mFOM zxR&@ye$p&$x}%AO*PdCblQ6w^jOu!w)5#uG{g0$7ORX(&6>^j-u^2Xa8Mb1uXNJ=!<<9QyH`o)a!;?-3-DL zanqr;QPb;A6_ts0*soY_>3r$Qtd8Omt8%DKyaT^=Lh9;ZEnAb1PuK-Oed^krZMyh6 z$Q$5dha?~6$XL+|)Vo}8l<+8uD0b$WHGzFuRzCRfeqK6J30GRrOQwX_cBW;eUEg*L zHzt~iI`8!7S=3(@r>eO4@A~GGin?1!tmhI(%BedrwW|OOa`kM*)rF#ZtGe4@OVH9B z-#Wgb3ju)5v*MSu6vOk=l}EEZ4vU|oV@=^HT+x*C-)$-1^(a!e(EKV)ZM3^OHS;A) z<6FIz37A_K9n=|p7aW7=L$Q}X^2sxx@J!i+>RG-F7A0~6Gi=+D+Yj&Uy6|1n@$IHa-9)I}5l%C$Z;d`=#id-z67+S!kN?(1vW$ zX<-rz0+{1Z1SXX)X=)sN)aqT93ACRJ*$();cby|48_L$@&9`u+0!w-Zk|sDyyvnxb zdlK@6cX~1F16Q0-re`HQI_Fuqe_!#UQ@y@?Hy7Y3pru=zwyTT&{9T~KUuF&SWh^Z_ z4R8auA8afE%ygTTa=QbnX4ks)#|Hok#TmFpqg%ze_}iAWBlF_-vZ#{yp2g%Sr3O!@ zksin&ROzrW1Ry)=k}^P>eiaN?=wHO^Z$%SD{II(?DHz`!+3*{KqqhxNKF+m!r7+oS z-qBRe`bx*e6C5!I>AlE(8^smSnOAG@%$OX@o=4(Zq$vw;e1s?5Y^t`uKNKRpp8q~y zp2dsEy^U@fl_F`$y!?pdZ%xulm-^EE<_sJ}FC~a;ni6ka(X3cBr1q9NhhAg|hJ(&1 zKP!6H;alHY9vR#_C|llp-g~?BWdUOFqnFGOP3n^Wh-f{O%a6EFQ3n|*vP&Mlm1p1u zp3bdiFh>?8O`j5rJow!Et^+TC=to)<=DkEoxU;4%*Az$0cC{IW?j4Lz#HCMCFi^(i^ z*?h8as_5zUyq>Y63yay~=9@ROkXKH$3!ta5m19yOhHdrtQp0&hgVK|%^Kd=Oh*Y!^ zeNulvCD%uAJ%x**RO{&O(UJ{nDM|5a|?YG>9Uc6!9vpeE^AYxa9WMtINB($U%;?C5_k$^)YUs?sZ zEZ;k8EzvNHNSoBzgTfzC5wuV#N>3Tt!sLD_53j336lkB zcV2w^mH$x@9p!baLE?|Aaa-SWK50*>N<||VxQ^Am(Mv??eBKaDg%yhEUj8UV+M8>J zC{O`Fy!%3}FwwIp<0vvj&_T0cygqR4tTICpT6$T0#LeeLgvw1*>51()5-Y$kUdS8W zX`JG}yxnXqjA409+=W$ZA&0AcXyMO1fuliyIv2lrY5P!SXL!e*V@kRAlZ^zMVg^^D z>d8*tSPMh%jGFS6;&#!$5+7i+EDQK+R5FcxNjw{hww<2 z3Tu{#v=@%+2zMw?v-RRB>Vxh^nrn_;X9^BSKJj_$dZ%J0C-`tDH+^ZvL0pBVkSr9- z6sd&RKXjQ!>=-MrK|@2!H|e>Nhkp(+|Q}L`pnVvL}qg=c$uLN0Uo|n?@cTy~?$cAz-q>qk4FTEX_X;kdS$~S(T zlXGhZbHvttL46FRVsx~(dfA9_EjSAsYmy%1mYdE4I&IJ=V7VX7Og!`N<}>R@Us33F zG#&&Fw{+|dwk#EN1q0b&-Y~t3bh-~hf(tAb%fsPNr=X`%uvx?-o`P>_i4=p9%ina% zM#hscd_ftMAFjny@|5+{9Kh!-7DCa5*`6mgtvOG?AN!tm>obeV)1g%&%!V?JECz|h zp@Z9$;D|}ssFfKb_Wufv1XnvVjzo1z@?6Yq?~L|VBNS6zE$>y+QEXW4Qa3MGe&6u` z!#;bLT==z!-F(_yH6=UyOwYKGt9h|~5`f9-G15b$WVCS!GjWtv6F ze2wPxjIV6?9aEW!Iwp@+9X8Y)@TxL_5QnNYophq>T_#=}A2~Y1ZjoV&%^t|TksceI zWxLnN>My*SFoVPZ97jD&@rIion7nx|jiLI*zBmw?p(U{lZV#)a#f8K%&vQTkx)pv=7gj7vXoPSrR= zKsTCFDZ;3qcWV@wWPB19v67^}b-} zK$Ipg|5{OXk(OGYmOU)&yZG-n53eyEg?WkuC3Hz-{kzhuhrf!*e4dN^E^j%1X?UR@ zQ)Z6Zem<1H{c$Iw%IRN6=YQ3LiH&bC$`;)rU1wL&>$J(R2fKw)aeH1=%NSY`Pw14YV zO)1j+*Y!pR(VV@M7Sx@_^>3aU`15O<7^s`Y0EhW}i|pHjP!EjE7E=>NAtLSEgJ zn|k`YDD&S{=<(y}PSe>SZx?j^W0C(=8fSWqQqT7BoV4NZvgLnQ3)rJXA*s{gfuh_0 z{M0|As9d6yRPikm^{>U#{jiOrr5y}7DsQ-xMe@f$z z8UII1{^4%^Ba;7!V~bBa;7bp_&59k+5b3neM~ErvS>7 z#(>@u1B^=+pApR*G@Vup-I>94h9%0k(&cabBhu@B{Y5n~B-fHacDE0=j*S%0@%n$0YqK zw~|*5d#nMSWuv8fK~5%^&kYXEH#kEm*{?1^o#dFMuKH7($^}#?=0(^Tu{F3_Mhg751ElVF0tfSA=Rl_o`B7OIL5By*0xOw;R?H0L2(dvQ; z`I8$n-bv}6c%RE<;QcLV*^pY!&&g@m8JF#ZynPqghn1!LeVTt*%bxnPe!}#Vc9)e; z0jo1vBTL&*4CJvdn-t?F@@IGE;VN^ZS7`c7Sse5F#GKD`qt~~+Cq3dJZ^Yd$CV0Fc zWp|&ZTV7KCk}EF}Ot?J8!_r>0wXwF99FCThvV3Va8FbRk9WuxCU80WP2<@O#SX>U+;eO!D zEerl991lmpi;1$hshCJ}bJZ60D&nM_=W&0<^yM{{DxbN4)be(E!`Sq&IBkhS;xp*K z+KEk^O3Ych8|>ZZBh6+6`ZES5Ds|`GR`^fmKdMh%5jsg@9<1QT|0G`tybI z9dlS#aZMDwdBlCOxA}Ktvi~XZkiZK!JVIXO0Tk`*&T%>-$)9lytaChV3tx{9G=$%# z3a{YgYvJnKZsiOZ&@5Ak@s52_+n*PQ!tN21wzsUkgN zvg+p38hX<48lS`pVCfJjFc!7aJzt_udZi`aAEmwG$jw+N8bxl?Tk@z4))7q~Kk`j= zpIE5_9DCHQB#K`jIWM)fDF5L!2whr2=^*ugmtIk zFHNxvNc7dK21+gLYR8eCrjR?G#)l~-VVjkNJopp%f?Kjb%Gn9ch34il7g7)fRLIwZ zTu!VuQ0q+d{xK~!@QfnJi?0O&gS=Wt*j+*g@bi<0Xmysp5zr3|wym5!XuQt1H8TM%E zWQb9G&3`s^_b)h&6pQ?KP0UluYZPa?C$JghLp(;>>Cl8LSTPmr)MebHKsXSadIUYL=>o}Y--4O?BJ43IYOBq=-RiJb74at~usdqrC4srfJ3rHpIp$`QWa0?9cG> zFM7OmLS@@YkraYje=mY?kCDh`2k)AILFSLm=b}_2Tl2Ncwc~ojuaI0~nKeZZx^3Pc z(>n;m21Fsz>!x|)s$J zF4VDM^Ol8V8{2l@INLNYqHdy>-QLN-b4Fohy@U`e2~wJtl&PIDBi!__UU@ONm9Hrl z0*mn%zKqKuFHL^%uH=3rCU%^I^vo;Sr_Uu|61}IZ2HSizdh_P^>7?G~p}l5mc%3t@ zdCGowofUSAtn@hiI$KK8PNj|1iF@(^YezSlcbRRum4vHEZ_^vha^JIyiK(-1=ZM7! z3Ni3H+7mgdeN*)hso8(kq=-IFTJHCQZy3D!A=rrm-1M#xTZIu^coSI+q~Ew5C%5oW zr1v`t0}9nM+o^~*1d!Zk)WmsPMDmffux%EGSRcN&JL0Fn+4Cg#e;33-!t!K@@OMuw zsg(~k6YEDuC$|pVWx_g#%qQ3BKtYMcC+l&vti~KuRUt%_ljHu!){XsouFEQA_4X<6 z){&E*TX*({@j`7_ys)0Vt#Vi~dPX*_o^O!PDv47H$L~pe^)dovqWLqRF$!*PHy;;$ zbbeKx`&J8LBC$xGqF)IO%~N}zqjBI|?^-4$S^sVSseac;uC*kae+)9EPK(RC79P_(i2oUW?VByjRf z(Dr3~fHj3S-pQgEiW{i0>@?(+4JEnXJXm1;vL3pzHJ>?-SFwBWn(X$8Q`>4VwgH!X z8s`{ZnNU?)t<}gPVmn>pH`=5PvDf8CpNPgf+H<<6egEo|ClIQ*_4qe61T(P4#3or| zm{A|QIb)ce&)ms{(H0k;o?!fbVyxF4Ulqp%|)a}Sd#PSQ6G0!*x@qPt&CIzbRm z_kJGM^FE0<2-RLmVgZ4!oSb&r32~ZA8uzBHjwNRE?AP zCVmRAA4%%1)s=3dXjvj`RHAVEXVl@#hXz^?%+52yz?Yw3COKSDy-R&kn+6$7g;e2+ z6`$A|bjHR@ah_^>siY_TJQ6D!EVe!+Y#O@gi_ES%hr2y!hN|XEe@{iJo~OQ=zM9Ip zYUN8CcV-TOEM3%~1@~@OzUGo3^c(E2Fw&t;>#f@>1woK^_8LHU*VU0ev4h5bj50f} zGM6)Svw_g4oaB@-Vl_G1&78bM`@!stun7|0-4Vbx1k2qe%IM?*K6~yqb+BxW$vqGPg z;qjeiS+His$pBB)W18_oxd>y@q9(*TV!rh)jcx+;?X|40aFp%YEybd2>sQ*~JqP2Z zaM1ZK?ux}Q!ur`QST?6^qKLAN>4FLPw$jk0nY8UyMlh;p2qqWf3Wuf8U+Qt%v~`wDhfvpseS5m=UW+-xWR5j({fl1x38NL`ZC$8Wl_@=>{DDpZ=4B_kv&h6 zQy@f&hRDoKADmrv)~ar^+>fmf=8JmWPril=_K#D$7)h8u5Eqg~Ny`j5Jk4+Sq1jyU zAlrlPWVIFzhl$^|k(v?XckuS3?md$6{XmoT&A}~hh`}Gn)_Bt8?H2p1X2pO`BDz1d zcr%eCy*b_a`R0vVMINY>{R-;LPXQNnwFn3d=3&od;vi_PJXwB#<3XL-v5c?MsOg(O z4CGnrt4k!&fpVeB3r@tC^%GCl9uzVb1va7haK1(xU_8LJ`Uyy+M=6oz@OUB&;h|HI zJ*e1Sy}J?ye4fMC&GC~=#>Ns@OjOSE@ zB2RYm=(~Myy2-1ddOTOGSf|fItNSYDuyyX1AN_}-B((tydskGLD_&K>WR&`fm)u(K zL!f?lX|5%zs|8rjrI|SC-d=9FOS66_^ZwEMQ}aj~weA!TsT;n#(~8BD+E?=gIN!vM zi{=IPdw0bt)`H29z5qPaa7SLlPW#j-dQt7^{jb{%jBLZzb{vy;3J?0fqLfkkrt`Uu zRXe9Z%I**js2@iOxb4GQ=Ut|D53A7zf-*ABnV(9R1^}E@#Kzdv_Ts!Unw`~w3G36$ zxb0+{#010ZcuVb0%r%?ice0UoCg?Yf66P#t_m@FX&4(os*{G-es;|9HJhHILFYTct{WqBu(M@tABO)L zwD4DD(#Fm2=GDuG76$JE_ItA+kAQMa8b|ozrb4uD@O@2E+rv}llK#~8Iz{fL?o7VN zN|2Yo%+-qJ_RK=~txCpp$QGP@71c7H(At8ntO#1XTq)QrTEMSCju*^iiqTYe_)8co z8$ima=Mb}o>Xqj{uS-3Y+@^=eJvu*he$)!bR?Up6*tqMr5M=ir!5q}yZTbLb^KXdj zUz6Q^ZHJa(Yspk9G{aT_@Mk%{3 z;TkD^E*nE}P4MAq_vULR8d}L3g=au!9nGLh4Oz)H0d|8u8|nr9G5qrn zth+KhDlD6qsn(CuMi?-;$9XAFnaQGCApXB9yvjTjSXl(ukwQ(mJA>BtcduL3;-AYT z!dg)YI43F=G7;t{qIpD?$sE^0y7XR%xD)M*LkusOv13E*5uxuNf~$YEm56{cUIvp( zHiwG^mkgFO1v`j{+b(K$K|s=>OI-2!JU@j;D4CVChRV9J8l6lQ-h&vBKV1=^MPz7j z-x6G1%8FKnezUCZ`O@8oFpWu(mUN~_8oE_u71rmOG&?(4ZDY3n^w?h!l_6K>u%5!E zUl*m1<+rW%tsv_imLHk0Y`J64Ooc^`3n&Rml#TlI|p_s8R zw$DP(6+#*8F6}`3>l%i70Hf7Ao^h2t`p*Yi5zQWv)Xy$?(popULRwC%?bwADvpeIa z;65j7w&x?&TH_xu*{E4X@H&TgbTXIKy~)S@_{Vk&`i&jkju?=Q&HM2FrS;*maxwUd zlu1m(_i*Tjbd;bgQv&dde~?6)=^HGWgGOUdRk`=(U>k;7=8|18@-L(7?3UtSaNMdRy#1 z8=}laFU736!VrqUE7q)vC-9$pyC=6uf!D-G#zI+CCqjeECTVIUoLWXGA%qY1!o3t0RsO zhUQtfKr&urX$9+ok}bR1j0hdALvJdiW4};c;^oE1P-_YJ!1B{K7jI}5)btI)W@qRC z<+q|<6DusUd$MEk#_b)2+D1wYr*8I@rmY zIh%x;|BTqdY)$n*vO85oj=GOeTfnrrY;0WyF}Thnl|6$>{G)UI*AeHAm?M$BNl$Ml zs&xmLYbe7E9DT9(6@(566CR)uZWxI@FLjZu3?;NSeNilZ`~b0_Aae;gc_48b9bKR2 zwFm}@iXh_B0MojV)6Q6lBb({t0xci<1F;+y?NHVg@+nEls?X#=Ez%Sx4~k%?lLCtO z4}^|BVCxM6{peeM4bZEY_-lK}eYCqgoiJX75fF^Ujw`bseawe`6;6#um zjd z{UCWvO2Y{vJ}iFxsz7V=#|QD4Cx?&+^bZKLWRw9RnCXW;qZKvt!2nrcMD1+BN5#tY zz~v-`w`{*Egql6_6Unz}C`el7V&=u-rL>K!Z4aEWVR_nZGR6Ix6n2%EQcla&F^(jH*e~~+V+Vr;KPv`g&qGCxix2w0qngv1Knss7e?<^O zlNHQKPIKwr5%nxE$B|vovAHylQ9Z|TNP3G(hgS#uRls?QT4G`yFYz6?uyZZzuo zecqfK^&-UwmQ&%_wm`gurX2@aQD()DZTb=#-A#aT8aFcLP;y0)?MezO}R`Z-A zhsDtQmgtlxOl53n$^Sw#8TrA}DMcBL(&^cia{;3&rT5T;dFaPI2_Y0Vv|9V_#>&H& z9Coe82VvAChtyaDv*HlXU;>7m%Qd8B&CeyLeewJE?|6ga^Y^mI2^O;UOP8e%#?*`p zbE7#0-I=eD91>i^s3XWop$TW5IdBi8)2ZnWMym@8 zF8czcWEB@xYo|JItfnf(9<4Ts$QFFC&H`Ngq%JZdmL5nj4cyV!4 zV=Zzw1?{%^g8n-S{g*=JKlU>9)#a11J@3ajm3YZ>wvN6zn$u>)Y|KKtxev^c6PRmK zleG4_@&g-fK=&?g_UYS*`7!;v1Pxi5GoCw^w>7qI=>M)5OYrSfR^=JCtI1Az6H5S# zX5Pe!vs0Qu{xO^F=r>xr=>QttA4O5U!RAI@cVeM8^0({pd__@qas&_r>Q#)*q-NO( zY2d6D(Yl?TES9B-&qOJWs4wM02lH913>E6HDKkP*g8IkrH|)a6f|p1y)>%I%{dO$t zM}jTrx)mr(%L#n!CgdaW#3a}%_lNv z%WQe8ONJlAtdq+;vuH2zu0ADBnW41b-m9LQit09cb=_Qs^iDW(9a`)t`8JCriQZMo zHD|W!D#V-&@|G)S5}v8G|409ej&Iv|1pH{)`T8&>_t zm}lH+;+aAPGG)GJAm*B}`VlfgP4iHRmwz3+e{NgqrF6Zo)ax@}ZK_8XKHdGPCbW_h z+w|>$BgxVAo+_dAQhsRGkx8bO>=)-@?oD-iHxunhtH(c za`zFKkuzh5<$M_+b6U2J1oEjn9d>6!uk35kh=k>(8Li0%nRH?tgX=P~>ewJRHRa9Y zHKr^kQ(-OUu6dX@g-`A&STfuFK+Y$nI40_!9I6}kdS;1G33*ync4bG)%VzyLl>B@G zTTTkPTfO%h5TjR|96`Uzhg9dQ@1Z%&H&)EfdeEm%(CAq6`s$9-I+Un<^u)JdUGK>E z)VZ*%{Yw8K?bDc+Cmoic7JPKeJ$*Nb2flza`uY<}p=#%~*M_Oe%~kWDtn9?cSgZPX zyKM`a8^n@7Po|Ti4lfr^uA}#w`nDye;>g5$OzB8a^CrnlKJBiz7egnOa)5XiPv^G! z{gZ6*ooF%M=^>+Tff?PBhT5Ckh?w~kr4)){Pc;mmahds#gj3T1B=f1|n$(JE z{W+oOM0}%Je|HV%>8K+p)R=FiaU4Qp1dAzKU%MA&bxV!tqfjVkp++k_i%_VZ0Zkms zK8}^8aPS*LxFmA=n&kfb=`yHVG>*Lg?AM;CCEJna@GGd=oS|c)dWz%T1)+7*@EHa+ z!l}0kT7ubbS0i;kakCLGa`h-z<9;4VUZjBC%9r)D;)~<0vTJEAc`+^BnfN+LwF+gx z0KchrO{sXY?Xnvy%?i7#NPDMcNayQDrQPH^wKFVa!B1+SHPfp&D%D!Y(WI?=n|6K< z5o&Goc7>LXoiXlJ?W&*iZqc(}Q0;E0+(Bm6ZUE=Nnwe;r+AXV^(q=dsWcT(w z>+V+0GRj0O)VXsur^}DRou?mk#}Oyf3(3HJ@v#*5 zeKJp6mNxQa-ea487_Y$zRzGg=X*e4a9b6Vdu7qA>5P7)u?nq#pG?>DyE#+Fa%!abF zd-{c!#PodWwWX!w%tc4HxF7B7?7}fFu~I_{aXF>B{>$CPjHug}d;5yfzxzLOA&Tr8 z+Ibne!nV;nwmXmeH=5$xS8J`-dmK%?rVskxVK9T|5@j2FJ`Xq50(PyY!yE?8pXf)I zVTMQ9hEhMGmv_ZRbm)&*U5F>_kEz(wcS(-MfD%!VP#rgmb7$qen=Q)<2dHyd6P_$r zb6@`p281hD>{~Ed6Pp`$rE4$Qp$;3h=fASWab4SCez}~fT?Gd0!GNOt8g99g1{`^{ zCNv^oe@-OBr}@bXV7@ku-JmB7HG^l&K4N6zUF|P`YyPf$`l#C{V}%$zLjZJdTUqiv z$5Fzn9bnp`Sc`{C`}Oy%R5g9Zh{fB)CG&nG!DLkKu5|gP-aI)3CSP{H+mnNAXyhIE}uMTPLH|JPG81jqfzx1;uG#D9|i9_~Epxp@m}h z7~I#~^lhWSkofCB0Xto_NABkVm7}S)Jf1|z^U}VW(37oN|7%BTF53N`)}wcA_>(K1 zQwo@h%3R#3yRY(iMuzDgmCCgHvT4;4?GyzM%cL`~fv^;NXrC|bMo95iGV!?-4A{@W zb>tJ1dxwXcM|uUbJ*!Z(5tkyi=6Oriw|}cE|07M5R%79Plpv06o7IB-VWIm$)1r%I(TME8Jt8Wajn{bFzgrfxP`Bo``vuED{&wt)OADExNa?DQpPvad zLVq9XW1SBjxT-Ic7neSWCX4ID5(^tgqxDrO;)e{I06@&Sq2vbJa8dG9bw}LZFae}L z>Qi+?qO%u-5BXr3ph^^q|FEs>a_Zrr=2cfQ-=z@A)UdMV5g?q*;7`}=>Q0<;^&fpt zX*FivM|pmiG;&t1x)~ny3KJ`Tl!nA)$@sol@-k33?_xQz6#u&mHW zNBd>UZ~{pz&-G#BBc54I+B)kCt%@jF2GP2a)*}eJ&O@mY2T~QhcHT%;x^YBKmHanD z{kypo7-F4|okgd1b{PpfZ>~D%_4T zMi_PZ98S{Pe=&;hmNc3tzx}TS-!)G?rTSBxgk7-y=8%J>lb59WbE}#S?b3!kmX&bg zDDlKBG*8Ot%+x-NS)eBM`&jmOwHmaA&Bte6>4AsDihq22_T_6?gjJ_mX^e8slyf~9;>KZ?upki?f2cZ9EW=r$E~|vb1+hcncD9Xz+f+`?IfUcq z8|~|RgoW`5+ocuG%^sa80?RX{MPj#qo~=x6PR~!niE;?e$iLp77+V*ZxJ!KXT> zmrcY%W8~fezE|MDD?i=0IlcDrt)WX-*!rh99iI*Xg{4b!53Fh^tQ{It3edYfQ7F^l zL&n+m6&RA(22R=g9=WvWChJFcI+V=X#lfX=bwTJ}zyeDWx@ng)X2o16rh1Vn?J)5yJEs4G~~%^2hSj^tF#3!!8r17 z?((}H4`*x-yG@U0>r7Uw__Ti=;jW#Z;*WD@&z_Qz9H(%2i};>5Qo*X6E@I{lE>LOB zIdmt_f(*v0Cat<_F4Q(5IGHo09>1GkoPYFZn4C++6hAC2)xSSwYYm-o@|dsx$kU1^%|P<_L^vgpCvI?-P{xm3kP4f^mHy9++`#HV;nF#HzY zwkDA!?uKh}wF;YCNHwT~AEaBP)`uDTY&2Jp_tA_#9YRwfRFYlt_*PZF$*#odyEjS_ zwq{r<#HgG=i6UZxk1D^-szU^mt}A@HRw*2hXlXdS-8QJ!fpZ$9o3YeeTD{kGKwVL<`|z9nQ*TXJ5&iWiaXd*fwo%W%MBpV|&wvg*k3ydq z?eT6!#|`#|hF{fmseV?o8Ws|W;$%$OK+@AYH*(*rO6etu|2r;Ml7+bUL7V#W?YvQ%XV(I zCRx7N4p4v?#Qq(Kk(zs%sdiXe=39UO*L!de+~hHO+T;Lqk}I-mGi=+SEqZRo$;thk1gih zr`38q>ZB@lexFBsrbRCS>8eY$4K@cO?o|pk9*fy&k8Bw-DQ@DD3%$D;k$x|YoGfLc z{WJ9^9%*$0>qgx8!lMme1h@qTlL&e6bq-58 z1}6-OzF>{rBS0}e1K*}t++-)b`)@_IkQ&t(Bn)i-HgRVm8d7H~RlV5#zhwr$p; z>j7|Vk_ik+YG*m?2XymFzpfngGxXK9>=&!HH<+(obsg(B^xVMFyeK>& z^cZk3dx5V-P~tXMpomfrIU~m+@AKC1QiFbvCiVK!(y_dhjWTD;M2|i9I5|YT0kOC& zC_7*8xYTFiZ9u?qcxPHlaD>92{ZZVip|)9g{ryBwpMSd*44P07`3wj6G&uwyaBI-_ zT2c-^_P!t=UsS`W?9s-Y>k?g|`+;|H+J3*4rc&sg35_SISYmU(Y_suvR>$ddJYioc9p>6uKz^nf(`=S+IcQ;;#unnDpVv1~p;uQ60B-$z^&bu(9 zsmeJuGujtqAdK&y^U0&iQp2_7MZv$@tD#Bm%IqIa}jrY$_mz zv*A>(*pE;6;noWXIHY!`?mJVtr6A~#HK#H(v7P!-P{MZ}45&O1D~7_x0$%TVfJeVg z7CsOEaIsulqI^7Bn5d!g_t)NK?uaH5S*H-+lcJk?&yDey*f#BSyXgTg{G-XCG?) zegBAyRQOEPw`6eQ&XXHpQU#<&sep!3JQkKKAgZKBeU1UyRibG!lb8~25?L8(6S84z zkAyKiXy$ancFbU-_7nO|o0DfwJrz-2=g;kW&-?xQMOOb(QIhz}HpmgJDu>=4;iJKY zsxi*`9Q{hy^7j3%uSb_IzE&ueR%7bdxmYZiY=7E|TM1>27?QG5^1F!MEvbgZ^vEwS1;$|jC{&Hxpd$EMx_>jbgTgqH5z#w*zev4rKI~s7DNn- z`AZJBS7M3pST6-Nd_V3J9w!Zsb%*aAj22e9!oBTG4<=g)4O}&IQlpKgj|G|_@i&d= z-2OQb?>}&%yp%+ou0o4iChgzivVZ$}`zkk3mEro`|B(;Jt;#@Tszrauc=daJ)_?r} zzrMb@Nu;V#UWxi2NoMr_pZ7u^aVfC#-)`?emxzS7I}5z8DgNH4|Lfkq66boq zB58g9KmS6(pJ+;79hmY+|2(<>G7ov;qHp`Xee^&7;*JcFHzzL|G)x>c{nyq14{rY3|h9?6T|sy6~Timu4U?THg5E-$8$W8M3rIJyCFwA?&8>Ut99` zPuyRKi@yCp=?}Q)|Gl@=+r%fwOZhTV>~Bx~-@Zn?ATIiU&E>C0|6iZ}*IfS1Nd7YA z|23CCEae~P`+v>l|6wlD$0R=Ir`1Jo2&JdQ!9r`rKfYd$mi9A(o%a03uAbuiKzB;q zG${YC^ZM7DDX4(x=K3Sm1O8F9Nzio{qLZjgv(?_7A8+a|PSJI@?-h@+@FRw%lKZtg zAQSwG&`;-NE}wm(l%yGHfnig;rf6ZxGD;ZVpl-u$;`b8nes=-CO@zdnH6+^@E=;mk zznNICEYd}0yLCABV0)N1%^nlQ*8g?=fBApEo3~3$)h6QLu(P(_I)~iT4bIl(owuY# z#Ol{V=g~fN;&Hd_abfNL>^j{>K)6&X=zMz0{G+UOUqC*#Y;=iy*1hJ`>1#mBfi>DelrK{y7&?^ zsz(HuDM`L`9IJZM30du`x|ISj27osrmIs`FGhEt z43{5ICT_OcXw+t9M@49No{%=8NkaB}?&HcJ?&){{Oog~pa#8*?0 zqtExM2{jVeic(e)xJ*A?I{RF1l9&cit1Nm*8+S(ajT7;D?PsA)Zct-EuwuIOTC&1~ zrb*yLtlk-1TaxVJZ(y^glyTEn9fS1`(y#sQqQ=U5v3jVL&5~0$x7Hs6rDH^S#XpQ! zIOn@r(=FqPq3$A+#Mp-cT>4?#^;|y*7qUxf?s_;8iAjtr6_&FA%rC9(EQ! zIQw)@RA+^lWm~ki8<>`7D=Fy2QC@yuARRt5rI&Gx8n?Dblyp&G?KSDdxb^sQA+gjy zYu24G*!F0(?=_=Wfl81|s{gXuzwXE{ox5a$^rF=h%2+y(q4vDr1>m3;VdkK@x-umP z{*Kt84^p;vvEdLe_B1bW9^~6!9-I4-ZEgIPhCDB&kLeQqIByBDY?tlBbg9f>e(O1{ z@NZ@0KfIx=ym2`Ni7-Wb(18|D16GExnfRdSWY*N?)tsRlp@Cv?g_t)vZzB9^zNE4I z_6W#>W?jAVeG_rxxgf1h+w=1?dz0hn{`8}r*M6ZQS~l#PsdAP4Ro%T=&d8ZfpOb-E zch8v9qcOPQCJx!X5reU1Zes>Y{SYshJs^?zq*-j`i7oYvoK&9i*g1+bnm8k9loVC{ zJQ2v3j*;@THc-Xp0!D1B4IrJ>$IGsBJGL)L*t+`q8k;5>M$5Uw{dz&aIUV~&s=bQM z(Q6*deNAUhbDJ^yM8OW-o>sa_Z1vP=v0J3~39)l73^Q*!YR}h3MDLs=s>r_PSo-Z9 zexv=RbPw|QdcqsSm%C$2&rgNUAFr<^5svi)W`K)6zj+kd+nPJNJI7BuF@$oWK=I$6 zB-4GrpL(ppqi1L<`>q&eoAE|h9CDP{p`x4`GPrmgXXjzjxg>lxX=#`-V&8Pmsb^bn zTV44)U$g2e%kJ;|@JBX!`3pe$Q+QL?HPBf_(Yej@>Fns))y#I()as4XAwc2I%eb$W z!!}N{EZKhRdT>ViL11BcQB_FvzDqgx~RiTGpT*^M# zYj)~R^0XoP$EwAd1A~aA;_-WAVu0Zy+c+8|x25X**~jq7HT0FwMHxIsh3*f_nh_f} zP~(ufb9z0ue*)(Z#;v_adpW%1H!5+0N6Q)2wnX&vsuNWuHIlYutzO8#^J9mnTG$LSL`SpV=xyq2pcS%^Q)fgk1(i~@ z^}ujo(p)!Nh`1GL=X%^&pZu`r!@t7@E?x?1l0Jjj-Xp&oW6)|*lT%54Un`&tV0uCx zuav(NqsTQ}*~cxOWe%?i6!u|TAIJ}^iB0Y+!wUk|fM1XCPWarwwN^k?MSS_@7i;&O z>a5+DLw1QKFOwb0B=>in&wh2h4E^Nri?RqCsE4bdlRCbgcD7ywUBWsSK~Gn%0jr+< zl5>7qy7|WZM^PR*f%tF260dos$@Li1OXKTOChrPfPW62etYRKd?g?8;j&YQ^aKAWE zb3`$veA81kiVE3qa;!JHy#bpYXKLn_trJf-Rw~N2#WsFo;mJe}n%AFim5xGIzqyF8 zRO{OvC?gZnbCaf+_-n4L|HZdIdKC zE>Z+sfEoesV(Q-%w^=$a#UB!Wfeax-_pGNI3nU4P0>pRd%3Aq;i$HNA3AFZf<3O?? z@mzQ|qbe^|uWaWtwJ~_CtSJoEPLM*UT6x?U>3kNh)vdRyzsRzL_j}iMkW-7(#9;4MgmGi}dVrSi-i8;Q$ zfaZ~LF3sU@+4CP_6*ZaYSAh;6AY;<`rq1F`Z;>X2#8}F)U~YrtV)N|x=6I`1G}p4Q zqC)+_umHuec-*%F%oC)bbwlQ%DH(fjpF z>iV+x8B=1%yoauHFAM{R%zG%CLJxGC%eJJnq>Mq~OURmPxL^3BdK^2h%EvMmpeB;K2Yx=682N20E2Zz^_eTl#mpM4yul2v;6(qZnn zr~NovkgvZ>-c4?W;=#->ub7$n_;b0_Q*%>wE?m`!K)77>MEPId4@4g9=x!#@egAR0 z+OvAhn57Xf0ZDum{~pw7wrO_vJkKsnYO&gA{Sy6v6&jaA3WoY`V7;=a)>NQCe#(B&^LBpk8!=UF8na>x#r`b1pbd zt%O2m9|IGsoI`=N%Ol7B`aF5jV9q~wxI^FXe%TG_98A6p%eNOd{3}$Db~%#{OdL=H zn=py2Y?|svgKa^hbuTP`g);usWwUGN`RHabk?R)^n+i2+OR}`1f2U~?7zLHJ=JHU^ zKiLHBu6LM0xiUV{xGdm@7SK6ZDFBBycHmHW9X1x;iqyICeB9={9wL>THpEQS$o;wf2IJmrtH}6;TiKauE4=f4ZKF`mY?M-e3HXq zaWs9Sw{+hscEt)>_U0P2vO~9Iz6dLOyn%%)i}zn>30+UVHZj&9OUEiH!w43OTZmB5 zovYVF85`qT8uph6qh7E%bh{|UnLBfi;h1~Fq5)9Fix3ezWjdbJ0%K8x2ehyi)W?M6n$UZKs>f0(NQ01F5n&^*H>GKrIpe{n`|L z$&_IIx0mQy>#m8z@uzq8{Ixrh6!!FP7lvqk+}>lnD;K0HahSLCGVv~riioBSI|i}8 z7LaqT_X%@X?3Z8l!-2@lD5vm3rAN-C*wf>g1JEVwJ*gC3ho-fe$_zCdH_iF*db4jc zJ{8sZEns~g>nFX(saG?~KQgYF2pGB{!e0jnfOq+Wu} z^O8ctdRT-7y!z{X^S!0upF{fziQ>yz_|fw2o=mo4N79sI2@mg{zS1M_A8c;BzgnXS z=;M)Q>l68lz`FxeS4EUaS0Pq_Kq<_=qX387WoB7 z&fw6oG(!x4Ni=EK1Lm`AVm5KAK0Qv&)o`fu{z|aJtVWJ_g$)BGDhtctZN~T!w$4ID zk^g)e`wrmS*@*!cal}y!kC{4Bn?OK znP~Qo6}}#rcEZLW-YSP$ALltKyb+Js%2`l$N*;}3-QL!B0S|lc$Gp5&gFi+f&)ZRv z1E-$jt|H62Fj#SvKK0!{%c$=gep^fG5g28Njk6p-2S*PlWvU)8vXj*Dm^_*h&A;m_uebvnb;oQWcM{78p zWelk>r<-W9VMczf-Rk#_`Dg(9Vf)p%M0FK@=3Xm-1+I?$4>Gr(Uo;y|M53M!DD*Oe zr4sK)wzq+R2S5a-yjkQe*X=ZSM_)2$34F1_cC^C~&2oqT=9uY` zq_9y5;O^pB-wRJ%i{lJ%w6(in>{xlaAjM{zbpG0YCD+72VEjpAU#KIk#(*FleApqz z!T}Ef9d?*IHY#dKT>EL=qG=IcH)s*@7QU+yLS8W{d8-yFh9~(pqsEbnTs>0XvVt^adu6rtO;idD zfw`|dfun2$G~5Tsj1f^h;%#9zt+m}u%kO)ZBKq!n)!RbyP|t!oh%dXGhr=pL32_d zZxBps6{tSfKXgHt7;F`P(ypIHT8+Po4m2D_(KN6d<~+Q`^v=X2^9D;2-1Y)SW51vo z(kgG~xsf7zGFXe%i!VTM5gnuIj;GDS(qQd?@ubw+vEKf86vDhRwhaaC2Lf>0hTp~- zL4k+X|8(gFynK8yQjHkmdUxq8RS!jj3f1Gni z*D|ksp~#*pxgFa2X1d~?Qo*zCoRQKX0nJ^DlJ55)nD{vWQA3)%q82Mk!P+JQLzpsVe@HR) zbEszoToSmV7A$wJdEF|)ICPI*1^SNr&7{wqcbVjytM;#6RoTA1C#1)JRC-6i=xx^G z=EEH4+>#q8E@zFh#jk>WeWh*G)F{6L%*j)wC!+x^&)1R;HHbST^!O|Reo$N5>&Jh> zm__so9B~Zq6z(!e6Lz=dy!|?Og2uO~AMP)0ptP z8#Ghp&f(V3MSr1WIUC>A=->6#+>LednoEYeOj`3rkMM60X{B9(*AU{FI zZ`7BzxNI~|Ar_Q>nj67bYqf3)MEzU^bacDU2M>Is*gnX09^d$BQEUT0=kk=Abw^8r z5(lke;rG=Rf^L9zvMFV10Ghd0NfaNKsCe2+>B5&%T|atYKOHRR;0aP9qffU`@o{5} z*ze=p745Wkf^#p{daCCh*U3?ReRA!?;u(mT6UsboVIyWLUDOEIAlot>feLX>hn>1|#TzVhZUWwU#1h&rQv z1_z)$DN8c!j_s9taLP}3A4@K+67A9ylv9?a*v>+RKdSw7iS4o9pFtr~dPg_v2@FF8 z9I)LYQHv}AY<2lf!%3+PVViJzoVe+KdU$%&k*nVh&-JsNMOT9TPV5_fbK;b#4q+sr_z`oJZgyHb$q+!1jO!gt_ znaQ*}!C*l)+dKHK9rt|4GjT>l$52Wh zQgDzNH zEBEwcch9mt%bSXi#<+Zf+UNVK0@$xvY`Fn(YcIij!=-79cF28&^8L=NmA#zUiEpQp z)1@DR-G77$L|F~G-&!D4SFyob-9`458m`PZzijJ`X(?NNA|>5$W#td2f5ERrT2AI8M{w^8(d zPi%Dqc5i*ia-`q|w5te6SW|louU4o z?rnR*wb0O%SC?}b-)*B@VSxq^^}()#t*XxKy${bC(t#4jWzgpRvKw*?S;RCW{GQew z_kb#cTVRLWM~>VZ(4=!usEA zb&a%KAbG;k_r*hk12a5dBTo-MY=c>(wu0+URM-rE{|Vh{a?(%(9W_qiUNTST*K~Dt z1=+8+(2wMv81a5$43nJP1r-PXBifo>b7uMW$u_GFz#b-cqKaR52~RL5ikU5@QN(Y2 zfHtKt7j)1RgP(ZM^!v$`j(C6Lq*3t-q;Yl0_wGsy@fMT0VWWl6wSCT2L`%N5yL@GB ztQA~0rWQx@pqtbC5d(vH5;m>K5KASKW?0%cMX#{Ub8|SV`sKaZdaB{GC3)n5eIwp3 z3a6r-vRbI0#71WxJ1{)BK7yG(+}Y-oOMJxJ!1&V=;*dgMmsOZNOxTa!{p1^mWle6F@)O4k7 zcgKYxN=QU&3lvxokH(s#c!2(H7|{4`*;ppdmg?fc;bWo05nQFsYF=7L(Cx={fy{Qi z>}57*i_5|iqg2itk)Nh=3eQ}@9Y2~pcWY}Gzry4dO#d4R>4^H@&fMU!khuL#OU@F<-Z|K20C#SUZ7-zgdMe_ug@HRUOOUb4p z<_4s{t&smKQ4AJB`RV1(kw)!o)tg&mglVCn0ssRO17A~~Yt-YO<&1Vf+je-)i?{Dv zJnWD-1@$VGC7T&f@CYj-TU2Zj-RJ$u@_n)rIV5NV7fC?Hripddwh4~mE&y-P=$ z^j<i1Zq%p@$l3sM3245JIGd-b;W`zQuXp_x!hKpEJh)=DYdExglJvk+m|{ zQ|2>&Wsc`HnJk^~uX`9|q`re;1##Y>Y4hs3^;%<7B)8Ia-qL@==X&$#TSThwZ9qgg zg@sQrrsred-gxmO*%jGp;! z)GK3_z5Wfy-tqC^VJeyq5{bR|kzd>0Y4Nh8bGwJTxpLK*wy)f@gw;C+4Dxv;#aatL zjlX!YXxv<$n25_!t&03gqS3iZC*j@=GCaCl#+&UvQUow7_~)XUF% z@84jZ3|Dwc9vThLU;fJG<0ay7cGCS7W8W=sP+$mK)j*k9DA3uPPk~FHYT;i|F|BH1 zEQ=KORH18IEw53_k<5FVb!TCT-QpDn_I&L&V$eDyyW?&IK5PXckjJS1;k;C9DxFzY zt1(N0kEWrV@O7fcINT$eVO|r_4f%PD?|ylfSajXeQEm%!-W=Q}mGA3a)6?@3KfI-A zbpbfbqP07$7ReQUiHHYs!vjxx&&W+0KNLW#ChDxdrEb zxUS4jQGs%y75!Tpd?zda1@*G%oe;Q^lhV$?y#Llj-doZ1J};p?(F!#Wfu*wb)V^ma zW}Nj!6~g%T=Et*gA0G2NbV8QC)^s1&*mn`UnV}bQJ+}DKHw~h4wX)#F^qe< zvm$XgOo2ZL5k4JDmsdpTt9gUS`ZlKmnc~qnPxNZ-jv`)2_i0A!CkHdPTrrsYX*~wSB1Q=5m7IT0^2w z75ol`h|!t4U{8#a-xhRtX<_|1+Z}2rURO#}Wc)&yeu`DhBa3YV2VI|T|JBxk4COk* zG5N%m+t-=Y6`Kb~7S47m9nF<;bpz?+Je`>OcnWOgPY|)kmfkx9;H*fA3be4|sWA=F zoso~LqT_p4ZtP5O+M5Q-|q9>jU*OeG|?Y@eJ z-sVSUscIT*d+qg9aGKW_KKG{0R#6Fs`X^K8F42fCo(Ld))4PM(?04b8WW*C?pnKoH z0L>XN$=8BcGMHFp)Tu9Ztu=IoinxSRi|?jM2<(GhHfP_EnE!ox{V%B?si8I8_>$Nq zF!f!*t@ZXhWVVASsVNg@88Ty%{~zz*xBtdoUiols?4_bhRvpmm0^GM4^wGfzQ#)A@vHR1a33J*? zaZ|*5{Zo5t3Q%UGZxAZ^_II4?f60};8JAkV7aCu^l&JlyMGJjb<2Z2W>VhjpA5ZAt z&Px9q%5NbJn(qYWzXy)|Yi$1#>Tju+K9h9zQ?(iYXIk#J;0xpzbDl(y{uZ&nvOaxp z()@V%KuU=r@IOAyM@hCzd{;8kUi}^D`R6zBoX6&-xFdtW--g3KA35h*|E+Jqx55AM zUbg8N-t$^6ZWY+g#yM{8h?T$0vvdSAb`#qO+|0oy=DXob5v(jw9A~i73KkGehMW z^d2E)$FqU*8F;MQpz`N=>uP-5V+u-vGr+F62LKU;Yn;sF;sIMU0c}BxX;og6sh4Uq zagTe>?S7tFq#0e}Nv?OPI$Xf{^Z?a&E^TA!qCLFlls%I0WnM|lc7GhgRf;$nAGRDx zK==HFSR??<$-X2f)f@$Hp~Rlk8%Ku|gLU+SCqI3T4r9%CIots_;;02mdp~+TuxsnD z@{NW&Pl_~R6cV?+>rbXg%?Gw+un%26jQ`Z|nsX6jH+*N?3DXmSKf@PWqzEGN4Xlw^ zWE_BGnuLMh1vRu%E4L_=zqXy^^zpLS$lwtja6H~4;P8uNA3NeG9v>m)*9_fg4(|>c>2ugwF@QF$R`gBT9hD1C3D7L_yAD|h zT7O`{39*d@1bw>BCkzjKx4#%^E{SmN(YVa@MBCWEb`S406Vza5&*N zZ1)1QtrsqpD)jj_cRR}5H`Wxd=2pUd7p{_gAz`RH<1XdYv8z2)4FT=^8Vu~w)U`D; zfOr)PF9U+k*#;r9--eQrpX53=A|x(XyZF6%d;1Eu@4HM&yQ95*?M}))ue~^ioe%RP zCibrLJr&|1ve!&Y8U*%(e1Q&w11Nuew+YKq`z!5zRTE|l$$BjzNUWvP(e3pjFr=64?RtH^0fKJlfBp)gTugT|=OziqA5-zAG*va#Y?7{Fr>Ip=8J$tuRDO{>ppa31y(g*eKtDknBBYf%zJ!m9TIECax>l6>8>T~qoasVR2p^W_K z*FL~Q3kj)MYQFZ6syZmDH@y;IAY z+tPh?w_c&UXZ^1wn+Hsn5|4u}+;>i1*1)EMw&zM&-eo-EfIas~)kRcRcML}MA^1E^ z4VKER_^$lv{2q+Ic1}mY*M?an&XC?O>YzMo%w+Gz68iYFC}>lvd9U7s81U-39|2t1-Sd#l<_M3@+6?{8ZuJyNc}M%-R{}kRKmp zu28->_1lJ@Q6rhacO@TDq{XmXZjXxWU(H!CbgY4XBsVUY73SDw ztx*tVBDQB=Pn?QQRetFoe|o&awF59s;{YnCpm8zqH{5!)zX1+b@MN1gab-#bxG#c- z!t03olS0XjLqG$}mxr#qC*~Njc)%a#XI~^+CNW-;##ZxS>QoyCK9fo(?Dc`p4y2!= zpul3lsi#n4{V?<8c7!as6`~e7dc03OQ=K>>oSpQc>SNa~U;vi3vm9oQc__=Ned+EF zMA7G9i}f*UJdODv|2Dp6qo&B>>QgPkRV;ly@ib73CcO`~&JK8@nxr7vbGt#OyQMV& zBi#8W?De*#9j;A_oJ7E_*fRj3^`CyW9tVcBs*lfod zQca2OVG*0rT(!r!5YV*kwrByXmaEbL&ZQ&eb5Fr)Efl?=$++^@foQZt`z9pdBi0=| z(n4~l0?|%6l=sqjDlKp_4WLx?p;$cGegUNqCz^!LU(MuI-Sp5USS?VxH4e*F#!!Qn z)Sa!GNAVx2*yFcd6B97&DU7`dgDwlu%ROO%F?`;Edh@4XF?ipFQi9`r_w>9~9Nf_3 zscOJf?0&^Ldhir3_#8k%n;G=7axF&+lnQAU>@fl1K$TXIG(~$nDqj<)Zr4A!>i+Vo zR`2T7w@$~bs?j_sQvKu&5@KD+O)a-C9m!W6?N-4irV;zo=P>Q0nWFMi;)dshqwqHFwrf8Hyoc=8aO}l{5Py$RyDXN>FiKF?2o6%+4TyDr<6K zdvRw4^wu-^9A!#fEER%o^Hnf;lP;%ZZj{fm!PeJnI_MUIw+(288^+|JAj2(4jh>5r zfB9JL+dd<%tql^5i4CV$mKH*`qsI>n)2?f*LstB|m_kie=3RDrS3rRi_AN&}lQ@R* z#BxC;u^OK5=)TVY2k=7w-5b@2rH#~q*^S-tM~EX)#kQiI=}bL;4^uN6d`!){BbXqT zl~1hO$=iV_eBQW^DD-Y#gce%M5gHum1RZmU66llq*OAEelSL6jo3^zec+m^5WEk2# zV10l%QP1jfK3$Kx+eJ^smn(t{DZwX&g!#?j-!{PvX{nEjeoSLp4?oV(_=PY*yZ6+m z+&56&<*}3w7Pff5kkUQnA){uAk(^?Q$!{<%$|bVBgnJsA+3$&C>0#U&>`}asjjF(v z@&YmyjXC&4$V6-;83r0XKHlLf z{GPEL&w-WfnC3Yt3#%Bs$Dx;5?P_tt zb4kH34YN+b9?ueqv#T-sW(M$}g6%Yhvn#Aic1J333A__7&%2m>CV)-?NIQr|Zny67 zw;ffbD#pv4g6{H(#&t(Wy3XAZfr+*uG|sIeg{GkwCk$1h^p)-Jqd~~qvy(TtT%+rA zy@nwZVEFw|I(NM?zb`dBuMYm6Z{>f3AQ zRHRipv8tGY%ApG@L4#k4E5-<;E!irs33^y93P7mu4r1_J3(Z2IB))6pv#=q4bPZz; zyWOyQvz-7uzR~KT;!)vqdWgmvCQJ}z6+<0@_F=f4Lil60VO#uqvIr+uG+#VbSJcF0B&sovFcw(2uNJxCrPYs&kVn8_Ev$HV~x zr-knWX5<{%eR2AVs`^f0)sld_;oGt)E^B~oDm?e=GS+>hGRU3SGH$Tv-g*!;G`YRc zL6>;4KaNqLolDphRY^C%#w1UkOmgiYOze_BoFkFxa77md!F*i|*2FbA@8OW3)8Vl& zYI$nlB<-!fR9ec!V66x;`|;O0*t~u*bVpA#b8ewV0zUix{$GnDHpZ8bgAX{qpOEre z2TCbAfRx0DFX!THl%7@`r=>nFwK209J!MsQ*$L4SyVGF-X{(ygwBq~n3@v~}N9$TZ zhAdFk_)sHM!LyzcKbZL%bXeBzq-e#CY;;~=AZLTwjvjLZjWTc;-+ZQfFV^hLxUb~l zt4X|?dAH+=o5HVn80VElR}oOx z{-E=UYd12D?QPpK8uR*VI}%Cj5d-2xx$9m`He)C1F%nH*jm{Cx&BjxZg*LiNiJ3gj z9rc3ARKzH$(Io%3eqzW*=FJjujNUy!j@DHYK40@_6}0dUxjoLor3H5^O6ID6(#83u zLjIUP8=Z1F(7Z!#X`}wExBC5VPopRCbFhyn@S#+z%S9kAa5BPwc*FzKomL#DE87hcEgaF4l- z`i1zp?st6pC1jiFuUlxn54a3Cg7z)1S0opdU5~L$F35HS&#Nm3s!t)v1^-|uWm%J=A>DPuNwM6!;?z&Ss^zYVDN$+qDVhV`J1f=4|v7uxArE01L~vZMFP3l`<0jzJE& z3}^{8*;AOqiHSL+-yHLEpQTqd(|;7BOg}zq?R#2cu^?6e^8lscsqpp$q{mIjMHv6bP3Gl6s+faL}CqZx$3wKwHB?hoC zY16796D=4DXX9$h$?gQ^SXiIoWf5}>hRdtHv1}@DG;iQ(l9yQko4u`e@@B4)4n^IT zv>COz)JO9ATYNvSh?Y@JTZ3x#qJ>0AG(>)asB*iJ4=qcYXkI~e`By)P60dwQqy}@` zB=zzB%x+i~>0tH+@oGzy5G^9CacyBQDfg1jh6aci&#_w*T)SLHQ@AK!{;*;HhueH^ zi2-cy)lmvLk5I;-$_iY7Q z(na1)%-W18%CoWd{ghfCX-80;wHuo*#sGRx5YbT2^A%8$b3^P#cOIoEMtPYe(Zx66 zq)v$ij%_<7{ESCV#}Xsg=oC-s2Ebwk;J^$_V8uXL?Ji?EHapQi1mU(**Zd-J=jiIn z4JU={TW9x%ptA&;g4hrV9~~z91N4F+;ql1<#jS}}`kx@y>H2b;yU)yeVgPb<0QXv7 zKy`2weI4WWkv_~;=Gi|>@IblOmqX`)?aRxSMMmUw`KA!5t9@qOUJgMwAnBXW$f#0X z+=fagS6)JCMLD;O@abaT_EL#P9QZ;-GS-DO5Rd39U_9up^!Ut7$=HnQ5!h=cydnyP5 z^2f85e)Ok%JG52v3+{FnVIcey!TV>Kx2^>hMtam8cN0K}(i+Vf%+WVWGC?ZFYn5}3 zZI#ND`|B2*mB&`}pUh9n)7NN7(tN@>@kygSGcEHX^*Q&QL>g*ShOTyLR?bj&<^enc zsyhY5(KvPzR=rr8)R#F2ag%6@^4YJeMN&=q0LA+H%Pi*ZB4cB}A*;LIF|)F%ebjC* zpNirAnh;ObqqnXq5;(-#yiO{rl~ z%DY2;c*nHe_)+}=3LuPdGQ3GkqZBdnadzyp3(}-nE~!nyG}V%3ZNE0>&|Yq;ep03l z)NiQl(r#IrAn3k3=;z+x-~T+AL(>)C3ICHZ@&%!6$U6UQ9VT{CUwk!q*&udx>;`cs z6H?Rk2+yoP?0n*0avC$JePKF-*p~sZsFwC#gCh? zUr+C?j^*Zn=Q{R6NpoGYRjOWo(>n7)olFJV8Jx|r5Zg5F1&_;#Gh;AasH~&B;jOl+ zyW3mGb=$TO`i+TzyFmyFeErEOM9`Kg#NBa`h6yr~AUIh|!Yz;oNViJ_g#+4+;=w6n`O~EzfQaLlA^~-;U8nk!; zy_j||;b|D8Y8Wr{lDAqs!K1N|zy=7eT*B9vx?Y_le89mK(k zf3hNHH0qHyu^+s-gxP>zV+)|6tUCkie9{%NeDBb#+Bulj1-<*eQt^LY0QBAz-kv?s(P$U@j+{>_CU?}us=kH6r6(g(WGz0C#japo$&|YqYw{P z&R6CY#<=C@^~h;nRpM}`-SJmbOpc=pOat19Mc)aSG?e%o7+iQkO>l(P|+W~4EsxYZyuL1g-a$=Di#xT zV8>hdg@jGB#q#%6Jk#UtyI&sCCTIeASt~VBJ%%2W6N4Jn6%c#u^eiIucK4Wrg58qk z2;0J#WEx4pY`FMDvLLz9Dm}7E8oyT~QOhy(8=@(hz<(uwqX$mb!kPkZj4Be()2b_( zNX`_XPr20p)l;$D(kUkIXOe__<59pza-~1A359G7UPs4W2tP*i<(yc#ZKXRI-?hMe z9v{*Gt;7l`K~1`n1g*eqiKE->lOS6!VRBqN@&%~@Qn4*e?xjB~rmX6`$iF|!b7(2< zWQX=21=|}UeMUe;Il5Q8@1*?gwYM-o4R6$}e)0$mS0Fh(@sG6zoYyLXxk@fy_My6& zyDVO6Hc|ATVy^?)WqbHXAmexLwD4l4y1zf%sr{0+irz1T|frPDW zF`PbQo_z7aSVZVE1uIWH+Br9L#M(eMnpc>aKV_|AW2(@Y2kr$;M&!${?Zh9{9+m8R z{xt5`_#>!LtNu*AuqCOJf=S9C>+E<3@p;^}fV0{@t;(reh}RV_mhPLdryc-(jrFRr z-n2p2s)W&4ZhhMEoEkBjAvFLkemt3Jk;YR_`rz8VRJ!NpV2hJ?M#Z^D2-~>ws2$hb z4IA?J1+0Ya$m0tQbaMuvDrOCeKs96BN|RX|{ES!jv}zYK=K}RkG4(M#*y}Lh5~&ZN zHysP;;b|t-|Fv#%gt0o#fK0MrZTejJNe<>h`Og}@2cFC@7*d@SxO_QDd_nF2mbLn( zet9>UFllcG5EBW4$%Xe$IMN%3qd9Milm7tw)E=T()B{u%>nw%~jqhMZJEkJ--24jb z_ggWqK_abpkk5^N0v@3o<$KJ`XD91{D`zR9+eJTp*aIqtz2A`woo-ZaiYP1qXG;UX z*#4h5`?Uu}^JH^t_2rM;20@ZCjBZ~BK!ctcCp5&qZ{OJnv(cIWFtkW_DWxbnwi6*I z&%DP-&Z;r`WH;b`{y=vJqljX1^P?p(XWgq3Jc%Ih73d=mDj#zh;%kh>#6CB*=|2&LF z6YvCBXZb;6buG@vC9aM~eBdF1Cb9-YUo&ZhvDGH@5`&n-6x8!|_eX20wBE2{g<5F9;-^j3q*)#wjf6c?rg^XA zTtX$HQlWg+K?234kMJYz6{TuSeAZ%4QrtzU#}TSOi(-q4ia>^ks0u+_W%LR5&kEi3 zYP6nh^Io>pr>5S;>Sb)E_na+5dFpqa)SFr$SHGFBVk@h<86~R z7`HV{d!|V)Ae=+Odv`jpYU2wb^0VyC1p;B-)JJBH;CXGs&+@Mr%$U>F+oZnO&y21D zKM7hwH^m2{!@_)|%L!D&{%i>WUJZ zY7vE+wfLEjwRle!rg*qzf@hNnx7RgkAX`yO6k7x}PpR%B=5R5_Ny8a1AELAT6=Tr0 z)jL_;s%OsL65jIbrr?kn&n*}gR=1AA|7I|g-}_zAS!do>i*WBoDIvuU<+(%bzdudB zn_{S6BQdAy0rt{SqI+udosA0z-8Y_XtFE+N-t`!L2}7T#S@t%W3C9$C)43`Ot}<7} zhJz{&4|`=@nWnum6`xF-?}RB4axVf)G z`kMZ{NBcD!J>sQI4m-3H+Q(b!+UQrclcqbKs-*x%*FCcosdu@mkQuvRKEcZA^wvz^ zSe($V);E73tm3yoZ(qL>Jmk*vyFtv+e_>%GC7!S!>36&-^;Hq$L@Y) ze=SXdb-5vUJUF}HNo^?mP>@HQ=4Z{14OCA+qbciHN^A#PAAgpAuZGB<_hkyQ*1FHd z>J&2Kmi)hpH&p01mH^?+ij?fZ^JkCfG4b-wUzmJ64E&h$-1B=ezy3(qZ}Ij(W$AOx z#~F($c^OQ{^opQjbj3Dvt^JBrx4h`Mm@Bp}&R{Zl5MzYp!$L?GfbB42=j7<&pz#C7 z4uL^6Y6%XV(`?vH1B-6MyZ7Qmw2fH-)M%rygD7~jb`9N;SL$sgEt?8CCA2X?H6m*F zC;HWN$i;Y>-sp9}8&kZQ%?v0XRrDzvblq6MjS(7R$X9A0Er1?0;VCcvGbMA}sJq@- z>SMpdS5$QtRdtcKGqaGNv}q6_HgR#Lp(epvhSm7^^%`|Q1){n-LBtSxT>b=rEWGCh z0Dakhv9bGk6D-23p0|iX$1vKli(h7CVZ6AN)AvMoKf1Ns%;U=&8O>cI4oba$c1GgN z=rXireZu$dIYrk9E^j2ngwmO^mpnkfLN?ugrVY>r)}a~oU8ko+*c%FQ=3nf~v$%+e zuk_}-sO*4vEdyO^JDA90l{;ujhv}jS&Ztbf`+Q>%<3C;RsKDt?IO62A3!27Q&Hl1Q zeUv;R%g~pS49%tSGuV2cr@NzGicW$2No_My`67e1hUD2UP24p3k&9?s6cQyi(wq-~ zI}rwzWcSK`rOL>66{315L8o(`D|mr7rj@HnSsD*PZU>p1Av1-BVykrNFTQ!JW`9=n z=5&mvU-n1WSj*IR`X|IYU>yibHEih#?(0iz_oH8+Sopss(JSvDJM8FB(is@FohI8; zUn>cGV2Y+MbJ!RUTv6_m^v4LH=7rap^vFHI0P~`;j@LEq!PHgnz6E!y1vV1Cu@7tJ zYx-Byn8Y-rujMx6j%F*!q2Ax{e3oP5v)D))f36O&i|6CO7!?gIaNcC|<@@0*lx#%G zqdsVXU!pZ|x(ui&-)-nV9b%Y#!Frh48J9|1;3F~^UOk|+UN{sWVWZt1x3q=8Q3AQWZwh5dy|ei>j9 zoZ)o(mR>bq_w1ovLx1i1>*z4LyPC4*!SI3%$mpbWmwf%(z?#EX^)B^;{NTfK6aC5x zhZG`SY|(tgS_qMfX`0XADfq^Adi}HW(M|4iDbKsw8Arma@j;ms?sHrfX#MTFkgWEU zQ#WN<X%~z4=q9H|4N<@8Lq3t4ww<22jt^9)=AaYWbzJNjl3-y-Kaj>PgsGk314v z%%RTQW{nkCaJ88&Oh+#42~ycox*H1T1uODDNE%1xffr6Fdw|ZpCe=0{ga(n)t_Zd9 zAXOD;-R(6lxEWdbd|x;d{7vY$w)?KHntJRQ9OJEzhffMr0(Tz4q)tvU>P>dt1J_l8 zmk=uj+-d-AK_QflMla&jgXp$$_b{=41MvX;nd>oJ%m3=o$(!kp!n!R@_qD_0l{PYu zuAWxXxBK8Ggr{fuSwJhTI0_tOdtqP6b9pM8>?mNZCh;8PtUqM=TF2J*Eo{2PIWeW) zv}$S6{>MEKIKk4CFkNrqgbCaGEj5t8OpPZsk2R-u&{s@R3}!O6~_t>;8nM zS+dfewU!`N+iQqkr}@#EV8VGNS7^brkE|lK?F4kXy7LRx*a=Uv0XRgRCp$}BU32Jv z?8tc)xZ$mI1#8`$qbyXGx^Fi8U0Bi9FVN8(FFNEMI*Fv<99_CPu90ekncSaCmazAQ zBxJpVrxgCN)IUQ?=RdXSr!P>dH29OWa}DT*wsO57W!y?#O*)cJOjEq1fx&rhy3m+2 zlEJBY)fR`K6Amy0O_AR@?Cy+xocMuzLO9a?Tr3{)tk3o}2J5=xifr;Ox{<1e+8Q?p zFfuo#TOEec{JBP|>2qt+w?L7nZ6c*Hv*tjh7 zZRfJbGYZ(@FHu=`-^R`z!S>`dCs)oL13r7-h=s(9rv%z&^N9O8suq+^LU4|OYqlO~ zBZYrxfr(>sjiC`N0gV>$_#al6~4rfUZZUcbypB&s}Grukq+>N*SJPv^hrZeFa4{Hqfio|KRfCE55 zZ*&ET&X&=o7JOGSa5Ls2xF^z81ElI@D0Rw`Am;i{_ge#mrFKB;M5mQoG-yRkULS%3 zpl)5cQg#4{33?y#+w3sAmVu?Z_@3Z+I`X9dhhh&y-_LP{GwUZp1v=3gVE(KI=eOoH z!GCJlEvp>z+t;npUEKZY>v<|s_3QM}A?cEwu1d+dB?CO4EpU&robICfi!`Azx-W%V z3yTfjr=dycEgSdA+*KTwq8m=8&41~M{3kXtIF_fi8?`d}`SMhbO^cV7bnsLun~jEL zTE^>eYp(jAVq%b7mCQMO6xodatw584rJ)e>_!NP%Fgm^Ah78B2NE}oY-F#4dNT68; z9b6UG)DHxz_Z=D}D@R)4Skf3^Pr9i75KEYJF5&02^f_V>=iYN8?D`eH5LZd>oY=e& z5I^@VF;yZR5Xs=z$#a#}?A`fW&rK|>hr!#8_wYqCq*q&3&FLYk3d`}trjn}liGGw~ zbiC(FNg8GS2_$!TcTL;Axdivf%y!a7$tkLP@Lr^TOD#$Fu($NI#xRxJ!H-jXiY~&P zTpY}yjq+sj`6WT1jzNy70re92YZs7?+nN42U98t(wagMU!+}MPj54iNY44RLVm)z9 zO|hEE?rR2QOew6CQZ0+25X!fbfY&hBu)S15F;B7bDUa*31ncq>!bYhiu(}*Hew}-vwmEJoHUSmPO!{S8k zv*oqg8!MG+Kek#7JBC?x_b>e7)djE8UvzJ1MmXCB7hh=~G+A4cMml%MOR+BuLBbyU+CfroBJ3JrEk!oXKHbZI#Qd_1H-!=rezB(p!Wzt4AtEzyE$_dgdqw9I%~_ zNrhG7J^PlEp-G{$$wMG?5VB|3?CKWhB1AJY*YjoGZI!dnaBI~M4t}ExZ!fC@{a8rhXaz?{5F&x@!mW5kn7FbbDGGM3mzDOTe&LI(E{|M zIT6Z!>Q*>9>&&9>t#_5V?8t!(`B|%$r;|-_{l+4 zb785+QEL_BV+2Vo)s!J2LU?M5uUh&1`-rKD|Vg^VMpi$Y=PopUk-u|_4d;;QVa za}Jzi_ev<;Xb9U9ah@LYBf;j@TG|BH{9hZmN*-OeDJH+Tg$fSW@1dB|?Vu<+K^yv1UFioikB3GkR;655ZnX>f3g3uLc&KG)FLAV6YSXq(YE=7PvObD5 zv|IDqjX_1pRG$DG_taMyUk~|fdXQv`T>bIP6y8fT&XTQoY4+cFMP0M80mL2xNFk!s z1>dh!{S9F^VhXseah`1ypO1>^`PBUEv=DkzQGg-GR|tr~!RiuSzQ@$eJYJvv(Q;&8 zorB+<*rJ7#uR~Vco90%Z=U)EC9z6%c`2GNtEeeWP0{`ww@P9v7Qso-Awu4HxD$8G) z8Gk*dT)1R;E;#w$m+&`9#sA#YH|^Gshd-XEKc)K5I-CFho~HknGIefL&~L=8zdjBy zBmfZ&3+t!mzv6zs-}T26KoIqWOr!JFzlP+W*F8`GE_oA4)oA?JFaQ0n%G7}BhuWXb z?5~sT_e;L9oC||Gf_`!Thrj?gd_o4i=HQpnJbxvS{{CQZsDMib=UzG7{lE9}`)$r= z9JN27WRgymi~rA;WCQ`1SUNoty7|}D_xCsjzXWtjY08=M|M`-^SHLBF!hbN3{O2(t z{SX)v{~b1ex9Yw2;J?G>zr*JD=`H#H(bYz>m`^w?6nYncib2jR`h++@=P;f$R2?r2 z+QgEuDfU)hrYzUIAWTxGBFZ!IE zRH)di?9HM3Vv(2fALM-X?tGABrI~X##f%P!<{MF8JHWcFpyG4`DQ-LJwNno|ZQl}t zdAONn{P7DoQ6&QI81t1qSvugsAl6rI`YXe75#WC-0N!TZGz?WeMdJPhB;ZQpBB4Ei zg;LDMiPC-01Yf>;LXJx2rz-a*ay&qlZg+oYbMA>}bJJIfQlfnrv1iD9dTzds=hTUr zEo7Y%|pbiw9&r9tj6|q%o7I-&{0g51emT1;p@q51_*|uWkVKzWNK=%4C zTEIXwD!p@F$Ia>x7XL)hE}oRd7lR2TJJUhutpXS{QjsbLyqSOzd2cQ8n5>j?HuZD- zzfj)(vBwKQe9L?uN%~zy=jwFaWE#eamH&b||4eQ1i%h%7ZC|yLVk7|%!krO7J6mvA zVyL*lHXyLENr6~KgMF}Vhf{Aco?b(9BihO%ucQGIs+n3W{}%^f&&M-6?5*nIDm`#a|*Yk;T82ID~Eb_1{5`e`Ez?dRGVQ9zM8fSZ#Wp*Kw6U zg7rc`_&xj669VpmEv(Ut#T#5FHzFQCZ3yJx& z**;K@QvLD!UDHoE198iY2R`wx#{SQ2k*EGJx+)8qmCm3e`} ziy$#J|AUVEhK2gOm?xQ@t3gP!d%%FXcZu%t58WEg2tmj~*}VvGPxgTGpm*t`uD%fR zFNJcO068{(hBetL?3rQLu;su2gC??CxK@vx_ruQ*>95;8JQs`Mj|g?=mPsr)K}?i* zL4LsDOVgp;<(-7xz!tuyANTE|06i4t+zh1Nr&hNS#rDizt7XIuX=ZKq&uxKo;AYV zZ_yro?tmPUPXs(1^_oAma$gf1WsB@&5;_)fZZvCtjF}TiZw)=?wa+ihe%TzNsBQxt z?K)>I$8+?!&Th09XH%|H>A=eujYfeE!E>?&?yK%WbW+sNpx*_H|5)&B6ffOF-+FMY z#-4Ipn3M~3q+>eOS6k~@00wMvPHf~5sOqwin;Br4Pbo;Xb=XSEgUze^%M*>Z>2kS% zSFZpUs=5`yQ?r50vz+)*n4^=bS0q3EsTZ}WnjTzY`V`cblK(8`@y7-{a}mJ+Qq2uI z)z67g3B5SYx0SN^pmD)fNL0I^`10_ZqZTbg(k=>iXpyz4I47S&HCyXQGe}I}ZBb)D z&{kxYdEO#A_k3lyG|C2WoS{5tNczb^2J0Q_7}gO!=pY|2bi3@$ytkL`{S|b$h`5BUh{rO|G^*Q;-W1FsCi#Z~S-1J0#AY7ZFk ztPG5AXt16~?W|b1j-c>RU&5)B3`z8EORz0a&#LUIJ?xgkuREsqu!le6_B%Qiyj$#f z6kclVms)tX$i0Xslo8E<>PP(X&U8HBb!yMKf@80J zf?le__FjK~niqQp&{a0*{wParGWt;T7AAsu9iZ?Y%iH6> z;O;uKWk{B@KlkY#XPJ(NK2Qcsq}3|$(Rr)%z@^6F%Mw8L1KP4~r-G;RpDOej6b)xz z9D#QThVcNz%&pROiTW-@(fCHKaL2B?QXCcFw`JFiDzMKc=dp{coIT3JO713bfG3{= zI$7Ipz*LL8Bf)QfpEMir557exU8&vo+`azM$xKn+lQRLP0a~gyWmi9>;&h(K zKWzLFKW$L4>^(80nRd9l96%=A!(P@`C=(+f%4EQ{JxhP_SYV@o$Q4jwh&SAEUWMu! zoG(wbi;VQgTA?vkwMh*0e;(-RcB~Bn;zXvP0+8LzaJ#r1Azwf2$$h>{A8NuuM6to5 zUtNRN$#fc}{Fgp}XOG}Z%x?f_k^3Acq7W8r{X?U>&&Te&o8wM*P29hd9sIp&yK?gkCWBj3H9J zqrDcU5(k?N7w+uCFKH-UJ=kpy2gS!zK6CRs<0L14G(PvW`h`7oen81!h{yy@a)|uI z0BO4P4oHdsXW&E@3u(4#fC{F>g0d%V-petM4rXB>ocS@(F`Wo(X|?ni5*%GNondgm z))vaMo$IL5yD=|VTrafJJBZ>etGa$Eb`ZpWXw}DIdXz3Q0iz{Ax0&O~`p98dK!e>_F zdT)YarC78-U~*&;@Rh+t;^g>ktiB%!yL>?Fwapw{)fxYt)ncOEYm_`q*vlN-(%1Oz zA?xa;BxtgclySB3Xq%@^MUrU2-oKhY9bQe3rH2*D<*Nm&A_`bYM=fFxT6A5PZN zgbtqeJ4!UAS(zp$lo2XlS=M{+%a)CO_!>!HSUp^3JvBCIOR8+Vz^m@f)dplY8`G#2eB>`uI zr=S&sw@f}sV8B5dyUPmmu>&l(SJ;}H;w27OZ|n@fVOK*a#snRib-wvt2NKQ)r02;u zDfz|D^FB8uRR9?eGo-B^-1k(mcLsc_3JLYCjFoQ3_g{?Du><06C?&A@(on^VjY}MsI~=Cl#jmH* zEj$o={ZUiCi2Tt+g%WG5NTbsB?;6Pe*;fZHS&rY@EWfYqv}zlP4LV#0EG5oOTxkvU zBRO_^HT*cge6D@6$~#_e`_{Qffl7}#x>NJb4cJjKrbCGY(bJnt%Xj5`GZ}(x(wP7J zaRW^Aj&O{O=^2Mj0DpK?rZT_(mf780?56UyBsvQt#O>v=AOE(v?tTRRp zO&T@mK-VfUJyVc%%j$A_GbD#*cebzOY}#&(i^t{_^@7~!a{^CO%bbXQ4%9iFL@)F5 zJ_el+wTZZqIa)76y8}=HSA|GQ{dfRf`hp()r3Arz`*Zy*w~<5a4U%|v&LxX;Ud!Q5 zUwwBsDQyj5=7vUd%RM+Vh3?$WzsN)XCp1t05gH)AV?|URBz!A8qNKi?h|RVWi49&F-`JFzx<0b_p7Q zU!BfM>-3gx;aBiQ?;fBjfWD@V6Kql{3u814Va%`u}0?J)@f3wy;s8qclZC znjlp`K)Up%NJr@%l}>=rdkBbF=~X&P6M;l}FE)_giL?Zym(Ys@0{6|{;y(Lq&l%&6 z`{$1DJO45QdEZs%n)8{@e3s$j94%F9K;^q|qdb|Cz_}Na`!xk*qS^{F!*6vzT(4Q6 z9K0d^L{Y}d&vO5+7}NFo69Ea8m&j@zDZ6mhfPfF0A~jZ2&986~>#v~q^b;ST)n<_u zeygAC8b=?aPt5eB@AxoI(nBTDfCFc7CJAwddi%p27RK;pob(!v+^&9%^)W#4>^fYL z6R%%uD3@G~37eEHWu0?0lWp9nV;-t`CAfsj~n8b2|&z$L;@@ zOagvr1r4y=S{P`kT)E?C{rHI0>xHV)w3pSngjSNbWTNeSUG* z=63+npJT;JgOk9*DWv=tZLl{0T+X8u`_GG*PFokM38a8nX?hvj{>!bhFK{UU(%a&{ zo3KB>6TSxk>Y6ejCXs)hMyGxH-@u%X#J^7a25>JB;o6gBim4y$y0_GoE{^)L)nC+o z6T@k8?w(0m;&ofH+esX^On4vLv^QxaaE9BUc=K%dUSpEy{^yCEz6MqJVt)bE#yO3H!nZ;*b;1rIQ> zTQhkw-}8WnKu-`C%7$^KlKtR6%#vT)@=IasAMkiR&iG#zo5gz$}-0zqtm z;6Uy^SL2;<_3y#-y!MX*ewufMn`Do-P`=Z%surhR4I)xvqs}HEuxbiYtB__z5|W}` zK2K$*R>KD#5*UX}+qpu^`~1-MZ93WV>De;PMg0zn3QuF-z5VA27`ky$bx$EgZnDn) z{l~t&OROknz5|fc-o93!Z=y#_a{>i^t7@X zZ0}EP)Q7wk!jHY4z0c7o;aIk2(C*)0$XsK^wP11|^>bNM_u#+Y+qbxBrtAB2sgMeW z+E5WPNn*-*lDLg}HsW%sNLi_A@kbil>x?)T6wSQfFDImXKRA6th(gU-W2lA+)GU0( z{Vw=)!LeS(Jtkeod#o5d(v=ccDB%yZGnC`}`!%hRMqV|aWqWQz=3=RX_ST1|zrhQ= zOjz8USKM6k@M{O}>9?#8asAo=HdV?iV5w3Iy=5ZBC%qLF;tl?zPd2#6aN1jZlQ=aA z)G+)Jlf`f31BOb|9q5?jVz@%W0$WLaA}a>=Ac3@4u?Z z{oQKC+yxBl1@$4! z#PGg8`-bV~tdMHnKOQjHLL(s_zR%z2mXAR~U2X~dnzCPW$r=UB3wez)iX|2;?aP=Y zyM@k##7(#E=w7qB!jmo!*Do@^H!v9^?tt7)tNLm*-kj*+i{hm1Oz?1#_e8QC%pqpB zj5AC<0;`H)-tH--9f7kSoZt<~ZP@ zPRp@M=jE~aEa*vMX?%WN(m`5#;tZvK#R$RH=o3NPm8gv4vI7gt>Un}V=>_IsL^%+I zeCOWyq;tm>`JJ{5ggP^W^!|9%n8<5+3y9m<3*n98+Tm?^UFYZoIu@U^e6DGJbg=#S z_9qN?r{N1^{kS+(=K3-tyABSpP2({GgviEb)$nj~)KULG+MR`1pB zRZp9beB`vTEWgS>`rfvvD-fDqw7LyF=0sbr@&P+cyd!9$Qb0fi#eASP=C$HN%=cXn zx%gafF3lp4W2Rf8y_J(iBWiW@VM&h^`?t-lDTyu@83N!omUZaBVdeSKq}TLU-ub}k zNsSwp^>Sjt>I&mGMQCq45+}q@XVYYlxq+W7U=jD)8Yw16GYfA%sXAxTc-%4jzLdu1 zBO~0ONE#g>$Ms!r9vSxZVIy1=wogj2A~*3HpS_=-x-v9GZBRbRGVDqFsOLgApF$Q! z(6S~w;hOHAOSfcDAk!nyUp=(^N@n$OMxbZ zp;JeUTw?-{N!P;Ki%VVWp8gg5OgA1@90je`h?ZF0Su45AHAa~=^YbYBwGr^nP=&rF zCv1@R&i4v-%vN*Pd%|ct8mx6`{&uYRQ4s;MI#ZZQ*#*sAF|3izI@iTy#NX6@BI_}ZYn z=Hj$xnhR4+nZ_30U6x;h4YNEHCDxy&%i0;zH4Ip zo7v}8GlcDoiw|GUlLK@#@p_K|AyQJpTib~(rT^}Fy4`M>++rr;9TVKuIPo^od+nt* zS``rLV00l<5ihTgdl(f^0*{~{K$*jJa(tGV1807GoGa35A5+P~_Ux>OpDXj)wU1-F zeb&DwfOg^CO)Zdw6ec&Qh>HS0K<{cy#>6Xuj1)9B#dEfizMNq6u?%q7hT>!P;*jM# zayLDuG+?YDS71?h26j^n=VQS_t;%E^U#c}%B17sUB&vUdUgP11p1U>7cxFuSq+D=E zsQ$R$)jvOiUcdz6B{tK(uRqvk)7um#yw~U`Y~Sxe|E;{JhzjekVfa-?o~2yEtT8x8 z5;9f4ZUI4_{MZ)sn2#>E%fYstOG@<=xWZlRp|s`1q?@^DC9y9Q)q-)P)V6AG!zKWnQV&^T(NcJTntm?_&jP7nYc zX0_Mkk+XF=z}Us)U$}klOGVmE_#kAlhEFO<<3mvG+?f7{6S~65ZY+pA31*SPsV{}; zgl~n0=ow zOgyRK=9IT*m2=?*_p`u;u+2BgvZGk8TYiXUhoQ#4iaHKa7w)*R_ctA+$qasBlDT=6 zvGTjAMAbQPXuArX*`Qn|-HxItv^cXuJ0!F+4C$T#&bA1P3@*va)rOQWAUyRI^-}BVCbeo3-^a zwng;VjT2tIHcAOp%;MG-t7p*V?juC3g`2Zeue%c|jeg>A zaA$qo|Id`)Gv_nMO)posJNr)q2OF|m2COa1hDwa}X%a!AZ$%0zrq`o@3suBjB2_w` zzC(gwg96?a_tfecc^{C=Idd|LWTW2S^O*j4+rJh>QhU{f!E@NfMA*y(|9E6Aq{569 zg4sLRLqe8G%ww`5q^K7nd{xvE@1#A8iU%%ho3uSn@D1|Gnk^u`#6HEjaWKzs*@fxY;l>F+X1C4 zX8glLkiU8JK4aUi-?(;F*&5ie;NcB`SFK*|}OXhXJoD??3lim*@Cq5zm4% z;H*l7KMnL`%H;PR%_asJ{tr(Mty#iUA9qIX)D zi)ZxsFXTQFO00z}Bpz0a_kr97QYcS0asVx8eL0gVbtJQ#>Q4KC!azrF(|g9!b-4Mx zC(Q$$4R=5>yEU6tpKzz(D>c2_1P#@;wFVfull0z)ceH*e2$(mpe!}d=JbgE5uW7ZD zA{Y}+7wM9<_-&FLfARia4)Jbmomf%Yq{!0A)lLLV;t?e_cYOsMKr4}}<6FKWW#JCr ztO_B%P@%0OhivHq5xqXy@0A~T^XZ%&b+%0@n=sOkAomBjt!iOVsA|E#^~U) z#TgnReu3(Wm?d$OQ0s)*%eE_G49)O{^R$Rb65aW|lh*5f5Qi}D!GOx!Bth~A|@)Om-lu?zu3q2=1=)fJZ?O|xm6V1TD$3=lTT`8`yuOWe|JKXJ{i#$8VEKz1yodWD(64W(xStWzd{1j_JbAr1P6c?Uh9g}W^Jn*#U)_-E z3)&>vc5Reb;3RTEjo)~n#dDbUu%)w~TPkjW@79b_|O}L#U6F+(wV!TWr2@B1=6B!gO zi&14YX^+2!&mFO;wOr|JPjbe~ZL`{ng&N*SVro|z$oovL7KQ@NYl@JlAp)~~$abPO zFNH+OXFIkwgsb?9k3TFKl*;MkVV8dNaDLxZrrV-5=z3$D%M&E0B^&m{Gst%pJtiVCn}sGPq86)MbhG3Di0C z_}HOV7a2M&08=B8t5nj~1rtt{88jIQ7XAc=_BSmLKq7RFe~ zUrmc>YQyGjwZcX1*Er7>K6?e?O*LB-oZ0Cme@F!Z3s}}aC|@1(Z4r4Xo3-35aW3lEqswwW{hHCT zz{2%Ec+zxOMq+C#XSR;$Yj;> zRW@CENS=EWh!o*$R~+Z-V~?v*y{c=%2Hi&{uH76cC^iLACB$!BXO|%vV*Q*gd^Yru z_e+A9BEq&a^>%&~^VP~!Ia~23-mAk_T+QuMF=Q{8Y{PfgMiiy!Eut33`7?PIn5%)3 zaAsLLk*o-O@Z~dKsVzr9PlY>PB1O{XV)R`_82T{7iH5l^)c zDcD)<@GHW`WhTX{Eko^@*Xj>7>6&!DHnh+s`f#mQaZ=t+ zA}9P3_BWct4(xw?BeUCEV}=c}zjB#LGpc6`s5FvTl5}|0^{W1E$Ap1Q)9o_I#dEp! z)5J@8A3`#*v(S_J0oFn$1buTfvNe9b2_qW)5N0F06D51tnY+Z2=G_PDu3)@^7T}WO z5$YJiEMhI$AX0dA}(QsZTgvFdm;9jLxnW+-()*&|Db!a9^v-bQ4hV?Pry8M@xrrr zLiiP%%ZYT-Y4&~x1uM3g38FI@X!)LucseWp$*w>EP0)ppB+B(1Hg2Rl8_RSa*$5FQ z4T(Y~R0C6BhqGbs9{qkV_VURkI`Z>8SG~^_SU3(zNSvL@5^Ope3mPzBe6u_pa3h5O zg4|1=?g!}lr{`5iFDl4SkXfBmkGL2bRO?9}dA!Db66n2h?ch<69=EQH(&kNMn$S2U zzSnx6p`8{J^E#`7c}LJ;Bh}m!>6h&;UwB_x&>WPHmAO2veW&{2=(y}#r^aQAFOFl5 zUI#Plj=mOfuwoDfb${m&(!WPa`R7e@Gb`k)P7U3^hkk`@Vz(FQpUbDClc$@y}R{|O; zN1vAMy~H}f7dU~~1a>qQQ`Y;#!B^fl`P#B+wclKUo$`S4@Y?QJPohv#$~0I<)YA)+ zU+IuF?5;LObSpWT zy0KkqHFppk*4-gmY@tWIvv|Sn%MQ=s6@sS#Q*EX3qq;kPxq6<*JVYN=w|x9!-L+kA zd?OE{Q?|A_5)6T$%$gz`?i*#jSRdIJD<7AzI%tL7__TUKt4*U{;==`LvEZEto^&%2 zQ%|G#XZWywJ9P9?^A=V`tF{vPI`-P&6YzDyz%Ni5ietu#L+>0WXlRU1^EVq}D_4Gf zt|@`XGW(xoaQjbThYUFUb}~GpF8_?`KPs~t`00yGI~7JQ0*~rq8}D&-!uB zJ?=>5ag@1gTI{9>5DMhyruOgH0KzB2{;h3xMoOk(udxBDIdw=1#g`FiG1(&pT6m~P ziFdS&o2@gRh;_`#>bFLnB>EYGi6qW)QIIkB*Alo50w(Mv?&v}+i_DPH^C`AqvaY5% z_IYDb)s?=Hqz}W^q)VR^G&{rQq$6Ol!odOYpcGFP5-kB+ukl+iv_n;*<=8M+!;?b9 zi_OAb%bS+h(XU1nK9P)Y?XRe(*P<}<1)Rg(=K;)Ljr7bruLJm;|9XZP^!eg~Va{Qt zKyQUG<5uPQ!x5Pz{QVDi&*&C>85H*2^eCJ>Dkg{K zCDShsWy6U>#qgx<2K38c(M1RVdeNV?(Wc_@j^%W(2xyFoQ06KW%k171P_(#4*a+Z8 zCR4WlU?`o04r`KVkDQ=V#on^dtv7XErkk=7VJ)$smqpC0r5v=g^`BV1lL%5$p<3fM zh!DCYy5w(F=^9qCyz?ggWLuEO-Z@aGcHlW=G2xF3lc^Q)k05l4-0{jkuR;oacK%tN zLP(}0^TfuA!FFD9KMFg$RBk(7UEdYmT%OwQ@b=1mFP@=yYRXwA6|Zj(exlO%EI|+_ z050MMNZd{+?|#h)k%-8{iNxwNQkDK6oypJInenZ!VM)*uEEPqhXv$AkP{fG%anrf^ zZkIh8WU++=)Wp0K6|^ARAKjb_*1+L?&BNF4;Dy>yf7{vh350i#%Y$_e(~L!YQ}wS| z==Nkv3-$!>`>rBE;0p-h$`Am~>4*g`Bj&eW4IJ!>-ZMMdKRLEfhU@%jmJfJEIA-5W zStnNv)makp%XKi42B_0XS%_29ExdvCl5?HE6!jU;Ood;j}Y8uBwaC0`Ph1oyfo zITD=_H6GtA(fzVJ*FXu@masD)RhL|DN7688KW(@(Hp8bvkJ*3bhY65&p z0m8E0Z(Fkx45((~qtgCF3z72mV3!0$D`o|z!B1rbX9LNnxE?|E~@Tg&@Cmr&=w-4IXPP1UD8`?k2g6m-SonrLCy)U_HrUe zNGPFTAF5n}Nv>N1CzN78-hn-7yOPI)F34Z)hy>H$fgTtHOM9wR)MwR1oX=6j+Z`Z= zKxSI320Zr~-H#+)d+nn9X9QU~|3t~35r(>9>Ul3TND}|-j%sk|+f|0IEQj3^wl|3R z8n=cTnq|~#%@3P0fzauI!myI3FBSmZZK6{w-?w=Q}R;X=5i&BmjsdUw`ItC8N9Eg&7pg7N0x(Mg90_ z(1J1Rz>M>nM~4Oc!qY#Has;xn-q~}ugHS>Cm2d2F2?9eI!|}6c?b_JY&%mR&{c6)o0x>3?t@zq3S}htTMOMT57#E@jgD^y3Ou|oNe!41=$S_DrAD=Q zZ@79-PT6t`R#>tZ|FmJDZkI?ao7X>%#?}37l!6}_u1zyq5^ArH4m2wT#ld8PvQ9wQ zd!GM~w0qwEyIF03=x|8>9{O_%Nqs}_9v%uz$QH`~TnUe(am`71_i%I|j_r%se0;T; z?9XGQ+|Tq*~hn76|y`a z?>idvr+#2WH8gS-&GgpjLQ8B7w^m>KEhex`F=Jd5fkh;f{WO=wP9!yx#YYefNV4(ZS z!r+mwjrSGW@0{JWU;nw=sITBp@9bOnJ=4`V9R;J%n6re}zDHRE+I$)F_Bhz$9MmVk z_xG4fC{7X4sPmHeD#oMxxJYbQ1;~Wc)YyDh?9GrCY>Q$^Rz_j(li&d~2?$NLU#!wq zLu+5}8ml_lzX~NkV%Md6SWov^j4}RII?_G@S?u9@*>oq|ruUfOx%Wf@4xIRLu`e{V zlI8gBGUZqM+b3pUvBF%;Bfl&c+w|T(^8&!n{`1UHB@c}uCp0E`M`3?$1r*m;%p=LgWsz#I+dOy);zXV`bB3d()(y@$oX-y08O!k8$`2ZpS`T z301`$3NZAt{36Xg=cXPA4f!nXto~~w{QFU-z$!%udmi;^_S)$*oi^>4C8B<&4OobN zf25?-&sY8Rr_*(F?L1&xIk{6m{m07x|2^b?1B(~>zjgAzz4JeN^6w57&U*j<(Z*gd zm;x~3*#+xnu4TDvO#d`sxW$Z5Lwcal0&q*`fP6K+G=m3cngY^em_sXyZEvAcqOEp$ z>$ppDPpUgv-2NUSz%I`6{+F>{i-lXgouxC}-wk4+g61*YSt|n7DDUW59y6^gu45`a zNABX5wq<{j-cB8@KV09>I;;jq;yURizG!JyYc8!s@cwFiBMD{uf&59F8Mysg_|`&f z+wxGHVI-p}kQb)0Ur;HeFs-C>>8sGqEA!QeUdSx9I{*$vd35Aqe94{{!0^WoK<$!2izntUDKunMPv8w`{g*5p@1 z@%=qJ-y~+$IVH&VX25>0C;$X|jzmga)Ehks^k<09T+g)9NlzHb2>kldk*4_eJ#6Dv zdGD7|K`4MD01T8}+E^J9RHL$4Kghjp4Pr;+fy}f3z{NP3#0P(q&pQnTNm=jXe8#EO z+U=|DjANDoNz&9AB4c`^l5tk~BQO1m(pZ4y+b)>hJlspy z9oH)XV^KzPxoSF_U zAOf&~(~p8Gv1Z$sWeHr}`3J`Yn!L+9)V{8>L?5$hAcE|!Yy%x7h;W|-s`*eaDUG#% z8)36D5h;C-42k=4wlgivvI;AVOi+Z?wo0qGTi1ET@q_Fncd+NB*MUuoUdm1XY6eSn zV1JtkC_r56W*CXBnzR%S!#g=TgjcGcoo(l|ezKDs*pXP3?62)Cg3l0!3b=Er#F#y^ z%?p74x0DXWaioG;0dJ?kK~t^FI2`EPE6pt$62o=p`~n-jgja~k6VPiRpgP9Wc6GK8 zpad#PFJ_PI8(yaB3(w8odX%zkp` z!svD;O@a0amw$&L4MnSQq0&-ZncbQwXyj;wcvF$RtpgxAb+5Dw>%_8!FK&wY;s?#cTYJPeaR~&8SvA0TyLOvbewH_Iu8rjt;uxc4Hv2(^-(qE~+KG$ZatUoZpPnKE zsq$JJ?X6YC0J)Q$)tzF{C;)hNuYD0`Y&$wkkze)Z(aTRbYCUkCTonQ;Ia7KMU)b&K z2CjX}4<~1mQ<)dE;$$%IbB&Hd?_dMVeZT&u`Wjf%SFcfD2*q<@jV_Fx@HkxisspgM z1bQ>JDM8+4!64=1A5{5=K~8?C*Xy&dTT5&=Gz7nTx@2y=TX5Eg(L=lB)0{VT#ly@rpBo_xA^-lE3s zp45(;JbkeNzv&IA>X0#GxAn5rEk=&Y2YXY#@-@pvItch=^t@7mgD z-p>cfSflpTEhepSZtV_$M&c%*KCon;<;(_f4@N3=dRrfW^2CwaM{Y@CpkS1L8(Ozs zMJ#Z1d6%)PU;sjNW>xb<%YncnF`&EaiD$3(bIIoQDc^y>nEk2I&^0|2($BqR#ZnP( zVQ(ztxS#t&^YD38o%a^$W5;UE zSJRIzP;J59jL@-miHm6VE$Wtmsb6gMf3d-=6GR_@`T`w{T>mB!+|_MI4Gpk9o(@T> z0{PT!^b=m%&ga_F@#0N;5Ukb$Te(hfZ}50!+EsLb{Zd!E?oFtr(QzS5FAc>DhdTB{ z7rScZvE4p?da%#jpul~v+HKFlNQp83c|i+KzL8*8V84!**~J3f8Bkq7RNMVIwT|`T z6mX)7H>lP}61;gfE3%g1T0hJ&y-<0@?#<*U2dV8g6aV?}k*L;G6NGUlD1g8v`EU~aMymo%hy*kK>pRuEin^W`*%S%*C+~u!MBa* z$6W3L_Sw8MsM`Ty`cHfrH;`<%Svl&6UyyAdvOweP&~@!2%=PA@75DBkb}92D@*61S zM>FyOnEFFQje5d&hRwA_(Sghg-%|Fj$gHN*y0m~1WrY*Y5%JlO;b;h!mR<^DVU)=d zEal__elwYF>^Q|}JzFUO7so>ZC!zC+S8V0jZV7f_g=VHF7cxz?wEbq0=7*tF@K!>_ z+Js)k2QkS(PZfmRpq&-ENtHl(y*GVEEPIDA+SSG@J&c=-d08ke4|?DoeQ7iVAcu4xs7yL2!w?K=X*z)*qKkIU&}wM_JI? zvP##nzPEvb(l_#g17yHW+nIb;H$>bE(~{tbYD?=nDBqGEpyk?p99*0`qXcj}x>CiO zfyxoQr0;!@PhswO%kt*Rb-R$^%L@#qhXx}7_@cdZI!LgY# zniVMO&T55wpFm(z%X&*d?xrevG8Qc!Xv)1)652KJBDPZ4qnqKbAK$-mrKGN(on;x&1K{AdN2lJtK&Z|ikSzlaaywoG=K6X9uzO@BR z=cAwrHbvxRh4X*{j;C#&KS^9zC}O}HSWRD3`UtO18};nf;qgtlgwQ;{$=ZZye}Qy` zlfcYV3eh&DzO~3TxOx9d301GUd7YP963lYNwAj`9X~RQ++LI^lw&F*->m<9_!MLbt zzC3@uUaMT?`$5(7g~5|Cv1qZD(#jIgpvcKX%2xzGOjmYFqWj^y-b81Ly~6@z1tn~2 zFyavch%IXk9G#P7X=FtZ3`^f~+vP2F`55q9FIh>Km4o06=9XutwqPn`VI{jVbLmTz zPM|EsS_*gJLJ?BW(qpb>5>#C`AtG51FEqf)ZSy$VUqN>^l=efRRS#*qj#n#teO(r{ z-|hf)4zM?(&-!;q4Pmw;5#rwh_Eua=G&x@EGKhtfU?%p0X)-g`{jNd9xfGw! zW@5mxE)Z5BA7DQqp)OO8Kd`&pUp^?(Q#_wWChN$T$)Q!TT~#FpFTTg`6t%pOrlC7TU$zPK1CMP*R^N0{-?QDQA7QWBufwkV%K zWrz2kxmDSV<*|N}0w#Ez8USPR{ZXvDbm2=w5(ptJ3>LKeHm?5}QoY ze3gh-jx}0#xPMnXl+Tk|1W0W8&W#jgz?;{k5W)+ZvDBAi4qm_8ADjGW>>cRaLGGyw zBn!c&)DF|XN%kCOyVt3fOoW7*;O9M3nwS5U~NN>K7?RU z2$;{BdzMkRUWJ03l}WcP(e^@Vo6bgByY+4JmHB%Sqljh^(j1)==tjS}NE)R!dh{-Q zQdx2^YI02>#D_MQK;iJvFY42@NmIFVhJZoCvjsLl73nu&52+arzQvu#ya-3OG5Z?( zf#YTg{tWi$VRtH~l@!6+c`z0p?ca;F0(pJ9V782Ej3-Brv$ramSB@v&=95o6OC@h7 zFUf3H8(V?&%r=%4FZ$p&{bKk{*f%M?g{rkD)(dr?Up09xEsvA-Z0TV4(mchp9hp&A z_4Sm7wd%XKR>wf!pO(WKD5iu)l#|Rv{3$L&v|jv}tP7TP*FDA@f}6VlPUrBtl;O|( z%im&BR%%!LO^}vGOU`h?tXT!rawihcet>uiX))HGDmmEo!82p!Vd{vh`HtFVu6j>F z+Dw@a`s8RMNoVepJ6IJU-*ftEqrjIP=oFPznrT)91a8)~Z+4jv&5%Kv$r0u9J`3XY zGDuc8m_~;qT3e+)u{3TtysKW%&h%v$n1Ufuq}9+ZU-!#PDf{jvv~(kZwqZUHbeP5O zRd4fbu0#sNr!RfxK~WsLFAeb6cGO_6zhszP@XOCovBDe=AhA!)CwUG!7tF69>Lfeg z=S%w&f_8YY?IL#dbwL9Sy)yl`yl#N(c`b9ZJq^7Yo{BuJA~`z1PKm?a&!!XQH*n>7 zCjCYX0GQ~HrmU{~QP17JLad;AKK`PnmexCmvS{@AH;~!_bz0+36Lpbhxp(sz;&NNcBT|I&7n_89-1!8J-lAT0d78iv1;0^=>u(=SS&g=@pLm< z=ou+SEvAbV$dXve25;p$`0_OAmMRgMzpOm>CUyqp$zN`_Q@B*krCn+lziSq~33!4Q z-mh$AZa4XSvO@@4fe9S$b1GwYU_k_^%QM?!ccZU@Ys2_)`Rtx*IhnSwKJKpQ?2lDaPOWH~ zRiSTSy;*InSkS_YjO-iMki9E6S0~bcKUQp}tQ`1fxFc0I`sEnXc6m_xt=Vv(9AxVd z7cK6Q4OEj=uwa2(0@}^&PF<;U^_FPt?p@_gZ^?k%#EHu{x&=cFcW-i~* z`yV~G97;&c#ef^NXJGyrJgfcL@4(7Cj8Yv7fUI1E$`I3Nd2NT^q+e&t;L?wFy(bHv zTR?f0xqrOp{3v%?4L-YlZ-%eILey%t+T_y-%Tz_wx3^}4vOkI_J0>bDjFMw5m3Pgm z;wKNO>N-k{wiOXUYw42a+hg8(S%^Dz45e+FnY={^u-lwQ7d=J#a6|J85FG=@QeS!2 zO@PyfcMop#w6lSe4|t)q3hJ>tSMQWTJSO@Fli=&S#|{NcB7|EMxyNwt}zjL^otA(%}m@d4e`^HUiv@|g5W*Bp7X@YxK zrrLG@K<4n*L8fkmIwT8W=09{=NUL_XQgpc*dTBmt?e(gX=!d1$?a_05YSpHOjA4er z%`YkC81>|r_gd9%KG>y`ci9Wd3UmQNIaKwXomT+-F|{1L9M8!Y$vWuNo^_~Q>mWK0 zl299)ixHWt6?wV?-F%k_%l^Dp#dC2IkCnF79%TCpmxN>rjp~ zd+sAWqnW8wwIYSC%Xh>|^*GO0$Q3pLbyRRyPz8DK2UBkX2wU)Is`nd3VDWNcBAco=Ll|h*#1A)Yz!Qd(aKbdEgX>YLl$sQXZQ}c&2LT!;>ZMiAhE`W+O8K&tJCGTHO_?B`n%K?nMVP|E3{5UnZX;SYESl%J0x;b~{ z3UucIv?$)I7XBfm5Fy|3hk*nd)hm1e1F(NGVC%n9cyWK)Ppp?0*~})+wO8zUAd(qTepPKYn&A3LqhUl}u(L z`|Vu*@k2|1KGdLU{I^N|+Y=RLNvTPn{jVv1AHx5Q%IQY^*9H2&QTab&RAM?nWar|{ zr#^y%3v9+|LKyHRRxc<&_zqw+`J=BFJHiqo!u*k16 z1pV&%fIvf%5h`e0?%S4ca>DYyVZ{PO>$8tM>c_D7!D9Ru51rcjydLFY&fQ7`hWCl> z-^|n>1F!JtZ0-#PDFJSW=kC{?fg0GYb@>y_1O_NQQSX0rkoRm;4S=Sz{6G3nqfQR9 zCeq;v5K^Fkk)0sWr*a`a@ZoSB#n#TYV7p-R6<-6}dFh;7*Y0JQ?T4NQnI9DNLauR* zqw6Hq?SN=N+O|+hxddtKbFN;WSe>L|QBV#=AW5@1do?mn=#~?m|1fC*h<$4(XW^NE zWy7^4587&~n(aY;+pnFIXn!jjp~+s~)iJ(ACy5IbmmHSA)rFIy;&ICe%8P4wsjyq4KP|QTa_ySn&}iI3Ka^)6FB#elTh_SXbc%4p+^O9N~?_d ztnl9n#+U%?ak{Tu?U@DJ8U%CDlOyYq9FK#6fnr5JA|aJ1XfG|{S2ybb|M%*)Ift1b zjzNA2?t1WB{p?%)N?UUy;MHaQLgSuHJ2tma0GZ|uyJLaoS}DwrR!fO9%KA##z~RA0 z9e|I+o!;pW2PzevyJSs;CUn3Fv>;h?#LI|h)Y{{lwvgqxzv*nkuE7pz~|P% zaXuYpvL2-rMq@r;1DQp&D)%{aikxEKLu?wM{y5Z@Lh15AIQ_d z6VEg+iKv9FAo0mj2ywe>+10KHHvz_SA?? zGXgO{X(Gwukn$O^M;tE}P`YsbR%QTXSOay@!j^~qinpts$FDwx{yGU5p-qUGWYEYQE>e{8gpuj|#Ib<1x}hDEAu+#{1_{ zD<=EZ3oTc-Yl4PNN}7)C3Y-spk{7++tF=+}yFjq5-YCo=f^{uLzK7Vn!Y3!cnXEUo zoj_o!Il{e>a!01{`SB$s9?ty}g4Z^R7Jqk>6r5iUo@xOA3z*dv|0)aVhOcoZg;*p2 z#XEXj6p|<6lUuAz5pOkF*$o7gb$l{uLGr#OX2(kbxFS3oekU)Dt^2Y(`*$I=mG|kF zM)rq87`o~jWWEaYE?-jh75B$D2iA@}*u_xzFw1b;^_X$gsvE@~(Z16F5^fwCu^wBh z)s>?s7CJ5w6$5}) z#kWpb3bAPMk01*X+H3r@PO@BiEPndJbOL;psWO~EIvPwHpN(2BT2PNRirzjZ=I01} zuKorQ;&at|`jIqsf3`v3;bqsF@>e+hDgzdmglZTKe=j|0e}sl1)DDiofmhb9>!O2m zBQ?}@1D=xrxh6Nbb1$y;u1RgRD-DnC!PR!dhBy9@SK$Xg?l78>L^AP7sv9QZ(_V== zyyC)Za@MMrYlmr4cgnTik~v^+``)9I+wPKJGIz}$hQzw&D3g;wC;2t=>-^G<4lK!a z0mo}4T~fiS@AK=>fT&HL&vumu=(VtJL&v8*aLG4F`zDJZNPCwXsAr#Y43B~#l-=_I4HH4}GTIcu2!mHXj zNzfx>(%an~79(lNJ#`t2_uS0gIB?wUK5k6x#loNPz)h?`{sd1yX`D855>C=3Hm2;dr z0Cr2<8snRhEcI>^;4#a|^moqGpr}_yMVhz2o$4(5bG=p~5RaywhmB ze7R~=2=6`2*bWdaDm?yV)afY@?P$t)CmD9oHT^uARrKJc? zaLGH%kE``bVDH(LT{y*50Nm|3SS$;viSs^ zNA?CwGX^}rQPPV$!7h(iYDDknhj!e_3K}tr-4mur7PoPh9zyvMYh|yGlEnBQwVA;siiZ2Q+Xr0u$Kb>He&VI$4CCjK$MC`HN z%Z#vgxHrV#(#&)XP;%!U2>{8<5>qB>sSuRgmsKH%HG3skWVSJ>I$yW#hDYDUdqSI{ z+H2*m=7&u-BXum9ZVc_ts{mno?gMnH#|l3^ns;ejNs!{ogWfjL*B{aWr1LzGuTBA2 zAWP|D1m2jvMh{cFl0N7msDHiR}R#c6ci-3A$);(;`@XYCQxkZ7_j}Y zI&MYpZgIu+gzEF|%~8sK9?dGaqgjXPnGR;0KhrQtvwD1tQ7Au>)fr^9j!-uXVORsd>k1*H{10ZEgZOI z3^+mDssF`+_2!1E;L%9PXg0T4_Yk zKBWsfz|KSTg`9cgi$?R6ll#MgHYcywae^LWdhkcbE$jHl2<9Kz}jZbhgP)Bv3a;DKLODB2bZdkP3=t)1f z5rGzipNAz_0+pc1)v%e$G+wI~g&woXw6_0LX>s>D4H*RaNRrFSz)aXW&fjIJa!vD- z)zVzuyeR1+A5l3JGIlshhxtY^!XP@ha`5tYxy|yo=~l3Po_=%no5r+#yDp*nPo;D} zQgB2R*!^^3+8y7G@ne^=qnv#UTPK2TRrW>eyc)~ik-bb5CcneiszeMP3wX43hAWIz zdF#Af{||d_85P&IvcMlNU-5Usy-~vlAf>#(>7Zt}d9_?3gYXxwW<^+r+Q9xzA7uOo%BShhdBxs1Aj4j^iz z|LEr@8*$5m2YM8Y)D6%0^ltNpefw~`oN~FlVMakJ#P>*1W%4_&9ry_w=5=C5_>Qulm$QG2z*{B^N@N8Ms$ zJI|0+?)tElsqdOT-?4$>H=f~)EADKp_nJ^OLl-cPZ0ejrfZfLQ33D1W+(ulte~x8) zOu#p4zVDkF9 z>)Xsm*fj`MFa8IH2v#gEhg)ffzwy&FlIdNlBMkaqaw^A4Os< zQKh>7$8-26L=gK5K}*jo-W<~5kpgREv5T8ORyfIRp_{9+wwQJ7b9l{WcRC79UDkb32wIhTJQ(Zt z6sWVe=Uvi8wnnrZ?gN+WT*&&{7#sT?EZmqizxd|JBWFF)CwGxl&P8AD%bz=+eNm3c z>_EAWWz$+&`Mz)Y$ylGdkcj53`*1pE60uxk)qkh~<2P@V6y9&p zfLfo*(uMwvgT34KJqKyjRQC?ItwmsaDV*tt_3YjXfOcsg*7wEssNH!R)%A%<`h9S& z1J#}z;riiXEh`L+@Zdf=tlwYaLF_b9859J2_6*o*1#*QkKE1QXrBN#sW62aN z&mWQmzICg+tYnPZP%NR@ytEscQhJ{+P~#Y;&DlfqICLqPGyks7Adp zT6fQ%wZQeG{Hh8bzd5Xs%_JSm;4V!cZ;onb|Aan%3_a%c7$dDveMX4bWj)2qleUUz zh1l6abh-~r9RV)^1ge0uC#v|b^jP?fK}pN*-wwfC~FJi?BFUveRAegN(mSPh=Xg14nfN%B2e=^2Hww z^fbxG*GubH<{K~c_q+puz3bp3on1SfmH8l^0*hhqdXD93xyH_3Cq+Z{wWhPAG>1iP zuQUiVmaV5@M23U2KKqGCO2-8|*lm5*_u=ay|M<3-Er&ta7}Uoe_=>l{ZOj*4=-9P> z=&G&a?GDW8_Wv8Fdk^FK#8E)vKo76`PK0MV@e<53G_aWfyQ|Sl54X z7s*zNv=J{zbQPTyjdx*R6m3MOUH=i0gfO^U;$cg&?c{os>xFuCbkImOsWUekT@jr& z9GpH!9|0lSLb5!c*DeA6+^aTqpByWUI}Q<3@U*YI19PwSn8Z-Z3Wp`SKdZZ+2Jaez z?LJT97A!bu?%|GtH)=_P8E<|8|A!h>NDU#YnS6&|>EWZ|>J6 z0$-Xkoo=KhoS)wAb0Q6QNiHK#f$o6{{kvtWj8+dGWSk9cTq-5QD;U05hfnTX_lN6VLJI~h#f9-t8 zi{5bvE4FM!Kt0HfTFJ;nkXqlq&8q;P9eFcUyl`>H&B6LGc7{>L*-sR;H^wRo%gEc7 zhfjN$2=PcRXeLt@=NrC9KHxx$CdFB_scH4gKBez}>_V6?vJ_Q1MKyMqF%E2$Q*2AMW za><#nus_wn_2qZ4?JP|itoOw5@d4-2FGlfv19?QW%lXMn49-p!tbM6PQt2uci(&m- zMk5_Qk*TYtmSc9tm%GP6Wk|OF|E%pltv@Bsc_5sStOKU6>0E~8< zcQ&0q${RVOu+HVZf_BT_Un?`vJ8fLdO{;ESbiq#siy+s1a z!wLv~u{Fln^sA*Vb63@ACAP9Pl8ig+eR6-bMp`RtRFQ^S>RxUlHFr8o`WWcbuMtix z+uqOlAJxN`>#b|$1G}<6tS>ES(@9`B^$B`712t24QKS+c{PWmjIC%Ky*ojn>YGzE7_A2U* zAeQi)rbK(on>An_eY>K=6s_WPogiChY^uN*A0%MBU3R_sDsf)EJgo2@KI)45aLmpv zg|Q|jFYfvz6$2~M9d&&|tvsrSp*l%MVI zUhlHZ)jfYQ0u&-XqVx0d#PeArbL}REFLR!6W+5Ji+PCYZslX>r(kCR<(noR2DJ%;o zJP!DQxDdKr0^&Gr{qH&48$Y!{+KS^{JF`u@RyLGFpYBgjdx}ZtO!Frv*KACN<(>JH z=eKwAm>_vN54~|3PK~}4B}`IV!k0!gCi67#bY}*B*phu3b8b15XvaErC?MrHX76m1 z^e#V#bLGlOPwU0}s2yp?VL>Fh%7HLsmHhKKgOvX|U@boqL#F+sH||w(pg%U>Y0u9^ z|3!g*gxt{}Y5D}F`^e)CDZuK%eEdr#1xB|{srSMH{i+6E<7y7ioFMYvy4J;10+nLs z_=jXAQX?+9x4eCtAJ+5Vy+NQTx%Ht$DD0w>0U-VUVTu#2=Rg8@L0 zduhUX%e&(xF|7Pw${j3T*OOX`pPHc66i{Z&_wG?r&f5b-eW)e$vizML>zMz9a6(D% z-72et2&9hpE$ugd6Eh#+jd>q?=qsKYi7Ar25BDFHu zLOWaw-2=RK_t2?ogH$icx8 zerW_+(Z7CL`2*j8+g5a@DK`>g!zhZ$jRhT<3QBMFAMXzx28RY!B)9An55SQKN$ZbI zI$7A#ROS|}M?)U~3?Iik?seObar5`PQ4`NvD$5??z95sYD%18Jw$Pzj>-$y$&2~2W zP!rBFq*y*8DhW=XP`{?|7Ui#N|9;1}5K_`&AJ`Y><278Fq5F*e>RQSXiJvFIjzR9O zUTR|FL8AS+QLie49Unwe#YJM5vIY+FovEP>)`DXnuNW{XdWYi(SM_XGFi@OGcw|$J6Z2bX|eqfl()%N?q50dGnfem93X)# zUcvgit>HawVBU;7*>$pSyh#7MLH@698_!dVig#7GwR<(p#&%hiS2AgkUiZ|FVdHVG z`89eMP+sNil(t!fyzf8M9Eq_;`qb#c8ViU1zkR;b!cJ&NL!hYnd~B)1=@608JVH>$KcW5F*hQLfC|r+HaqG-b6KSLt}&!D?65HLqbBF9k-x6 z-#&y5-&kZALf?hb(EVmB|7krxVZi2-6O^3(zfJi6-4~t3Hnz?x*&H*J{X3iSFDpXH zgk*{K3FCwN+rO&tKWG1cFEqpfp@9E?z`qmm|A#fCthR26vaJk}gmtvMb6+%U62}-V zl?ivp9~?^;pjm#dNAthS9;O5f`DovN{E+q4Z=ie7-xr&#J_0~k!?R5$7p=cKQU5dy zzb*phUSe0)+Z>vi5hKF!2icSGpJ>N^i$a6TDoeBNWuRd(h=pac0ova%<9 z%okf+g;tR8gGv&UkHE21gRHnFz zvm7l{B*&uqzx?kT$**M*O~er$h0E&kdb5ZU1$#r&Ot`8N|z{f<(Y)sSLF#F!ben!8#9;u<0BPiXO}4&Kr*lB z6JubG+u7o?KM!z;mNz5Ek*<^OS?68hEDnc3lcmd9M)mo#Y>nEZ%D;A~f1CWjZe|rc z{}dBL(3XW8^I>v>i5JOsy<=5>*o+WfnGK+ zm<-Wd_2e3>AF2n1gh=iRZv8CrWtiL;75>-!{%+DRC*tf!i(@HC3`#iDdY~^XOi~B!MK_-g{Z30{Q#mpl8AD;jYUE(wBz)KZ`QTzWsAg!ik;Zgj5d2g8H zjJu~^)Z73w^Hq97r?Txxyi9uqYW#bp9BQ@Ki#CO)e&*q}9lHNOmO?rT*GdN}{ApEZ z(*WEENc>oY=*EN#_ZMG9TW7EBxR7S9ohI- zB}G;K_Ogj_JG&Enf_mOl>L4>M{xpGE*NE`^j2jG~Ctyob6nUU69~Y31ws+T76jIC} zK%ardm@v=(l^!%GZMh^Q&AF$V`{ds9?eEsCT9J~J25xL`CjMRIF>dMh34XxFui???mge|32{`y`{BwOD{8W-Qgi}4()E~hhsSAJ4+?aeAz z%N`WO2&DQ5EW5iq!_i~{Bdp0p`xUMDw(G1nH^?9KbgfHhY1vOptEyz2on7S52-Xt$c;o#!Xa&!OiFRSw)On-vW;IkYP6BB<~#{~jfvH>KQ4_k*RU`M9J7mmlV zt?4s^59U5!u`m2?(z;mX;P(A`&W^&K8*8!QD~O9mu5l?}uX-*UOdVCxIYY>V-n%B8 z^m;>jmCTN|t)?EPBJz%Z0GmPI>tU-yg}WzoZI}$Xlyg}b9^M^tk|t9ri0Xhrs%0Va zBe(St7P1#x(X6%O6%Fru?Je}izc}P`%;*=Nenr+c9jBN85)F#pKe{A#e_Z%kMhj_9OOz!Xf~D^h)<;COPf{@=?G=+wQ) zI+t6X^5IPuRhOH$I&`S>;XzNc{WRRn9HZo&8#7y&0{%vANNf z)(N0JT*m%2U!Y&|uOm{LcjbsCJGIoQk+G3EV59?`w)ge=j_&f^O$@(lEiE<+!o$?v zQDL|buQ))2Ml|b;`X?M)fE@}y&(}tn3g>D8K>-gDlW~b6Wu1>VjrZwIsIdKh0m<6p z!@&70+t6vNccL|7@mCnTg_GTMu+K8^xu1%Le8_RDGmp(P`|PBHJNgeFt!^-WFf zZ5KVxi#E?Zc6cIFhcy;K37HM|On#v&Y&M48iu{lx`pinB!xhr%op^47$D={hwqq)x z)s-L2W&=fM)*rQLVbzMsZB1s;>qRJ_z~|a;)S?(Y|87U5TtXVUm|DNTz_0WOcq0V| zyrEQudydF086+PID{16;3w$1xwmhqo`~c~ko&U7SBZ>19cSRGmy&|U{b@jQ&3XBx| zasnb^kB?{PHZ-L{{?hegi>aS^bx})ETk2!iB8yTYxDiI(z{qL>hW%|QfUr*s=8$*YOfwEHGEtD^p?_Z98TqceAn|LPBS`2Q; zD}XKUUZ={nnJ*@s7=A+LO+DIsB5E3hd;N5yfID$I;j53f_Zu`fRxtcrSB+EOcP-g@ zH8Dvxr9kT1LGNoOjZkS^jY)>LjsN9h()lt)z%M)ZWh=&>uF<`D3@_bHz;jz%%{;Xs zH9m=c-EPU&{pLIslxLGEX6{~@nDz=+`YB_*|H9tq^Fn+_U(Xrk+J`7C(9i*aVPcYD zfV{J_^UkUGvoD4Q4hiwm0wps}9Tc%A?}sAkqr&!qMt(G{vy~Q8Ci;uJZ}}Q$tvXtt zBpAhvWw3ea&QogjKQt7S0bUth1j(ju`gFyGQCPpZuBhCz$UD&PxJC8?Wa78cfVdON2kyvh4u@+X8)KuA;@Jpp zw6N;Q-rV9y5`ZkMnS)tCPbg0Mz)eWPzH`Sr7m!xG6(A2>D;O1#uPq3Z8CFyJLY`iU zrOn=uv%>D1$CS(gVZ2cQ4kxYqvbk}GV6+t~3EUtxAJjwyvko0d1p3(S?S+l398X-~ zXg%9rf4rCfD%?7!4~h|<_c?}$Y-jb|4S((@ed+f&|ARp$-R_pP^I=Ya(``=h=4jXf zX>D_$)v(jhV13n0yK`BQ)pH#y)BmQPGT^@78}^oODNT8H`t3OGtU*Jgr(lD1v`Qac zeC{WIS=n~h@M`)d+LZ%457~RSIca+$m?Wa}ZI3%#bF&wx`EI;-r9VTar8g;FkFXqQ z*gYu?%mo~`t!yONvpql-@Yds%?6BVf% z0T?h2Fr2zg(Nn+*wV(I6bjJGW*h^v+Y}~cl>|((lCSjY|d)b=bA2mO)7e*1kX-dxN zrlb7W#W>!1-tx+@xsUMasSr~4eR8%7WSXtxOWVD#OQ+%F?c3&~9GCX6hZ?X4Q2``N zWYGn(%Jp)RtRgi@@FGnRa?Wp+4SvF3?{L@>W8ej>QrQ&%XTW<5kYl;mmbQbk{pr1) z&4es-Eg?cKtNa_2XDy$MGeu%arAlEzc*bu7+gob)s&Pq^{<;THN}<1Txj`k)dF|Xa zhlE!5SWy)f3YS#crkO~$s($k{1l|m?dNBN?vV*GB$X7$N=x2G+KxYoB+-xhzXCluU z@D>f@Zk1$)cZic=DuRIyEhia-L6n3ahuYE(tL|f@FuN#m7z5uwFXre|N;iqb zu_Pd`aXU04&V>^+&(y7!BPa35tb>8c^Y;BhoCYT(ygwM!RM_z_SQ*ALG|e@`8VFj+ zO|{;Nh0jnc`-*j;gc59%OLvy*s=vdCYP&~x%^PjGBynIl6yFM>ut=zvc@m$PNb{|K z7kqwrzD@HC126I2XCz(*>~6aQ+>16z@i@&Lpiv`6!nP8tA*%~MOT08i+dRWc8WdHx zkJQS?&%*`UqCag&#KTrEfLHPCT{7$RE-Ma0Jr(;xmM3GvohOTKhun0Ng2u}W_z$h1 zfZzlI=hniR67z(_CM}p%B-5fl7~I}^WMvu^3)+e)6THXylyq0dnFR{t%ZDd-qgjVu;Htl!mA zuOLYlc1EXJKI1ub<5M7ARCMigf%SK9c4e9$N``k(6oZ2;h^h0w#DCdFbe(K<&!o)C(5}&N2Jv&m5r#05AZY}_jb(c206}5x|TS0I0 zX!@ey-T6eW5*p@0=DwdrBD8^J1l2dDi#^QF{lrut!{fRlC~yafJB!a;PxI>`BxV(8 z%-wPWgBct-Z$Caq2o)T8&fD$lYkP&jryC_>F9mSyh);tG=C50U4`w(*;btnW{6>owR4DZ{4<2X$8rc*7nu6S*K!lL!Gt`DIW?|K)NekOkqH2}9w0(PoL>I@S47D#im2=z98fg9wmxD4Ty9r;PkY{rV2 zg8OqGu^d^nw6p^=)sQA`s`bYzoiS^laxYDx>~Xs7@O~j=^ZTequ$JkHCQ+`ht=X5_ zxbBkgVb9^@AkAw1UQt+|em3WAjUMP^(v{+mDAP#GB?ECItJ_glZF1yKI&#C#g2K9= zg;Elxp{xnajWh~D77Qxdf2vwEim`3!pon*Q5O3l{ZV2}_Wob(zi9as4ptxv%hrkDT zHf&{xyGB=1b-91CSOWO;574{@66LaHoP}}o4G1!G0R3_^pQ@X8TrAoz>l8kxZ0biq z$GaPi5m*|DctK1SYKh1j=pnpaV6&XGNP6P&#X_NRN3fZ zf}y3dW0m$ZKalZvf1Eo;Gz$%(@n;Y0VvuMOTe+v_6`14!z=4ofu#c&%KE<@M$>Mv~ zT#j^@$|cgDr+Uga;|UNcGla$#TD-$AM8F=}_1|CDk+xtjO zTC-7&?%Y@WGUE^nvL;U_#I8VWDS@8zf=O+I&+o!b%c~UtVacI5f6`FuWC1u!3)2$F zK~BSA<*kF?As-_{$+rM1y0t_$*>Eq%C$!E-{Nlqde4YN;+hhCqTqEuqsb5 zzq^y~5(VMDb;eLVA4$oRyRKzRBrwu*h&1jnTv966HhoG|gkcW!gNxZ#SpvQ+VNc@= zsAekd7f9t9{&We*5ztWk$dbV~$gr6%(9OW^z5v&JcJ)BVZ+ZNF{B?J;l4O#L`pqgV z5{{%Y-bo>dIs-1&v!%L9$P6Z=rynjMVB`dQEY&mo>J7zvSI>}!nC=J9tpMVCpOTqa{ z5m)Frw7et#c3o69o4~Rvki-7`8tW|6W zd3Na!5T>Vsg_YfIjg4zJqS0@T5nvesUaefXhu7l@r@kN7xGFh@z#DRgpZV;u;2&C2 zt`}ahP(x!rNB7)2VeCd#it?TKHY^`s3qO&vZ|(@@K!P!B7G|*l&2?{qY$rfwKTPBo zH}B5L^fcY0^=Gmpn&*LsE-i+uUx1V+UX3zH>pa)Vzrj*j-Z+j@sBgxNJ45e^)C?AF zQO5kNmudnU&r{qB#L}KQf9Xvn2y#W8L)#F`*xtC2^a7ZlmZFk?{1|HB?UMT4y1Zm%4TLI;Jau)Du=n zjt#hboIwuPi^@p1SkSLd4ZXZZ*%7iLe0GO><4tS-HK-TvJzZC#hh=>y+W!)vVkafLnoiP6qKUC>YE3 z=>ki1^6k0!$e3SGy`?eg9KX+nT_4AE>OVvE@KxGK%k%MhG+4oV{}7Gk?x*_YaTp{2m9tnc^9&<}-&M#>Q&PdKD3wycdo=>Tn_~~U zbyy*4iL+3})^sD%^8{RRAugsn z8r>~eOh<%#6mx6*gf`nzT!5m;LhySset#L-mIz*&y~{DnZU?~Wy>jN4fynce;4`e7 zwX9cCYd#lK>e|ZQZyT=lUCP9dpX6b5-@hr)u~OQj@V_N$MWg0l+0IoGg2<(PM{d(1 zo~d+j2IZdeVq8n9W-WZLmn3G&(-bp9iKISeYhQ2;KJGZ*Cs-%^!HtQ>P;sdAZW>6i zbgv$Pc841QIO}af*S)Fu$Te*t3IES_EKq~ocg2Bb0O+eDBd+Y*wA4%2= zn16hPEb~lafzlxT#Yh~zD_Pz!x7O0^8bl_5Ug*tx(PVzcwXvq( zQiin3rs$#;+e*er3yBA)*YkvTH0r_g0XI?orqyQ;ccE@y=eEuOQh_mH^sh1D7dpW= z7GbkmO{j~Oq3No+D%Uq!89#FdaHF-nf`~DyX_c9>Pnp9xf>{#sPLEJ*7@nEriA~BG zAs4sr4up_JizZ|8IX<37KPwzpjwv>3tl;}TI?ShUKY;iwgmqgP+*9$Xi#?={Oh&67 zBZ{=&JUbr!|(s+NU$d8Spn;lL{%Na8h>YPD&mKV17xVH>biH!*h}&}RWlLLI+Y~ePHG0OX@=~uS>PznH zn|QX4vz4t5t1rHgej&u}mC(&`7S16E;T@l$8m7)!y`-p0z(aCjsyA6tQV=l$PYz;e zAmi%{uCSlp*Wr*wT|u7pe`M02RfQUd(C@1ncG^g%pK>TUSY%!9yet!ydX02yyB>-u;7= zQ|q$!KT6Y~PJd&LKj18Av_XTLy}6LyFwD-@iD2jXp-ErO1m#GH-BwDA9aLf+Mp4Ln zeYP8-%;R#}oq%{eWnd>_4&q|qU3Y4HWdv;-OcaJ@$LX?PU#jvANQ>OV5`)*#M8z4D z40J@%GlL^DHV=9WE_7+a;zGL?8cX7_cO#51HZ_%^o(wQQbGTox@3NQNNbLJFQV2HA8KWu+{w{{gGaI$S5zQQbnCG+>sDa)>geKG+!sW5Phj7 z1FW&UVY2e~7qBY45SC4B8K{lnQPLPcUlVFsD3EIh)dI=;&^Yrz<>oo)a>v^D@Z3+B z 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 literal 0 HcmV?d00001 diff --git a/source/includes/figures/atlas_connection_select_cluster.png b/source/includes/figures/atlas_connection_select_cluster.png new file mode 100644 index 0000000000000000000000000000000000000000..52d827d67bf9a46e30671df001d144f4538c4695 GIT binary patch literal 35481 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

4N?~)Xc)h9V|#8Xnx^ocodOvO(h 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 literal 0 HcmV?d00001 diff --git a/source/includes/get-started/quickstart-troubleshoot.rst b/source/includes/get-started/quickstart-troubleshoot.rst new file mode 100644 index 00000000..7ad83bce --- /dev/null +++ b/source/includes/get-started/quickstart-troubleshoot.rst @@ -0,0 +1,6 @@ +.. note:: + + If you run into issues on this step, ask for help in the + :community-forum:`MongoDB Community Forums ` + or submit feedback by using the :guilabel:`Rate this page` + tab on the right or bottom right side of this page. diff --git a/source/includes/quick-start/Program.cs b/source/includes/quick-start/Program.cs index a050d16d..62da7c08 100644 --- a/source/includes/quick-start/Program.cs +++ b/source/includes/quick-start/Program.cs @@ -4,7 +4,7 @@ var connectionString = Environment.GetEnvironmentVariable("MONGODB_URI"); if (connectionString == null) { - Console.WriteLine("You must set your 'MONGODB_URI' environment variable. To learn how to set it, see https://www.mongodb.com/docs/drivers/csharp/current/quick-start/#set-your-connection-string"); + Console.WriteLine("You must set your 'MONGODB_URI' environment variable. To learn how to set it, see https://www.mongodb.com/docs/drivers/csharp/current/get-started/create-connection-string"); Environment.Exit(0); } diff --git a/source/index.txt b/source/index.txt index d852dbca..72444317 100644 --- a/source/index.txt +++ b/source/index.txt @@ -12,7 +12,7 @@ MongoDB C# Driver .. toctree:: Previous Versions - Quick Start + Get Started Quick Reference What's New Usage Examples @@ -32,7 +32,7 @@ Introduction Welcome to the documentation site for the official {+driver-long+}. You can add the driver to your application to work with MongoDB in {+language+}. Download the driver using `NuGet `__, or set up a runnable -project by following our :ref:`Quick Start guide `. +project by following our :ref:`Get Started ` guide. Previous Versions ----------------- @@ -47,11 +47,11 @@ deployments running on one of the following hosted services or editions: .. include:: /includes/fact-environments.rst -Quick Start +Get Started ----------- Learn how to establish a connection to MongoDB Atlas and begin -working with data in the :ref:`csharp-quickstart` section. +working with data in the :ref:`csharp-get-started` section. Quick Reference --------------- diff --git a/source/quick-start.txt b/source/quick-start.txt deleted file mode 100644 index 96690d2c..00000000 --- a/source/quick-start.txt +++ /dev/null @@ -1,134 +0,0 @@ -.. _csharp-quickstart: - -=========== -Quick Start -=========== - -.. facet:: - :name: genre - :values: tutorial - -.. meta:: - :keywords: set up, runnable app, initialize, connect - -.. contents:: On this page - :local: - :backlinks: none - :depth: 2 - :class: singlecol - -.. include:: /includes/quick-start/overview.rst - -Create a MongoDB Cluster ------------------------- - -Set Up a Free Tier Cluster in Atlas -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To set up your Atlas Free Tier Cluster required for this guide, complete the guide on -:guides:`MongoDB Atlas Setup `. - -After completing the steps in the Atlas guide, you have a new MongoDB -cluster deployed in Atlas, a new database user, and -:atlas:`sample datasets loaded ` into your cluster. You also have -a connection string similar to the following in your copy buffer: - -.. code-block:: bash - - "mongodb+srv://:@cluster0.abc.mongodb.net/?retryWrites=true&w=majority" - -Set Your Connection String -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Run the following code at the command prompt to save your MongoDB -:ref:`connection string ` to an -environment variable. This method is safer than including your credentials in your source -code. - -.. code-block:: bash - - export MONGODB_URI="" - -.. note:: PowerShell Environment Variables - - If you are using Microsoft PowerShell, run the following command to - save your connection string in an environment variable: - - .. code-block:: bash - - set MONGODB_URI="" - -.. important:: - - Make sure to replace the ```` and ```` sections of the connection - string with the username and password of your Atlas database user. - -For more information about connection strings, see :manual:`Connection Strings `. - -Set Up Your Project -------------------- - -Create the Project -~~~~~~~~~~~~~~~~~~ - -Create a new directory and initialize your project with the ``dotnet new`` command, as follows: - -.. code-block:: shell - - mkdir csharp-quickstart - cd csharp-quickstart - dotnet new console - -.. _csharp-add-mongodb-dependency: - -Add MongoDB as a Dependency -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Use the ``dotnet add`` command to add the {+driver-short+} to your project as a dependency. - -.. code-block:: shell - - dotnet add package MongoDB.Driver - -Query Your MongoDB Cluster from Your Application ------------------------------------------------- - -In this step, you'll use the {+driver-short+} -to connect to your MongoDB cluster and run a query on the sample data. You'll need your -preferred text editor or :wikipedia:`integrated development environment (IDE) ` -installed and running. - -Open the file named ``Program.cs`` in the base directory of your project. Copy the -following sample code into ``Program.cs`` - -.. literalinclude:: /includes/quick-start/Program.cs - :language: csharp - :dedent: - -This sample code runs a query against your sample dataset in MongoDB Atlas. Run it -from your command line by using the following command: - -.. code-block:: bash - - dotnet run csharp-quickstart.csproj - -.. include:: /includes/quick-start/query-output.rst - -.. tip:: - - If your output is empty, ensure you have loaded the - :atlas:`sample datasets ` into your cluster. - -After completing this step, you should have a working application that uses -the {+driver-short+} to connect to your MongoDB cluster, run a query on the -sample data, and print out the result. - -To learn more about connecting to Atlas with the {+driver-short+}, see -the :atlas:`Atlas driver connection ` guide -and select :guilabel:`{+language+}` from the :guilabel:`Select your language` dropdown. - -Next steps ----------- - -Learn how to read and modify data using the {+driver-short+} in the CRUD Operations -guide or how to perform common operations in Usage Examples. diff --git a/source/usage-examples.txt b/source/usage-examples.txt index 38dc7079..1096d1e9 100644 --- a/source/usage-examples.txt +++ b/source/usage-examples.txt @@ -67,7 +67,7 @@ or you can Once you have imported the dataset, you can copy and paste a usage example into your development environment of choice. You can follow the -:ref:`csharp-quickstart` to learn more about getting +:ref:`csharp-get-started` to learn more about getting started with the {+driver-long+}. Once you've copied a usage example, you'll need to edit the connection URI to get the example connected to your MongoDB instance: diff --git a/source/whats-new.txt b/source/whats-new.txt index d7009d26..263e0fc9 100644 --- a/source/whats-new.txt +++ b/source/whats-new.txt @@ -61,7 +61,7 @@ The 3.1 driver release includes the following new features: in the Atlas Search documentation. - Adds support for the ``sort`` option to be passed to update commands. To learn more about - using update commands with the {+driver-short+}, see :ref:`csharp-change-guide`. + using update commands with the {+driver-short+}, see :ref:`csharp-crud-write-operations`. For more information about this release, see the :github:`v3.1 release notes `. From 48b8bec7ed034f94cb9c857a4acebc4a5f4bed1c Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Wed, 2 Apr 2025 12:57:18 -0500 Subject: [PATCH 02/35] DOCSP-48809 - Remove FAQs page (#553) --- .github/workflows/add-netlify-links.yml | 4 +- source/faq.txt | 324 ------------------ source/fundamentals/builders.txt | 7 + .../connection/connection-pools.txt | 86 +++++ .../connection/server-selection.txt | 68 ++++ source/fundamentals/linq.txt | 7 + source/fundamentals/serialization.txt | 44 +++ source/includes/linq-vs-builders.rst | 8 + .../unsupported-filter-expression.rst | 60 ++++ source/index.txt | 9 +- 10 files changed, 290 insertions(+), 327 deletions(-) delete mode 100644 source/faq.txt create mode 100644 source/fundamentals/connection/connection-pools.txt create mode 100644 source/fundamentals/connection/server-selection.txt create mode 100644 source/includes/linq-vs-builders.rst create mode 100644 source/includes/troubleshooting/unsupported-filter-expression.rst diff --git a/.github/workflows/add-netlify-links.yml b/.github/workflows/add-netlify-links.yml index cb0770c8..69377f9f 100644 --- a/.github/workflows/add-netlify-links.yml +++ b/.github/workflows/add-netlify-links.yml @@ -26,7 +26,7 @@ jobs: CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }} run: | new_links="" - base_link='https://deploy-preview-${{ github.event.number }}--mongodb-docs-csharp.netlify.app' + base_link='https://deploy-preview-${{ github.event.number }}--docs-csharp.netlify.app' files=$(echo "$CHANGED_FILES" | tr "," "\n") for file in $files; do echo "processing ${file}" @@ -55,4 +55,4 @@ jobs: appendContentOnMatchOnly: true regexFlags: is content: "\n${{ steps.build_page_links.outputs.staging_links }}\n" - token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/source/faq.txt b/source/faq.txt deleted file mode 100644 index 3cf1dae9..00000000 --- a/source/faq.txt +++ /dev/null @@ -1,324 +0,0 @@ -.. _csharp-faq: - -=== -FAQ -=== - -.. contents:: On this page - :local: - :backlinks: none - :depth: 1 - :class: singlecol - -.. facet:: - :name: genre - :values: reference - -.. meta:: - :keywords: .NET, questions, errors, problems - -This page contains frequently asked questions and their corresponding answers. - -.. tip:: - - If you can't find an answer to your problem on this page, - see the :ref:`csharp-issues-help` page for next steps and more - resources. - -Why Am I Getting Errors While Connecting to MongoDB? ----------------------------------------------------- - -If you have trouble connecting to a MongoDB deployment, see -the :ref:`Connection Troubleshooting Guide ` -for possible solutions. - -.. _csharp-faq-connection-pool: - -How Does Connection Pooling Work in the {+driver-short+}? ---------------------------------------------------------- - -Every ``MongoClient`` instance has a built-in connection pool for each server -in your MongoDB topology. Connection pools open sockets on demand to -support concurrent MongoDB operations in your multi-threaded application. - -The maximum size of each connection pool is set by the ``MaxConnectionPoolSize`` option, which -defaults to ``100``. If the number of in-use connections to a server reaches -the value of ``MaxConnectionPoolSize``, the next request to that server will wait -until a connection becomes available. The following diagram illustrates a high-level view -of how the ``MongoClient`` manages a connection pool: - -.. figure:: /includes/figures/CMAP_diagram.svg - :alt: CMAP diagram - -In addition to the sockets needed to support your application's threads, -each ``MongoClient`` instance opens two additional sockets per server -in your MongoDB topology for monitoring the server's state. -For example, a client connected to a three-node replica set opens six -monitoring sockets. If the application uses the default setting for -``MaxConnectionPoolSize`` and only queries the primary (default) node, then -there can be at most ``106`` total connections in use. If the -application uses a :ref:`read preference ` to query the -secondary nodes, those connection pools grow and there can be -``306`` total connections. - -To support high numbers of concurrent MongoDB threads -within one process, you can increase ``MaxConnectionPoolSize``. - -The driver has a wait queue that limits the number of threads that can -wait for a connection. The size of the wait queue is determined by the -``WaitQueueMultiple`` option, which defaults to ``5``. To calculate the -maximum wait queue size, the driver multiplies ``WaitQueueMultiple`` by -``MaxConnectionPoolSize``. If you use the default value for each option, -the wait queue size will be ``500``. You can also set the wait queue -size by specifying the ``WaitQueueSize`` option, which overrides the -other settings. However, we do not recommend changing the wait queue -size from the default. - -Connection pools are rate-limited. The ``MaxConnecting`` setting -determines the number of connections that the pool can create in -parallel at any time. For example, if the value of ``MaxConnecting`` is -``2``, the third thread that attempts to concurrently check out a -connection succeeds only in one of the following cases: - -- One of the first two threads finishes creating a connection. -- An existing connection is checked back into the pool. -- The driver's ability to reuse existing connections improves due to - rate-limits on connection creation. - -You can set the minimum number of concurrent connections to -each server by using the ``MinConnectionPoolSize`` option, which -defaults to ``0``. The connection pool will be initialized with this -number of sockets. If errors cause any sockets to close and the -total number of sockets (both in-use and idle) drops below the minimum, -the driver opens more sockets until the number reaches the minimum. - -You can set the maximum number of milliseconds that a connection can -remain idle in the pool by using the ``MaxConnectionIdleTime`` option. -Once a connection is idle for ``MaxConnectionIdleTime``, the driver -removes it. This option defaults to 10 minutes. If the pool size falls -below ``MinConnectionPoolSize``, the driver removes *and* replaces the -idle connection. - -``MongoClient`` also has the ``MaxConnectionLifeTime`` option, which -specifies the length of time, 30 minutes by default, that a connection -can be pooled before expiring. - -The following default configuration for a ``MongoClient`` works for most -applications: - -.. code-block:: csharp - - var client = new MongoClient(""); - -Create a client once for each process, and reuse it for all -operations. It is a common mistake to create a new client for each -request, which is very inefficient. - -There is no supported way to terminate a ``MongoClient`` in the driver. - -Why Does the Driver Throw a Timeout During Server Selection? ------------------------------------------------------------- - -Each driver operation requires that you choose a healthy server -satisfying the :manual:`server selection criteria -`. If you do not select an appropriate -server within the `server selection timeout <{+new-api-root+}/MongoDB.Driver.Legacy/MongoDB.Driver.MongoServerSettings.ServerSelectionTimeout.html>`__, the driver throws a -server selection timeout exception. The exception looks similar to the -following: - -.. code-block:: none - - A timeout occurred after 30000ms selecting a server using CompositeServerSelector{ Selectors = MongoDB.Driver.MongoClient+AreSessionsSupportedServerSelector, LatencyLimitingServerSelector{ AllowedLatencyRange = 00:00:00.0150000 }, OperationsCountServerSelector }. - Client view of cluster state is - { - ClusterId : "1", - Type : "Unknown", - State : "Disconnected", - Servers : - [{ - ServerId: "{ ClusterId : 1, EndPoint : "Unspecified/localhost:27017" }", - EndPoint: "Unspecified/localhost:27017", - ReasonChanged: "Heartbeat", - State: "Disconnected", - ServerVersion: , - TopologyVersion: , - Type: "Unknown", - HeartbeatException: "" - }] - }. - -The error message consists of multiple parts: - -1. The server selection timeout (30000 ms). -#. The server selectors considered (``CompositeServerSelector`` - containing ``AreSessionsSupportedServerSelector``, - ``LatencyLimitingServerSelector``, and - ``OperationsCountServerSelector``). -#. The driver’s current view of the cluster topology. The list of - servers that the driver is aware of is a key part of this view. Each - server description contains an exhaustive description of its current - state including information about an endpoint, a server version, a - server type, and its current health state. If the server encounters issues in - reporting its health, ``HeartbeatException`` contains the exception from the - last failed heartbeat. Analyzing the ``HeartbeatException`` on each - cluster node can assist in diagnosing most server selection issues. - The following heartbeat exceptions are common: - - * ``No connection could be made because the target machine actively - refused it``: The driver cannot see this cluster node. This can be - because the cluster node has crashed, a firewall is preventing - network traffic from reaching the cluster node or port, or some other - network error is preventing traffic from being successfully routed to - the cluster node. - * ``Attempted to read past the end of the stream``: This error - happens when the driver cannot connect to the cluster nodes due to a - network error, misconfigured firewall, or other network issue. To - address this exception, ensure that all cluster nodes are reachable. - This error commonly occurs when the client machine’s IP address is - not configured in the Atlas IPs Access List, which can be found under - the :guilabel:`Network Access` tab for your Atlas Project. - * ``The remote certificate is invalid according to the validation - procedure``: This error typically indicates a TLS/SSL-related problem - such as an expired/invalid certificate or an untrusted root CA. You - can use tools like ``openssl s_client`` to debug TLS/SSL-related - certificate problems. - -.. _csharp-faq-linq-vs-builder: - -Should I Use LINQ or Builder Classes When Querying for Documents? ------------------------------------------------------------------ - -If you're used to programming in {+language+}, consider using LINQ because of its similar feel -to programming in native {+language+}. If you have prior experience with other MongoDB drivers, -consider using Builder classes because of their consistency with other drivers. - -We encourage experimenting with both approaches to determine the most suitable mechanism -for your purposes. - -.. _csharp-faq-unsupported-expressions: - -Why are Certain LINQ or Builder Expressions Unsupported? --------------------------------------------------------- - -Each LINQ or Builder expression must be available in the Query API. This is not -always possible for the following reasons: - -1. You are attempting to use a {+lang-framework+} feature that does not have an - equivalent MongoDB representation. For example, {+lang-framework+} and MongoDB have - different semantics around collations. -#. The driver does not support a particular transformation from LINQ or - Builder expression into MQL (MongoDB Query Language). This may happen because the - provided query has no MQL translation or because a feature has not been - implemented yet in the driver. - -If you receive an ``Unsupported filter ...`` or ``Expression not -supported ...`` exception message, try the following -steps: - -1. Use the `{+analyzer+} - `__ to analyze your - expressions. -#. Try to simplify your query where possible. -#. Provide a query as a ``BsonDocument`` or JSON string. All driver - definition classes such as ``FilterDefinition``, - ``ProjectionDefinition``, and ``PipelineDefinition`` support implicit - conversion from ``BsonDocument`` or JSON string. For example, the - following filters are equivalent when used in a query or - aggregation: - -.. code-block:: csharp - - FilterDefinition typedFilter = Builders.Filter.Eq(e => e.A, 1); - FilterDefinition bsonFilter = new BsonDocument {{ "a", 1 }}; - FilterDefinition jsonFilter = "{ a : 1 }"; - -.. note:: - - If you use ``BsonDocument`` or JSON string, then `BsonClassMap - `__, - BSON serialization attributes, and serialization conventions are not - taken into account in the Query API. Field names must match the - names and casing as stored by the server. For example, when referencing - the ``_id`` field, you must refer to it using ``_id`` in - ``BsonDocument`` or JSON string definitions. Similarly, if a document - has a field ``FirstName`` annotated with ``[BsonElement("first_name")]``, you - must refer to it as ``first_name`` in ``BsonDocument`` or JSON string - definitions. - -You can combine the raw and typed forms in the same query, as the -following code demonstrates: - -.. code-block:: csharp - - FilterDefinition filter = Builders.Filter - .And(Builders.Filter - .Eq(e => e.A, 1), BsonDocument - .Parse("{ b : 2 }")); - -.. _csharp-faq-object-serializer: - -What Object Types Can Be Serialized? ------------------------------------- - -The ``ObjectSerializer`` allows serialization and deserialization only of types -that are considered safe. When you construct an ``ObjectSerializer``, -you can pass in a delegate of type ``Func``. This delegate -accepts an object type and returns a boolean value indicating whether the -type is safe for serialization. - -In most cases, you should pass in the ``ObjectSerializer.DefaultAllowedTypes()`` -delegate. This method returns true for a number of well-known -framework types that we have deemed safe. To serialize custom types, -create a boolean expression that evaluates to ``true`` for the -types you want to include. Then, add this expression to the end of the -delegate you pass to the ``ObjectSerializer`` constructor. - -In the following example, -the ``ObjectSerializer`` will serialize and deserialize any type that is allowed by -``ObjectSerializer.DefaultAllowedTypes()`` or whose full name begins with -``"MyNamespace"``: - -.. code-block:: csharp - - var objectSerializer = new ObjectSerializer(type => ObjectSerializer.DefaultAllowedTypes(type) - || type.FullName.StartsWith("MyNamespace")); - BsonSerializer.RegisterSerializer(objectSerializer); - -To allow anonymous types to be serialized, add the boolean expression -``type.FullName.StartsWith("<>f__AnonymousType"))`` to your delegate, -as shown in the following example: - -.. code-block:: csharp - - var objectSerializer = new ObjectSerializer(type => ObjectSerializer.DefaultAllowedTypes(type) - || type.FullName.StartsWith("<>f__AnonymousType")); - BsonSerializer.RegisterSerializer(objectSerializer); - -You should create and register your ``ObjectSerializer`` at the start of your program, -before doing anything else. - -What is the Difference Between the {+driver-short+} and the {+ef-provider-long+}? -------------------------------------------------------------------------------------------------- - -The {+driver-short+} is a library that exposes MongoDB functionality -directly and includes a LINQ provider with projections, group -operations, and flexible mapping. The driver includes features such as the -following: - -- Transactions -- Bulk operations -- LINQ queries -- Operations that directly modify the database -- Aggregation operations -- Custom mapping - -The `{+ef-provider-short+} `__ -allows you to use Microsoft's Entity Framework Core with -MongoDB in your {+lang-framework+} applications. The {+ef-provider-short+} supports -change tracking, entity-based LINQ operations, and modeling familiar to -Entity Framework Core users. The provider includes features such as the following: - -- Intelligent object tracking -- Entity-based LINQ operations -- Entity Framework modeling and mapping with the fluent API -- Automatic database updates through change tracking \ No newline at end of file diff --git a/source/fundamentals/builders.txt b/source/fundamentals/builders.txt index 1876e831..4ccf6189 100644 --- a/source/fundamentals/builders.txt +++ b/source/fundamentals/builders.txt @@ -20,6 +20,8 @@ Operations with Builders Overview -------- +.. include:: /includes/linq-vs-builders.rst + In this guide, you can learn about the helper classes, or **builders**, that the {+driver-short+} provides to create types used in your operations. Using builders helps you identify errors at compile time and avoid them @@ -488,6 +490,11 @@ The results of the preceding example contain the following documents: To learn more about Atlas Vector Search, see :atlas:`Atlas Vector Search Overview ` in the Atlas manual. +Troubleshooting +--------------- + +.. include:: /includes/troubleshooting/unsupported-filter-expression.rst + Additional Information ---------------------- diff --git a/source/fundamentals/connection/connection-pools.txt b/source/fundamentals/connection/connection-pools.txt new file mode 100644 index 00000000..db9a3a7e --- /dev/null +++ b/source/fundamentals/connection/connection-pools.txt @@ -0,0 +1,86 @@ +.. TODO: Connection Pools page + +.. _csharp-faq-connection-pool: +.. _csharp-connection-pools: + +How Does Connection Pooling Work in the {+driver-short+}? +--------------------------------------------------------- + +Every ``MongoClient`` instance has a built-in connection pool for each server +in your MongoDB topology. Connection pools open sockets on demand to +support concurrent MongoDB operations in your multi-threaded application. + +The maximum size of each connection pool is set by the ``MaxConnectionPoolSize`` option, which +defaults to ``100``. If the number of in-use connections to a server reaches +the value of ``MaxConnectionPoolSize``, the next request to that server will wait +until a connection becomes available. The following diagram illustrates a high-level view +of how the ``MongoClient`` manages a connection pool: + +.. figure:: /includes/figures/CMAP_diagram.svg + :alt: CMAP diagram + +In addition to the sockets needed to support your application's threads, +each ``MongoClient`` instance opens two additional sockets per server +in your MongoDB topology for monitoring the server's state. +For example, a client connected to a three-node replica set opens six +monitoring sockets. If the application uses the default setting for +``MaxConnectionPoolSize`` and only queries the primary (default) node, then +there can be at most ``106`` total connections in use. If the +application uses a :ref:`read preference ` to query the +secondary nodes, those connection pools grow and there can be +``306`` total connections. + +To support high numbers of concurrent MongoDB threads +within one process, you can increase ``MaxConnectionPoolSize``. + +The driver has a wait queue that limits the number of threads that can +wait for a connection. The size of the wait queue is determined by the +``WaitQueueMultiple`` option, which defaults to ``5``. To calculate the +maximum wait queue size, the driver multiplies ``WaitQueueMultiple`` by +``MaxConnectionPoolSize``. If you use the default value for each option, +the wait queue size will be ``500``. You can also set the wait queue +size by specifying the ``WaitQueueSize`` option, which overrides the +other settings. However, we do not recommend changing the wait queue +size from the default. + +Connection pools are rate-limited. The ``MaxConnecting`` setting +determines the number of connections that the pool can create in +parallel at any time. For example, if the value of ``MaxConnecting`` is +``2``, the third thread that attempts to concurrently check out a +connection succeeds only in one of the following cases: + +- One of the first two threads finishes creating a connection. +- An existing connection is checked back into the pool. +- The driver's ability to reuse existing connections improves due to + rate-limits on connection creation. + +You can set the minimum number of concurrent connections to +each server by using the ``MinConnectionPoolSize`` option, which +defaults to ``0``. The connection pool will be initialized with this +number of sockets. If errors cause any sockets to close and the +total number of sockets (both in-use and idle) drops below the minimum, +the driver opens more sockets until the number reaches the minimum. + +You can set the maximum number of milliseconds that a connection can +remain idle in the pool by using the ``MaxConnectionIdleTime`` option. +Once a connection is idle for ``MaxConnectionIdleTime``, the driver +removes it. This option defaults to 10 minutes. If the pool size falls +below ``MinConnectionPoolSize``, the driver removes *and* replaces the +idle connection. + +``MongoClient`` also has the ``MaxConnectionLifeTime`` option, which +specifies the length of time, 30 minutes by default, that a connection +can be pooled before expiring. + +The following default configuration for a ``MongoClient`` works for most +applications: + +.. code-block:: csharp + + var client = new MongoClient(""); + +Create a client once for each process, and reuse it for all +operations. It is a common mistake to create a new client for each +request, which is very inefficient. + +There is no supported way to terminate a ``MongoClient`` in the driver. \ No newline at end of file diff --git a/source/fundamentals/connection/server-selection.txt b/source/fundamentals/connection/server-selection.txt new file mode 100644 index 00000000..57772394 --- /dev/null +++ b/source/fundamentals/connection/server-selection.txt @@ -0,0 +1,68 @@ +.. TODO: Server Selection page + +Why Does the Driver Throw a Timeout During Server Selection? +------------------------------------------------------------ + +Each driver operation requires that you choose a healthy server +satisfying the :manual:`server selection criteria +`. If you do not select an appropriate +server within the `server selection timeout <{+new-api-root+}/MongoDB.Driver.Legacy/MongoDB.Driver.MongoServerSettings.ServerSelectionTimeout.html>`__, the driver throws a +server selection timeout exception. The exception looks similar to the +following: + +.. code-block:: none + + A timeout occurred after 30000ms selecting a server using CompositeServerSelector{ Selectors = MongoDB.Driver.MongoClient+AreSessionsSupportedServerSelector, LatencyLimitingServerSelector{ AllowedLatencyRange = 00:00:00.0150000 }, OperationsCountServerSelector }. + Client view of cluster state is + { + ClusterId : "1", + Type : "Unknown", + State : "Disconnected", + Servers : + [{ + ServerId: "{ ClusterId : 1, EndPoint : "Unspecified/localhost:27017" }", + EndPoint: "Unspecified/localhost:27017", + ReasonChanged: "Heartbeat", + State: "Disconnected", + ServerVersion: , + TopologyVersion: , + Type: "Unknown", + HeartbeatException: "" + }] + }. + +The error message consists of multiple parts: + +1. The server selection timeout (30000 ms). +#. The server selectors considered (``CompositeServerSelector`` + containing ``AreSessionsSupportedServerSelector``, + ``LatencyLimitingServerSelector``, and + ``OperationsCountServerSelector``). +#. The driver’s current view of the cluster topology. The list of + servers that the driver is aware of is a key part of this view. Each + server description contains an exhaustive description of its current + state including information about an endpoint, a server version, a + server type, and its current health state. If the server encounters issues in + reporting its health, ``HeartbeatException`` contains the exception from the + last failed heartbeat. Analyzing the ``HeartbeatException`` on each + cluster node can assist in diagnosing most server selection issues. + The following heartbeat exceptions are common: + + * ``No connection could be made because the target machine actively + refused it``: The driver cannot see this cluster node. This can be + because the cluster node has crashed, a firewall is preventing + network traffic from reaching the cluster node or port, or some other + network error is preventing traffic from being successfully routed to + the cluster node. + * ``Attempted to read past the end of the stream``: This error + happens when the driver cannot connect to the cluster nodes due to a + network error, misconfigured firewall, or other network issue. To + address this exception, ensure that all cluster nodes are reachable. + This error commonly occurs when the client machine’s IP address is + not configured in the Atlas IPs Access List, which can be found under + the :guilabel:`Network Access` tab for your Atlas Project. + * ``The remote certificate is invalid according to the validation + procedure``: This error typically indicates a TLS/SSL-related problem + such as an expired/invalid certificate or an untrusted root CA. You + can use tools like ``openssl s_client`` to debug TLS/SSL-related + certificate problems. \ No newline at end of file diff --git a/source/fundamentals/linq.txt b/source/fundamentals/linq.txt index 2e72709d..a66598c0 100644 --- a/source/fundamentals/linq.txt +++ b/source/fundamentals/linq.txt @@ -21,6 +21,8 @@ LINQ Overview -------- +.. include:: /includes/linq-vs-builders.rst + In this guide you can learn how to use `LINQ `__ with the {+driver-long+}. LINQ allows you to construct queries against @@ -1060,3 +1062,8 @@ uses a scalar operation, then prints the translated query: ``LoggedStages`` is not thread-safe. Executing a query and accessing the associated ``LoggedStages`` property from multiple threads might have non-deterministic results. + +Troubleshooting +--------------- + +.. include:: /includes/troubleshooting/unsupported-filter-expression.rst \ No newline at end of file diff --git a/source/fundamentals/serialization.txt b/source/fundamentals/serialization.txt index f5a0bfce..a144c98a 100644 --- a/source/fundamentals/serialization.txt +++ b/source/fundamentals/serialization.txt @@ -48,6 +48,50 @@ primitive types, collection types, and custom classes. For a full list of available serializers, see the `Serializers namespace API documentation <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.Serialization.Serializers.html>`__. +.. TODO: Revisit this page + +.. _csharp-faq-object-serializer: + +ObjectSerializer +---------------- + +The ``ObjectSerializer`` class allows serialization and deserialization only of types +that are considered safe. When you construct an ``ObjectSerializer``, +you can pass in a delegate of type ``Func``. This delegate +accepts an object type and returns a boolean value indicating whether the +type is safe for serialization. + +In most cases, you should pass in the ``ObjectSerializer.DefaultAllowedTypes()`` +delegate. This method returns true for a number of well-known +framework types that we have deemed safe. To serialize custom types, +create a boolean expression that evaluates to ``true`` for the +types you want to include. Then, add this expression to the end of the +delegate you pass to the ``ObjectSerializer`` constructor. + +In the following example, +the ``ObjectSerializer`` will serialize and deserialize any type that is allowed by +``ObjectSerializer.DefaultAllowedTypes()`` or whose full name begins with +``"MyNamespace"``: + +.. code-block:: csharp + + var objectSerializer = new ObjectSerializer(type => ObjectSerializer.DefaultAllowedTypes(type) + || type.FullName.StartsWith("MyNamespace")); + BsonSerializer.RegisterSerializer(objectSerializer); + +To allow anonymous types to be serialized, add the boolean expression +``type.FullName.StartsWith("<>f__AnonymousType"))`` to your delegate, +as shown in the following example: + +.. code-block:: csharp + + var objectSerializer = new ObjectSerializer(type => ObjectSerializer.DefaultAllowedTypes(type) + || type.FullName.StartsWith("<>f__AnonymousType")); + BsonSerializer.RegisterSerializer(objectSerializer); + +You should create and register your ``ObjectSerializer`` at the start of your program, +before doing anything else. + Serializer Registry ------------------- diff --git a/source/includes/linq-vs-builders.rst b/source/includes/linq-vs-builders.rst new file mode 100644 index 00000000..2d016a5a --- /dev/null +++ b/source/includes/linq-vs-builders.rst @@ -0,0 +1,8 @@ +.. tip:: LINQ or Builders? + + If you're used to programming in {+language+}, consider using LINQ because of its similar feel + to programming in native {+language+}. If you have prior experience with other MongoDB drivers, + consider using ``Builder`` classes because of their consistency with other drivers. + + We encourage experimenting with both approaches to determine the most suitable mechanism + for your purposes. \ No newline at end of file diff --git a/source/includes/troubleshooting/unsupported-filter-expression.rst b/source/includes/troubleshooting/unsupported-filter-expression.rst new file mode 100644 index 00000000..69344be0 --- /dev/null +++ b/source/includes/troubleshooting/unsupported-filter-expression.rst @@ -0,0 +1,60 @@ +.. _csharp-faq-unsupported-expressions: + +``Unsupported filter`` or ``Expression not supported`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you use a LINQ or builder expression that isn't available in the Query API, +you might receive an ``Unsupported filter ...`` or ``Expression not +supported ...`` exception message. +An expression might not be available in the following cases: + +1. You are attempting to use a {+lang-framework+} feature that doesn't have an + equivalent MongoDB representation. For example, {+lang-framework+} and MongoDB have + different semantics around collations. +#. The driver doesn't support a particular transformation from the LINQ or + builder expression into the Query API. This might happen because the + provided query has no Query API translation or because a feature hasn't been + implemented in the driver. + +If you receive one of these exceptions, try the following steps: + +1. Use the `{+analyzer+} + `__ to analyze your + expressions. +#. Simplify your query where possible. +#. Provide a query as a ``BsonDocument`` object or JSON string. All + definition classes, such as ``FilterDefinition``, + ``ProjectionDefinition``, and ``PipelineDefinition``, support implicit + conversion from ``BsonDocument`` objects or JSON strings. For example, the + following filters are equivalent when used in a query or + aggregation: + + .. code-block:: csharp + + FilterDefinition typedFilter = Builders.Filter.Eq(e => e.A, 1); + FilterDefinition bsonFilter = new BsonDocument {{ "a", 1 }}; + FilterDefinition jsonFilter = "{ a : 1 }"; + +You can combine ``BsonDocument`` objects, JSON strings, POCOs in the same +query, as shown in the following example: + +.. code-block:: csharp + + FilterDefinition filter = Builders.Filter + .And(Builders.Filter + .Eq(e => e.A, 1), BsonDocument + .Parse("{ b : 2 }")); + +.. note:: + + If you use a ``BsonDocument`` object or JSON string, your field names must match + the case-sensitive names stored by the server. For example, when referencing + the ``_id`` field, you must refer to it by using the field name ``_id``. + + Because the Query API doesn't recognize + :ref:`manual class mappings `, + BSON serialization attributes, or serialization conventions, you can't use these + mechanisms to change field names. For example, if a document contains a field named + ``FirstName`` annotated with ``[BsonElement("first_name")]``, you must refer to it + as ``first_name`` in ``BsonDocument`` or JSON string definitions. + diff --git a/source/index.txt b/source/index.txt index 72444317..0730ca4c 100644 --- a/source/index.txt +++ b/source/index.txt @@ -134,6 +134,13 @@ The MongoDB Entity Framework Provider is an object-relational mapper (ORM) that use Microsoft's Entity Framework to work with MongoDB data. ORMs provide an object-oriented interface for data management. +The provider includes features such as the following: + +- Intelligent object tracking +- Entity-based LINQ operations +- Entity Framework modeling and mapping with the fluent API +- Automatic database updates through change tracking + To learn more, see the `MongoDB Entity Framework Provider documentation `__. @@ -143,4 +150,4 @@ To learn more, see the The {+analyzer-short+} is a tool that helps you understand how your {+driver-short+} code translates into the {+query-api+} and if your code includes any unsupported LINQ or builder expressions. To learn more, see the -`{+analyzer-short+} documentation `__. +`{+analyzer-short+} documentation `__. \ No newline at end of file From d2b5421167cec96344f52e9561d0bc4002d9242f Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Wed, 2 Apr 2025 14:04:43 -0500 Subject: [PATCH 03/35] DOCSP-48810 - Move usage examples (#554) --- .../crud/read-operations/retrieve.txt | 9 +- .../crud/write-operations/delete.txt | 6 +- .../crud/write-operations/insert.txt | 6 +- .../crud/write-operations/replace.txt | 9 + .../crud/write-operations/update-many.txt | 5 +- .../crud/write-operations/update-one.txt | 5 +- .../includes/page-templates/update/update.rst | 4 +- source/usage-examples/deleteMany.txt | 82 -------- source/usage-examples/deleteOne.txt | 91 --------- source/usage-examples/facets.toml | 3 - source/usage-examples/findMany.txt | 178 ------------------ source/usage-examples/findOne.txt | 130 ------------- source/usage-examples/insertMany.txt | 82 -------- source/usage-examples/insertOne.txt | 83 -------- source/usage-examples/replaceOne.txt | 88 --------- source/usage-examples/updateMany.txt | 86 --------- source/usage-examples/updateOne.txt | 98 ---------- 17 files changed, 33 insertions(+), 932 deletions(-) delete mode 100644 source/usage-examples/deleteMany.txt delete mode 100644 source/usage-examples/deleteOne.txt delete mode 100644 source/usage-examples/facets.toml delete mode 100644 source/usage-examples/findMany.txt delete mode 100644 source/usage-examples/findOne.txt delete mode 100644 source/usage-examples/insertMany.txt delete mode 100644 source/usage-examples/insertOne.txt delete mode 100644 source/usage-examples/replaceOne.txt delete mode 100644 source/usage-examples/updateMany.txt delete mode 100644 source/usage-examples/updateOne.txt diff --git a/source/fundamentals/crud/read-operations/retrieve.txt b/source/fundamentals/crud/read-operations/retrieve.txt index 396b0580..4527d807 100644 --- a/source/fundamentals/crud/read-operations/retrieve.txt +++ b/source/fundamentals/crud/read-operations/retrieve.txt @@ -272,8 +272,13 @@ To learn more about query filters, see :ref:`csharp-specify-query`. To learn how to specify queries using LINQ, see :ref:`csharp-linq`. -To view runnable examples of the ``Find()`` method, see the -:ref:`csharp-find-one` page. +For runnable examples of the find operations, see the following usage +examples: + +- `FindOne() <{+example+}/find-one/FindOne.cs>`__ +- `FindOneAsync() <{+example+}/find-one/FindOneAsync.cs>`__ +- `FindMany() <{+example+}/find-many/FindMany.cs>`__ +- `FindManyAsync() <{+example+}/find-many/FindManyAsync.cs>`__ API Documentation ~~~~~~~~~~~~~~~~~ diff --git a/source/fundamentals/crud/write-operations/delete.txt b/source/fundamentals/crud/write-operations/delete.txt index 0b5605fe..8b91da80 100644 --- a/source/fundamentals/crud/write-operations/delete.txt +++ b/source/fundamentals/crud/write-operations/delete.txt @@ -214,8 +214,10 @@ Additional Information For runnable examples of the delete operations, see the following usage examples: -- :ref:`csharp-delete-one` -- :ref:`csharp-delete-many` +- `DeleteOne() <{+example+}/delete-one/DeleteOne.cs>`__ +- `DeleteOneAsync() <{+example+}/delete-one/DeleteOneAsync.cs>`__ +- `DeleteMany() <{+example+}/delete-many/DeleteMany.cs>`__ +- `DeleteManyAsync() <{+example+}/delete-many/DeleteManyAsync.cs>`__ API Documentation ~~~~~~~~~~~~~~~~~ diff --git a/source/fundamentals/crud/write-operations/insert.txt b/source/fundamentals/crud/write-operations/insert.txt index 3ead0ef9..e7f3e53f 100644 --- a/source/fundamentals/crud/write-operations/insert.txt +++ b/source/fundamentals/crud/write-operations/insert.txt @@ -281,8 +281,10 @@ Additional Information For runnable examples of the insert operations, see the following usage examples: -- :ref:`csharp-insert-one` -- :ref:`csharp-insert-many` +- `InsertOne() <{+example+}/insert-one/InsertOne.cs>`__ +- `InsertOneAsync() <{+example+}/insert-one/InsertOneAsync.cs>`__ +- `InsertMany() <{+example+}/insert-many/InsertMany.cs>`__ +- `InsertManyAsync() <{+example+}/insert-many/InsertManyAsync.cs>`__ .. To learn more about performing the operations mentioned, see the .. following guides: diff --git a/source/fundamentals/crud/write-operations/replace.txt b/source/fundamentals/crud/write-operations/replace.txt index e64af0d9..c094116b 100644 --- a/source/fundamentals/crud/write-operations/replace.txt +++ b/source/fundamentals/crud/write-operations/replace.txt @@ -241,6 +241,15 @@ The ``ReplaceOneResult`` class contains the following properties: **Data Type:** `BsonValue <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonValue.html>`__ +Additional Information +---------------------- + +For runnable examples of the replace operation, see the following usage +examples: + +- `ReplaceOne() <{+example+}/replace-one/ReplaceOne.cs>`__ +- `ReplaceOneAsync() <{+example+}/replace-one/ReplaceOneAsync.cs>`__ + API Documentation ~~~~~~~~~~~~~~~~~ diff --git a/source/fundamentals/crud/write-operations/update-many.txt b/source/fundamentals/crud/write-operations/update-many.txt index e05203fd..7d46dfce 100644 --- a/source/fundamentals/crud/write-operations/update-many.txt +++ b/source/fundamentals/crud/write-operations/update-many.txt @@ -49,9 +49,10 @@ Update Many multiple documents - .. replacement:: usage-examples-link + .. replacement:: usage-examples-links - :ref:`csharp-examples-update-many` + - `UpdateMany() <{+example+}/update-many/UpdateMany.cs>`__ + - `UpdateManyAsync() <{+example+}/update-many/UpdateManyAsync.cs>`__ .. replacement:: sync-api-link diff --git a/source/fundamentals/crud/write-operations/update-one.txt b/source/fundamentals/crud/write-operations/update-one.txt index 192bf0ed..9afb9fd3 100644 --- a/source/fundamentals/crud/write-operations/update-one.txt +++ b/source/fundamentals/crud/write-operations/update-one.txt @@ -49,9 +49,10 @@ Update One a single document - .. replacement:: usage-examples-link + .. replacement:: usage-examples-links - :ref:`csharp-examples-update-one` + - `UpdateOne() <{+example+}/update-one/UpdateOne.cs>`__ + - `UpdateOneAsync() <{+example+}/update-one/UpdateOneAsync.cs>`__ .. replacement:: sync-api-link diff --git a/source/includes/page-templates/update/update.rst b/source/includes/page-templates/update/update.rst index 49741885..c6087ced 100644 --- a/source/includes/page-templates/update/update.rst +++ b/source/includes/page-templates/update/update.rst @@ -246,7 +246,9 @@ Additional Information |instruqt-lab-instructions| -For runnable examples of the update operations, see the |usage-examples-link| page. +For runnable examples of the update operations, see the following usage examples: + +|usage-examples-links| To learn more about creating query filters, see the :ref:`csharp-specify-query` guide. diff --git a/source/usage-examples/deleteMany.txt b/source/usage-examples/deleteMany.txt deleted file mode 100644 index 96103487..00000000 --- a/source/usage-examples/deleteMany.txt +++ /dev/null @@ -1,82 +0,0 @@ -.. _csharp-delete-many: - -===================== -Delete Many Documents -===================== - -.. facet:: - :name: genre - :values: reference - -.. meta:: - :keywords: code example, .NET, operation - -.. contents:: On this page - :local: - :backlinks: none - :depth: 2 - :class: singlecol - -You can delete more than one document using the ``DeleteMany()`` synchronous -method or the ``DeleteManyAsync()`` asynchronous method on a collection object. - -Example -------- - -The following code deletes all documents in the ``restaurants`` collection whose -``borough`` field value equals the word "Brooklyn". - -Select the :guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the corresponding -code. - -.. tabs:: - - .. tab:: Asynchronous - :tabid: delete-many-async - - .. literalinclude:: ../includes/code-examples/delete-many/DeleteManyAsync.cs - :start-after: start-delete-many-async - :end-before: end-delete-many-async - :language: csharp - :copyable: - :dedent: - - For a fully runnable example of the ``DeleteManyAsync()`` operation, see the - `DeleteManyAsync code sample <{+example+}/delete-many/DeleteManyAsync.cs>`__. - - .. tab:: Synchronous - :tabid: delete-many-sync - - .. literalinclude:: ../includes/code-examples/delete-many/DeleteMany.cs - :start-after: start-delete-many-builders - :end-before: end-delete-many-builders - :language: csharp - :copyable: - :dedent: - - For a fully runnable example of the ``DeleteMany()`` operation, see the - `DeleteMany code sample <{+example+}/delete-many/DeleteMany.cs>`__. - -Expected Result -~~~~~~~~~~~~~~~ - -Running either of the preceding full examples prints the following results: - -.. code-block:: none - - Deleting documents... - Deleted documents: 6086 - Resetting sample data...done. - -Additional Information ----------------------- - -To learn more about deleting documents, see the :ref:`csharp-delete-guide` guide. - -To learn more about using builders, see :ref:`csharp-builders`. - -API Documentation ------------------ - -* `DeleteMany() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.DeleteMany.html>`__ -* `DeleteManyAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.DeleteManyAsync.html>`__ diff --git a/source/usage-examples/deleteOne.txt b/source/usage-examples/deleteOne.txt deleted file mode 100644 index edd66963..00000000 --- a/source/usage-examples/deleteOne.txt +++ /dev/null @@ -1,91 +0,0 @@ -.. _csharp-delete-one: - -================= -Delete a Document -================= - -.. facet:: - :name: genre - :values: reference - -.. meta:: - :keywords: code example, .NET, operation - -.. contents:: On this page - :local: - :backlinks: none - :depth: 2 - :class: singlecol - -You can delete a document from a collection by using the synchronous -``DeleteOne()`` method, or the asynchronous ``DeleteOneAsync()`` method. - -.. note:: - - The ``DeleteOne()`` method deletes only the first document that matches the filter. - To delete more than one document, use the ``DeleteMany()`` method. - - To learn more about using ``DeleteMany()``, see :ref:`csharp-delete-many`. - -Example -------- - -Delete a Document by Using Builders -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The following example uses ``Builders`` to delete a document in -the ``restaurants`` collection with the ``name`` "Ready Penny Inn". - -Select the :guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the -corresponding code. - -.. tabs:: - - .. tab:: Asynchronous - :tabid: builders-async - - .. literalinclude:: ../includes/code-examples/delete-one/DeleteOneAsync.cs - :start-after: start-delete-one-builders-async - :end-before: end-delete-one-builders-async - :language: csharp - :copyable: - :dedent: - - For a fully runnable example of the ``DeleteOne()`` method, see the - `Asynchronous Delete One Example <{+example+}/delete-one/DeleteOneAsync.cs>`__. - - .. tab:: Synchronous - :tabid: builders-sync - - .. literalinclude:: ../includes/code-examples/delete-one/DeleteOne.cs - :start-after: start-delete-one-builders - :end-before: end-delete-one-builders - :language: csharp - :copyable: - :dedent: - - For a fully runnable example of the ``DeleteOne()`` method, see the - `Synchronous Delete One Example <{+example+}/delete-one/DeleteOne.cs>`__ - -Expected Result -~~~~~~~~~~~~~~~ - -Running either of the preceding full examples prints the following results: - -.. code-block:: none - - Deleting a document with builders... - Deleted documents: 1 - -Additional Information ----------------------- - -To learn more about deleting documents, see the :ref:`csharp-delete-guide` guide. - -To learn more about using builders, see :ref:`csharp-builders`. - -API Documentation ------------------ - -- `DeleteOne() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.DeleteOne.html>`__ -- `DeleteOneAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.DeleteOneAsync.html>`__ \ No newline at end of file diff --git a/source/usage-examples/facets.toml b/source/usage-examples/facets.toml deleted file mode 100644 index 07bd7b7f..00000000 --- a/source/usage-examples/facets.toml +++ /dev/null @@ -1,3 +0,0 @@ -[[facets]] -category = "genre" -value = "tutorial" diff --git a/source/usage-examples/findMany.txt b/source/usage-examples/findMany.txt deleted file mode 100644 index 81cb98f6..00000000 --- a/source/usage-examples/findMany.txt +++ /dev/null @@ -1,178 +0,0 @@ -.. _csharp-find-multiple: - -======================= -Find Multiple Documents -======================= - -.. facet:: - :name: genre - :values: reference - -.. meta:: - :keywords: code example, .NET, operation - -.. contents:: On this page - :local: - :backlinks: none - :depth: 2 - :class: singlecol - -You can retrieve multiple documents from a collection by using the -``Find()`` method. - -Example -------- - -Find Documents by Using Builders -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The following example uses ``Builders`` to find documents in -the ``restaurants`` collection with the ``cuisine`` "Pizza". - -Select the :guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the -corresponding code. - -.. tabs:: - - .. tab:: Asynchronous - :tabid: builders-async - - .. literalinclude:: ../includes/code-examples/find-many/FindManyAsync.cs - :start-after: start-find-builders-async - :end-before: end-find-builders-async - :language: csharp - :copyable: - :dedent: - - For a fully runnable example of using the ``Find()`` method to asynchronously - find multiple documents, see - `Asynchronous Find Multiple Example <{+example+}/find-many/FindManyAsync.cs>`__. - - .. tab:: Synchronous - :tabid: builders-sync - - .. literalinclude:: ../includes/code-examples/find-many/FindMany.cs - :start-after: start-find-builders-sync - :end-before: end-find-builders-sync - :language: csharp - :copyable: - :dedent: - - For a fully runnable example of using the ``Find()`` method to synchronously - find multiple documents, see - `Synchronous Find Multiple Example <{+example+}/find-many/FindMany.cs>`__. - -Find Documents by Using LINQ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The following example uses LINQ to find documents in the -``restaurants`` collection with the ``cuisine`` "Pizza". - -Select the :guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the -corresponding code. - -.. tabs:: - - .. tab:: Asynchronous - :tabid: linq-async - - .. literalinclude:: ../includes/code-examples/find-many/FindManyAsync.cs - :start-after: start-find-linq-async - :end-before: end-find-linq-async - :language: csharp - :copyable: - :dedent: - - For a fully runnable example of using the ``Find()`` method to asynchronously - find multiple documents, see - `Asynchronous Find Multiple Example <{+example+}/find-many/FindManyAsync.cs>`__. - - .. tab:: Synchronous - :tabid: linq-sync - - .. literalinclude:: ../includes/code-examples/find-many/FindMany.cs - :start-after: start-find-linq-sync - :end-before: end-find-linq-sync - :language: csharp - :copyable: - :dedent: - - For a fully runnable example of using the ``Find()`` method to synchronously - find multiple documents, see - `Synchronous Find Multiple Example <{+example+}/find-many/FindMany.cs>`__. - -.. _csharp_find_all: - -Find All Documents -~~~~~~~~~~~~~~~~~~ - -The following example finds all documents in the ``restaurants`` collection. - -Select the :guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the -corresponding code. - -.. tabs:: - - .. tab:: Asynchronous - :tabid: find-all-async - - .. literalinclude:: ../includes/code-examples/find-many/FindManyAsync.cs - :start-after: start-find-all-async - :end-before: end-find-all-async - :language: csharp - :copyable: - :dedent: - - For a fully runnable example of using the ``Find()`` method to asynchronously - find multiple documents, see - `Asynchronous Find Multiple Example <{+example+}/find-many/FindManyAsync.cs>`__. - - .. tab:: Synchronous - :tabid: find-all-sync - - .. literalinclude:: ../includes/code-examples/find-many/FindMany.cs - :start-after: start-find-all-sync - :end-before: end-find-all-sync - :language: csharp - :copyable: - :dedent: - - For a fully runnable example of using the ``Find()`` method to synchronously - find multiple documents, see - `Synchronous Find Multiple Example <{+example+}/find-many/FindMany.cs>`__. - -Expected Result -~~~~~~~~~~~~~~~ - -Running the preceding full examples prints the following results: - -.. code-block:: none - - Finding documents with builders...: - Number of documents found: 1163 - - Finding documents with LINQ...: - Number of documents found: 1163 - - Finding all documents...: - Number of documents found: 25359 - -.. tip:: Sample Datasets - - These examples use the :atlas:`sample datasets ` provided by Atlas. - The number of documents returned may differ depending on the data in your - collection. - -Additional Information ----------------------- - -To learn more about retrieving documents, see the :ref:`csharp-retrieve` guide. - -To learn more about using builders, see :ref:`csharp-builders`. - -To learn how to find documents using LINQ, see :ref:`csharp-linq`. - -API Documentation ------------------ - -- `Find() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollectionExtensions.Find.html>`__ \ No newline at end of file diff --git a/source/usage-examples/findOne.txt b/source/usage-examples/findOne.txt deleted file mode 100644 index 9d65265c..00000000 --- a/source/usage-examples/findOne.txt +++ /dev/null @@ -1,130 +0,0 @@ -.. _csharp-find-one: - -=============== -Find a Document -=============== - -.. facet:: - :name: genre - :values: reference - -.. meta:: - :keywords: code example, .NET, operation - -.. contents:: On this page - :local: - :backlinks: none - :depth: 2 - :class: singlecol - -You can retrieve a document by using the ``Find()`` method on a collection object. - -Example -------- - -Find a Document by Using Builders -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The following example uses ``Builders`` to find a document in the ``restaurants`` -collection that has a ``name`` field with a value of "Bagels N Buns". - -Select the :guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the -corresponding code. - -.. tabs:: - - .. tab:: Asynchronous - :tabid: builders-async - - .. literalinclude:: ../includes/code-examples/find-one/FindOneAsync.cs - :start-after: start-find-builders - :end-before: end-find-builders - :language: csharp - :copyable: - :dedent: - - For a fully runnable example of using the ``Find()`` method - to asynchronously find one document, see the `Asynchronous Find One Example <{+example+}/find-one/FindOneAsync.cs>`__. - - .. tab:: Synchronous - :tabid: builders-sync - - .. literalinclude:: ../includes/code-examples/find-one/FindOne.cs - :start-after: start-find-builders - :end-before: end-find-builders - :language: csharp - :copyable: - :dedent: - - For a fully runnable example of using the ``Find()`` method - to synchronously find one document, see the `Synchronous Find One Example <{+example+}/find-one/FindOne.cs>`__. - -Find a Document by Using LINQ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The following example uses LINQ to find a document in the ``restaurants`` -collection that has a ``name`` field with a value of "Bagels N Buns". - -Select the :guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the -corresponding code. - -.. tabs:: - - .. tab:: Asynchronous - :tabid: linq-async - - .. literalinclude:: ../includes/code-examples/find-one/FindOneAsync.cs - :start-after: start-find-linq - :end-before: end-find-linq - :language: csharp - :copyable: - :dedent: - - For a fully runnable example of using the ``Find()`` method - to asynchronously find one document, see the `Asynchronous Find One Example <{+example+}/find-one/FindOneAsync.cs>`__. - - .. tab:: Synchronous - :tabid: linq-sync - - .. literalinclude:: ../includes/code-examples/find-one/FindOne.cs - :start-after: start-find-linq - :end-before: end-find-linq - :language: csharp - :copyable: - :dedent: - - For a fully runnable example of using the ``Find()`` method - to synchronously find one document, see the `Synchronous Find One Example <{+example+}/find-one/FindOne.cs>`__. - -Expected Result -~~~~~~~~~~~~~~~ - -Running any of the preceding full examples prints results similar to the following: - -.. code-block:: none - - { - "_id" : ObjectId("5eb3d668b31de5d588f42950"), - "name" : "Bagels N Buns", - "restaurant_id" : "40363427", - "cuisine" : "Delicatessen", - "address" : {...}, - "borough" : "Staten Island", - "grades" : [...] - } - -Additional Information ----------------------- - -To learn more about retrieving documents, see the :ref:`csharp-retrieve` guide. - -To learn more about using builders, see :ref:`csharp-builders`. - -To learn how to find a document using LINQ, see :ref:`csharp-linq`. - -API Documentation ------------------ - -- `Find() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollectionExtensions.Find.html>`__ -- `FirstOrDefault() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IFindFluentExtensions.FirstOrDefault.html>`__ -- `FirstOrDefaultAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Linq.MongoQueryable.FirstOrDefaultAsync.html>`__ diff --git a/source/usage-examples/insertMany.txt b/source/usage-examples/insertMany.txt deleted file mode 100644 index 89f631e8..00000000 --- a/source/usage-examples/insertMany.txt +++ /dev/null @@ -1,82 +0,0 @@ -.. _csharp-insert-many: - -========================= -Insert Multiple Documents -========================= - -.. facet:: - :name: genre - :values: reference - -.. meta:: - :keywords: code example, .NET, operation - -.. contents:: On this page - :local: - :backlinks: none - :depth: 2 - :class: singlecol - -You can insert multiple documents into a collection by using the synchronous -``InsertMany()`` method or the asynchronous ``InsertManyAsync()`` method. - -Example -------- - -The following example inserts multiple documents into -the ``restaurants`` collection. - -Select the :guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the -corresponding code. - -.. tabs:: - - .. tab:: Asynchronous - :tabid: insert-many-async - - .. literalinclude:: ../includes/code-examples/insert-many/InsertManyAsync.cs - :start-after: start-insert-many - :end-before: end-insert-many - :language: csharp - :copyable: - :dedent: - - For a fully runnable example of the ``InsertManyAsync()`` operation, see the - `InsertManyAsync code sample <{+example+}/insert-many/InsertMany.cs>`__. - - .. tab:: Synchronous - :tabid: insert-many-sync - - .. literalinclude:: ../includes/code-examples/insert-many/InsertMany.cs - :start-after: start-insert-many - :end-before: end-insert-many - :language: csharp - :copyable: - :dedent: - - For a fully runnable example of the ``InsertMany()`` operation, see the - `InsertMany code sample <{+example+}/insert-many/InsertManyAsync.cs>`__. - -Expected Result -~~~~~~~~~~~~~~~ - -After running either of the preceding full examples, the output is as follows: - -.. code-block:: none - - Number of restaurants found before insert: 0 - - Inserting documents... - Number of restaurants inserted: 5 - - -Additional Information ----------------------- - -To learn more about using builders, see :ref:`csharp-builders`. - -API Documentation ------------------ - -- `InsertMany() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.InsertMany.html>`__ -- `InsertManyAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.InsertManyAsync.html>`__ diff --git a/source/usage-examples/insertOne.txt b/source/usage-examples/insertOne.txt deleted file mode 100644 index 4ea96a6d..00000000 --- a/source/usage-examples/insertOne.txt +++ /dev/null @@ -1,83 +0,0 @@ -.. _csharp-insert-one: - -================= -Insert a Document -================= - -.. facet:: - :name: genre - :values: reference - -.. meta:: - :keywords: code example, .NET, operation - -.. contents:: On this page - :local: - :backlinks: none - :depth: 2 - :class: singlecol - -You can insert a single document into a collection by using the synchronous -``InsertOne()`` method, or the asynchronous ``InsertOneAsync()`` method. - -Example -------- - -The following example inserts a document into the ``restaurants`` collection. - -Select the :guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the -corresponding code. - -.. tabs:: - - .. tab:: Asynchronous - :tabid: insert-one-async - - .. literalinclude:: ../includes/code-examples/insert-one/InsertOneAsync.cs - :start-after: start-insert-one-async - :end-before: end-insert-one-async - :language: csharp - :copyable: - :dedent: - - For a fully runnable example of the ``InsertOneAsync()`` operation, see the - `Asynchronous Insert One Example <{+example+}/insert-one/InsertOneAsync.cs>`__. - - .. tab:: Synchronous - :tabid: insert-one-sync - - .. literalinclude:: ../includes/code-examples/insert-one/InsertOne.cs - :start-after: start-insert-one - :end-before: end-insert-one - :language: csharp - :copyable: - :dedent: - - For a fully runnable example of the ``InsertOne()`` operation, see the - `Synchronous Insert One Example <{+example+}/insert-one/InsertOne.cs>`__. - -Expected Result -~~~~~~~~~~~~~~~ - -After running either of the preceding full examples, the ``InsertOne()`` -method inserts the document, and the :ref:`Find() ` method returns -the newly inserted document. The output is similar to the following: - -.. code-block:: none - - Inserting a document... - Document Inserted: { "_id" : ObjectId("..."), "name" : "Mongo's Pizza", "restaurant_id" : "12345", "cuisine" : "Pizza", "address" : { "_t" : "MongoDB.Bson.BsonDocument, MongoDB.Bson", "_v" : { "street" : "Pizza St", "zipcode" : "10003" } }, "borough" : "Manhattan", "grades" : [{ "_t" : "MongoDB.Bson.BsonDocument, MongoDB.Bson", "_v" : { } }] } - - -Additional Information ----------------------- - -To learn more about using builders, see :ref:`csharp-builders`. - -API Documentation ------------------ - -- `InsertOne() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.InsertMany.html>`__ -- `InsertOneAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.InsertOneAsync.html>`__ -- `Find() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollectionExtensions.Find.html>`__ -- `FirstOrDefault() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IFindFluentExtensions.FirstOrDefault.html>`__ diff --git a/source/usage-examples/replaceOne.txt b/source/usage-examples/replaceOne.txt deleted file mode 100644 index e82a9e4b..00000000 --- a/source/usage-examples/replaceOne.txt +++ /dev/null @@ -1,88 +0,0 @@ -.. _csharp-replace-one: - -================== -Replace a Document -================== - -.. facet:: - :name: genre - :values: reference - -.. meta:: - :keywords: code example, .NET, operation - -.. contents:: On this page - :local: - :backlinks: none - :depth: 2 - :class: singlecol - -You can replace one document with another by using the ``ReplaceOne()`` synchronous method -or the ``ReplaceOneAsync()`` asynchronous method on a collection object. - -Example -------- - -The following code replaces the first document in the ``restaurants`` collection that has a -value of "Pizza" in the ``cuisine`` field. After the replacement, this document will -have a ``name`` field with a value of "Mongo's Pizza" and new values for the -``address`` and ``borough`` fields. - -Select the :guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the -corresponding code. - -.. tabs:: - - .. tab:: Asynchronous - :tabid: replace-one-async - - .. literalinclude:: ../includes/code-examples/replace-one/ReplaceOneAsync.cs - :start-after: start-replace-one-async - :end-before: end-replace-one-async - :language: csharp - :copyable: - :dedent: - - For a fully runnable example of the ``ReplaceOneAsync()`` operation, see the - `ReplaceOneAsync code sample <{+example+}/replace-one/ReplaceOneAsync.cs>`__. - - .. tab:: Synchronous - :tabid: replace-one-sync - - .. literalinclude:: ../includes/code-examples/replace-one/ReplaceOne.cs - :start-after: start-replace-one - :end-before: end-replace-one - :language: csharp - :copyable: - :dedent: - - For a fully runnable example of the ``ReplaceOne()`` operation, see the - `ReplaceOne code sample <{+example+}/replace-one/ReplaceOne.cs>`__. - -Expected Result -~~~~~~~~~~~~~~~ - -Running either of the preceding full examples prints the following results: - -.. code-block:: none - - First pizza restaurant before replacement: J&V Famous Pizza - Restaurants modified by replacement: 1 - First pizza restaurant after replacement: Mongo's Pizza - Resetting sample data...done. - -Additional Information ----------------------- - -To learn more about replacing documents, see the :ref:`csharp-replace-operation` -guide. - -To learn more about using builders, see :ref:`csharp-builders`. - -API Documentation ------------------ - -* `ReplaceOne() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.ReplaceOne.html>`__ -* `ReplaceOneAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.ReplaceOneAsync.html>`__ -* `ReplaceOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ReplaceOptions.html>`__ -* `ReplaceOneResult <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ReplaceOneResult.html>`__ \ No newline at end of file diff --git a/source/usage-examples/updateMany.txt b/source/usage-examples/updateMany.txt deleted file mode 100644 index 7c1b5203..00000000 --- a/source/usage-examples/updateMany.txt +++ /dev/null @@ -1,86 +0,0 @@ -.. _csharp-examples-update-many: - -===================== -Update Many Documents -===================== - -.. facet:: - :name: genre - :values: reference - -.. meta:: - :keywords: code example, .NET, operation - -.. contents:: On this page - :local: - :backlinks: none - :depth: 2 - :class: singlecol - -You can update more than one document using the ``UpdateMany()`` method on -a collection object. - -Example -------- - -The following code updates all documents in the ``restaurants`` collection that have a -``cuisine`` field with the value of "Pizza". After the update, these documents will -have a ``cuisine`` field with a value of "Pasta and breadsticks". - -Select the :guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the corresponding -code. - -.. tabs:: - - .. tab:: Asynchronous - :tabid: update-many-async - - .. literalinclude:: ../includes/code-examples/update-many/UpdateManyAsync.cs - :start-after: start-update-many-async - :end-before: end-update-many-async - :language: csharp - :copyable: - :dedent: - - For a fully runnable example of the ``UpdateManyAsync()`` operation, see the - `UpdateManyAsync code sample <{+example+}/update-many/UpdateManyAsync.cs>`__. - - .. tab:: Synchronous - :tabid: update-many-sync - - .. literalinclude:: ../includes/code-examples/update-many/UpdateMany.cs - :start-after: start-update-many - :end-before: end-update-many - :language: csharp - :copyable: - :dedent: - - For a fully runnable example of the ``UpdateMany()`` operation, see the - `UpdateMany code sample <{+example+}/update-many/UpdateMany.cs>`__. - -Expected Result -~~~~~~~~~~~~~~~ - -Running either of the preceding full examples prints the following results: - -.. code-block:: none - - Restaurants with cuisine "Pizza" found: 1163 - Restaurants modified by update: 1163 - Restaurants with cuisine "Pasta and breadsticks" found after update: 1163 - Resetting sample data...done. - -More Information ----------------- - -To learn more about updating documents, see the :ref:`csharp-update-many` guide. - -To learn more about using builders, see :ref:`csharp-builders`. - -API Documentation ------------------ - -* `UpdateMany() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.UpdateMany.html>`__ -* `UpdateManyAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.UpdateManyAsync.html>`__ -* `UpdateOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateOptions.html>`__ -* `UpdateResult <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateResult.html>`__ \ No newline at end of file diff --git a/source/usage-examples/updateOne.txt b/source/usage-examples/updateOne.txt deleted file mode 100644 index df6c799a..00000000 --- a/source/usage-examples/updateOne.txt +++ /dev/null @@ -1,98 +0,0 @@ -.. _csharp-examples-update-one: - -================= -Update a Document -================= - -.. facet:: - :name: genre - :values: reference - -.. meta:: - :keywords: code example, .NET, operation - -.. contents:: On this page - :local: - :backlinks: none - :depth: 2 - :class: singlecol - -You can update a single document using the `UpdateOne() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.UpdateOne.html>`__ method on -a ``MongoCollection`` object. This method requires a **query filter**, which specifies which document to update, and an **update** statement, which specifies the changes the driver should make to the first document matching the query filter. - -.. note:: - - The ``UpdateOne()`` method updates only the first document that matches the - filter. To update more than one document, use the :ref:`UpdateMany() method `. - -.. tip:: - - You can pass an instance of `UpdateOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateOptions.html>`__ to the ``UpdateOne()`` method in - order to customize its behavior. - -Example -------- - -The following example uses ``Builders`` to update the ``name`` of the -first document named "Bagels N Buns" in the ``restaurants`` collection to -"2 Bagels 2 Buns". - -Select the :guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the -corresponding code. - -.. tabs:: - - .. tab:: Asynchronous - :tabid: update-async - - - .. literalinclude:: ../includes/code-examples/update-one/UpdateOneAsync.cs - :start-after: start-update-one-async - :end-before: end-update-one-async - :language: csharp - :copyable: - :dedent: - - For a fully runnable example of the ``UpdateOneAsync()`` operation, see the - `UpdateOneAsync Example <{+example+}/update-one/UpdateOneAsync.cs>`__. - - .. tab:: Synchronous - :tabid: update-many-sync - - .. literalinclude:: ../includes/code-examples/update-one/UpdateOne.cs - :start-after: start-update-one - :end-before: end-update-one - :language: csharp - :copyable: - :dedent: - - For a fully runnable example of the ``UpdateOneAsync()`` operation, see the - `UpdateOne Example <{+example+}/update-one/UpdateOne.cs>`__. - -Expected Result -~~~~~~~~~~~~~~~ - -After running either of the preceding full examples, each call to ``UpdateOne()`` -writes the following to the console: - -.. code-block:: none - - Updated documents: 1 - -.. tip:: - - ``UpdateOne()`` returns an `UpdateResult <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateResult.html>`__ object. - -More Information ----------------- - -To learn more about updating documents, see the :ref:`csharp-update-one` guide. - -To learn more about using builders, see :ref:`csharp-builders`. - -API Documentation ------------------ - -* `UpdateOne() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.UpdateOne.html>`__ -* `UpdateOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateOptions.html>`__ -* `UpdateResult <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateResult.html>`__ \ No newline at end of file From d982c057d86151fd774f5daeb58eeb3914e49147 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Mon, 7 Apr 2025 11:10:15 -0500 Subject: [PATCH 04/35] DOCSP-48812 - Match PyMongo TOC (#556) --- snooty.toml | 16 +- .../linq.txt => aggregation.txt} | 364 ++++++++++++++- source/{fundamentals => }/atlas-search.txt | 30 ++ .../builders.txt => atlas-vector-search.txt} | 440 +----------------- source/connect.txt | 28 ++ .../connection-options.txt | 10 + .../connection-options}/connection-pools.txt | 0 source/connect/connection-options/csot.txt | 0 .../network-compression.txt | 0 .../connection-options}/server-selection.txt | 0 .../connection-options}/stable-api.txt | 0 source/connect/connection-targets.txt | 0 .../connection-troubleshooting.txt | 2 - .../connect.txt => connect/mongoclient.txt} | 9 +- source/crud.txt | 24 + .../write-operations => crud}/bulk-write.txt | 0 .../configure.txt} | 0 .../crud/write-operations => crud}/delete.txt | 0 source/{fundamentals => crud}/geo.txt | 0 source/{fundamentals => crud}/gridfs.txt | 0 .../crud/write-operations => crud}/insert.txt | 4 +- source/crud/query.txt | 21 + .../read-operations => crud/query}/count.txt | 1 - source/crud/query/cursors.txt | 0 .../query}/distinct.txt | 0 .../retrieve.txt => crud/query/find.txt} | 2 +- .../query}/project.txt | 88 +++- .../query}/specify-documents-to-return.txt | 26 +- .../query}/specify-query.txt | 108 ++++- .../write-operations => crud}/replace.txt | 0 .../{fundamentals => crud}/transactions.txt | 0 .../write-operations => crud}/update-many.txt | 50 +- .../update-many/arrays.txt | 0 .../update-many/fields.txt | 0 .../write-operations => crud}/update-one.txt | 54 ++- .../update-one/arrays.txt | 0 .../update-one/fields.txt | 0 source/data-formats.txt | 41 ++ .../{fundamentals => data-formats}/bson.txt | 0 source/data-formats/custom-types.txt | 26 ++ .../custom-types}/class-mapping.txt | 0 .../custom-types}/poco.txt | 3 - .../custom-types}/polymorphic-objects.txt | 0 .../custom-types}/serialization.txt | 8 - source/data-formats/extended-json.txt | 11 + .../guids.txt} | 0 .../time-series.txt | 2 +- ...llection.txt => databases-collections.txt} | 4 +- source/fundamentals.txt | 58 --- source/fundamentals/aggregation.txt | 221 --------- source/fundamentals/connection.txt | 31 -- source/fundamentals/crud.txt | 17 - source/fundamentals/crud/read-operations.txt | 25 - source/fundamentals/crud/write-operations.txt | 25 - source/get-started.txt | 218 ++++++++- .../get-started/create-connection-string.txt | 86 ---- source/get-started/deploy-cluster.txt | 29 -- source/get-started/download-driver.txt | 34 -- source/get-started/run-sample-query.txt | 49 -- source/index.txt | 179 +++---- source/{fundamentals => }/indexes.txt | 79 ++++ source/integrations.txt | 62 +++ .../{fundamentals => integrations}/odata.txt | 0 source/logging-and-monitoring.txt | 18 + .../change-streams.txt | 0 .../logging.txt | 0 .../monitoring.txt | 0 source/reference.txt | 25 + source/{ => reference}/compatibility.txt | 0 source/{ => reference}/previous-versions.txt | 6 +- source/{ => reference}/quick-reference.txt | 18 - .../release-notes.txt} | 10 +- source/{ => reference}/upgrade.txt | 4 +- source/{ => reference}/upgrade/v2.txt | 0 source/{ => reference}/upgrade/v3.txt | 0 .../run-command.txt | 0 source/security.txt | 18 + .../authentication.txt | 12 +- .../authentication/aws-iam.txt | 0 .../authentication/kerberos.txt | 0 .../authentication/ldap.txt | 0 .../authentication/oidc.txt | 0 .../authentication/scram.txt | 0 .../authentication/x509.txt | 0 .../in-use-encryption.txt} | 1 + .../tls.txt => security/tls-ssl.txt} | 0 source/usage-examples.txt | 105 ----- 87 files changed, 1386 insertions(+), 1316 deletions(-) rename source/{fundamentals/linq.txt => aggregation.txt} (80%) rename source/{fundamentals => }/atlas-search.txt (96%) rename source/{fundamentals/builders.txt => atlas-vector-search.txt} (62%) create mode 100644 source/connect.txt rename source/{fundamentals/connection => connect}/connection-options.txt (97%) rename source/{fundamentals/connection => connect/connection-options}/connection-pools.txt (100%) create mode 100644 source/connect/connection-options/csot.txt rename source/{fundamentals/connection => connect/connection-options}/network-compression.txt (100%) rename source/{fundamentals/connection => connect/connection-options}/server-selection.txt (100%) rename source/{fundamentals => connect/connection-options}/stable-api.txt (100%) create mode 100644 source/connect/connection-targets.txt rename source/{ => connect}/connection-troubleshooting.txt (99%) rename source/{fundamentals/connection/connect.txt => connect/mongoclient.txt} (97%) create mode 100644 source/crud.txt rename source/{fundamentals/crud/write-operations => crud}/bulk-write.txt (100%) rename source/{fundamentals/read-write-configuration.txt => crud/configure.txt} (100%) rename source/{fundamentals/crud/write-operations => crud}/delete.txt (100%) rename source/{fundamentals => crud}/geo.txt (100%) rename source/{fundamentals => crud}/gridfs.txt (100%) rename source/{fundamentals/crud/write-operations => crud}/insert.txt (99%) create mode 100644 source/crud/query.txt rename source/{fundamentals/crud/read-operations => crud/query}/count.txt (99%) create mode 100644 source/crud/query/cursors.txt rename source/{fundamentals/crud/read-operations => crud/query}/distinct.txt (100%) rename source/{fundamentals/crud/read-operations/retrieve.txt => crud/query/find.txt} (99%) rename source/{fundamentals/crud/read-operations => crud/query}/project.txt (66%) rename source/{fundamentals/crud/read-operations => crud/query}/specify-documents-to-return.txt (89%) rename source/{fundamentals => crud/query}/specify-query.txt (77%) rename source/{fundamentals/crud/write-operations => crud}/replace.txt (100%) rename source/{fundamentals => crud}/transactions.txt (100%) rename source/{fundamentals/crud/write-operations => crud}/update-many.txt (67%) rename source/{fundamentals/crud/write-operations => crud}/update-many/arrays.txt (100%) rename source/{fundamentals/crud/write-operations => crud}/update-many/fields.txt (100%) rename source/{fundamentals/crud/write-operations => crud}/update-one.txt (61%) rename source/{fundamentals/crud/write-operations => crud}/update-one/arrays.txt (100%) rename source/{fundamentals/crud/write-operations => crud}/update-one/fields.txt (100%) create mode 100644 source/data-formats.txt rename source/{fundamentals => data-formats}/bson.txt (100%) create mode 100644 source/data-formats/custom-types.txt rename source/{fundamentals/serialization => data-formats/custom-types}/class-mapping.txt (100%) rename source/{fundamentals/serialization => data-formats/custom-types}/poco.txt (99%) rename source/{fundamentals/serialization => data-formats/custom-types}/polymorphic-objects.txt (100%) rename source/{fundamentals => data-formats/custom-types}/serialization.txt (96%) create mode 100644 source/data-formats/extended-json.txt rename source/{fundamentals/serialization/guid-serialization.txt => data-formats/guids.txt} (100%) rename source/{fundamentals => data-formats}/time-series.txt (99%) rename source/{fundamentals/database-collection.txt => databases-collections.txt} (99%) delete mode 100644 source/fundamentals.txt delete mode 100644 source/fundamentals/aggregation.txt delete mode 100644 source/fundamentals/connection.txt delete mode 100644 source/fundamentals/crud.txt delete mode 100644 source/fundamentals/crud/read-operations.txt delete mode 100644 source/fundamentals/crud/write-operations.txt delete mode 100644 source/get-started/create-connection-string.txt delete mode 100644 source/get-started/deploy-cluster.txt delete mode 100644 source/get-started/download-driver.txt delete mode 100644 source/get-started/run-sample-query.txt rename source/{fundamentals => }/indexes.txt (86%) create mode 100644 source/integrations.txt rename source/{fundamentals => integrations}/odata.txt (100%) create mode 100644 source/logging-and-monitoring.txt rename source/{fundamentals/crud/read-operations => logging-and-monitoring}/change-streams.txt (100%) rename source/{fundamentals => logging-and-monitoring}/logging.txt (100%) rename source/{fundamentals => logging-and-monitoring}/monitoring.txt (100%) create mode 100644 source/reference.txt rename source/{ => reference}/compatibility.txt (100%) rename source/{ => reference}/previous-versions.txt (95%) rename source/{ => reference}/quick-reference.txt (95%) rename source/{whats-new.txt => reference/release-notes.txt} (98%) rename source/{ => reference}/upgrade.txt (92%) rename source/{ => reference}/upgrade/v2.txt (100%) rename source/{ => reference}/upgrade/v3.txt (100%) rename source/{fundamentals/databases-collections => }/run-command.txt (100%) create mode 100644 source/security.txt rename source/{fundamentals => security}/authentication.txt (85%) rename source/{fundamentals => security}/authentication/aws-iam.txt (100%) rename source/{fundamentals => security}/authentication/kerberos.txt (100%) rename source/{fundamentals => security}/authentication/ldap.txt (100%) rename source/{fundamentals => security}/authentication/oidc.txt (100%) rename source/{fundamentals => security}/authentication/scram.txt (100%) rename source/{fundamentals => security}/authentication/x509.txt (100%) rename source/{fundamentals/encrypt-fields.txt => security/in-use-encryption.txt} (77%) rename source/{fundamentals/connection/tls.txt => security/tls-ssl.txt} (100%) delete mode 100644 source/usage-examples.txt diff --git a/snooty.toml b/snooty.toml index 085ef4b7..61696522 100644 --- a/snooty.toml +++ b/snooty.toml @@ -1,15 +1,7 @@ toc_landing_pages = [ - "/fundamentals/connection", - "/fundamentals/crud", - "/usage-examples", - "/fundamentals", - "/fundamentals/serialization", - "/fundamentals/crud/write-operations/update-one", - "/fundamentals/crud/write-operations/update-many", - "/fundamentals/authentication", - "/upgrade", - "/fundamentals/database-collection", - "/get-started" + "/get-started", + "/connect/connection-options", + "/security/authentication" ] name = "csharp" title = "C#/.NET" @@ -47,5 +39,5 @@ string-data-type = "``string``" int-data-type = "``integer``" not-available = "N/A" analyzer = "MongoDB C# Analyzer" -analyzer-short = "C# Analzyer" +analyzer-short = "C# Analyzer" query-api = "MongoDB Query API" diff --git a/source/fundamentals/linq.txt b/source/aggregation.txt similarity index 80% rename from source/fundamentals/linq.txt rename to source/aggregation.txt index a66598c0..404bf1ea 100644 --- a/source/fundamentals/linq.txt +++ b/source/aggregation.txt @@ -1,15 +1,369 @@ -.. _csharp-linq: +.. _csharp-aggregation: -==== -LINQ -==== +=========== +Aggregation +=========== + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: code example, transform, pipeline .. contents:: On this page :local: :backlinks: none - :depth: 3 + :depth: 2 :class: singlecol +Overview +-------- + +In this guide, you can learn how to use the {+driver-long+} to perform +**aggregation operations**. + +Aggregation operations process data in your MongoDB collections and +return computed results. The MongoDB Aggregation framework is modeled on the +concept of data processing pipelines. Documents enter a pipeline comprised of one or +more stages, and this pipeline transforms the documents into an aggregated result. + +Analogy +~~~~~~~ + +Aggregation operations function similarly to car factories with assembly +lines. The assembly lines have stations with specialized tools to +perform specific tasks. For example, when building a car, the assembly +line begins with the frame. Then, as the car frame moves through the +assembly line, each station assembles a separate part. The result is a +transformed final product, the finished car. + +The assembly line represents the *aggregation pipeline*, the individual +stations represent the *aggregation stages*, the specialized tools +represent the *expression operators*, and the finished product +represents the *aggregated result*. + +Compare Aggregation and Find Operations +--------------------------------------- + +The following table lists the different tasks you can perform with find +operations, compared to what you can achieve with aggregation +operations. The aggregation framework provides expanded functionality +that allows you to transform and manipulate your data. + +.. list-table:: + :header-rows: 1 + :widths: 50 50 + + * - Find Operations + - Aggregation Operations + + * - | Select *certain* documents to return + | Select *which* fields to return + | Sort the results + | Limit the results + | Count the results + - | Select *certain* documents to return + | Select *which* fields to return + | Sort the results + | Limit the results + | Count the results + | Group the results + | Rename fields + | Compute new fields + | Summarize data + | Connect and merge data sets + +Server Limitations +------------------ + +Consider the following :manual:`limitations ` when +performing aggregation operations: + +- Returned documents must not violate the :manual:`BSON document size limit ` + of 16 megabytes. + +- Pipeline stages have a memory limit of 100 megabytes by default. If required, you can exceed this limit by setting + the `AllowDiskUse <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.AggregateOptions.AllowDiskUse.html#MongoDB_Driver_AggregateOptions_AllowDiskUse>`__ + property of the ``AggregateOptions`` object that you pass to the ``Aggregate()`` method. + +- The :manual:`$graphLookup ` stage has + a strict memory limit of 100 megabytes and ignores the ``AllowDiskUse`` property. + +Aggregation Example +------------------- + +To perform an aggregation, pass a list of aggregation stages to the +``IMongoCollection.Aggregate()`` method. + +.. note:: + + This example uses 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 :ref:`csharp-get-started`. + +The following code example produces a count of the number of bakeries in each borough +of New York City. To do so, it uses an aggregation pipeline that contains the following stages: + +- A :manual:`$match ` stage to filter for documents whose + ``cuisine`` field contains the value ``"Bakery"``. + +- A :manual:`$group ` stage to group the matching + documents by the ``borough`` field, accumulating a count of documents for each distinct value + of that field. + +The following sections implement this example by using LINQ, Builders, and BsonDocument +approaches to create and combine the aggregation stages used in the example pipeline. + +LINQ Approach +~~~~~~~~~~~~~ + +.. io-code-block:: + + .. input:: /includes/fundamentals/code-examples/LinqAggregation.cs + :language: csharp + :dedent: + :start-after: begin-aggregation + :end-before: end-aggregation + + .. output:: + :language: console + :visible: false + + { _id = Bronx, Count = 71 } + { _id = Brooklyn, Count = 173 } + { _id = Staten Island, Count = 20 } + { _id = Missing, Count = 2 } + { _id = Manhattan, Count = 221 } + { _id = Queens, Count = 204 } + +To learn more about using LINQ to construct aggregation pipelines, see the +:ref:`csharp-linq` guide. + +Builders Approach +~~~~~~~~~~~~~~~~~ + +.. io-code-block:: + + .. input:: /includes/fundamentals/code-examples/BuilderAggregation.cs + :language: csharp + :dedent: + :start-after: begin-aggregation + :end-before: end-aggregation + + .. output:: + :language: console + :visible: false + + { _id = Bronx, Count = 71 } + { _id = Brooklyn, Count = 173 } + { _id = Staten Island, Count = 20 } + { _id = Missing, Count = 2 } + { _id = Manhattan, Count = 221 } + { _id = Queens, Count = 204 } + +To learn more about using builders to construct aggregation pipelines, +see the :ref:`csharp-builders-aggregation` section of the Operations with Builders guide. + +BsonDocument Approach +~~~~~~~~~~~~~~~~~~~~~ + +.. io-code-block:: + + .. input:: /includes/fundamentals/code-examples/Aggregation.cs + :language: csharp + :dedent: + :start-after: begin-aggregation + :end-before: end-aggregation + + .. output:: + :language: console + :visible: false + + { "_id" : "Brooklyn", "count" : 173 } + { "_id" : "Manhattan", "count" : 221 } + { "_id" : "Bronx", "count" : 71 } + { "_id" : "Missing", "count" : 2 } + { "_id" : "Staten Island", "count" : 20 } + { "_id" : "Queens", "count" : 204 } + +Additional Information +---------------------- + +MongoDB Server Manual +~~~~~~~~~~~~~~~~~~~~~ + +To view a full list of expression operators, see +:manual:`Aggregation Operators `. + +To learn more about assembling an aggregation pipeline and view examples, see +:manual:`Aggregation Pipeline `. + +To learn more about creating pipeline stages, see +:manual:`Aggregation Stages `. + +To learn about explaining MongoDB aggregation operations, see +:manual:`Explain Results ` and +:manual:`Query Plans `. + +API Documentation +~~~~~~~~~~~~~~~~~ + +For more information about the aggregation operations discussed in this guide, see the +following API documentation: + +- `Aggregate() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.Aggregate.html>`__ +- `AggregateOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.AggregateOptions.html>`__ +- `Group() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.PipelineStageDefinitionBuilder.Group.html>`__ +- `Match() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.PipelineStageDefinitionBuilder.Match.html>`__ +- `Where() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Linq.MongoQueryable.Where.html>`__ +- `GroupBy() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Linq.MongoQueryable.GroupBy.html>`__ +- `Select() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Linq.MongoQueryable.Select.html>`__ + +.. TODO: integrate into existing page + +Sample Class +------------ + +The code examples in this guide demonstrate how you can use builders to +create types to interact with documents in the sample collection ``plants.flowers``. +Documents in this collection are modeled by the following ``Flower`` class: + +.. literalinclude:: /includes/fundamentals/code-examples/builders.cs + :language: csharp + :dedent: + :start-after: start-model + :end-before: end-model + +Each builder class takes a generic type parameter +``TDocument`` which represents the type of document that you are working +with. In this guide, the ``Flower`` class is the document type used in +each builder class example. + +.. _csharp-builders-aggregation: + +Build an Aggregation Pipeline +----------------------------- + +The ``PipelineDefinitionBuilder`` class provides a type-safe interface for +defining an **aggregation pipeline**. An aggregation pipeline is a series of +stages that are used to transform a document. Suppose you want to create a +pipeline that performs the following operations: + +- Matches all documents with "spring" in the ``Season`` field +- Sorts the results by the ``Category`` field +- Groups the documents by category and shows the average price and total + available for all documents in that category + +Use ``PipelineDefinitionBuilder`` classes to build the pipeline: + +.. code-block:: csharp + + var sortBuilder = Builders.Sort.Ascending(f => f.Category); + var matchFilter = Builders.Filter.AnyEq(f => f.Season, "spring"); + + var pipeline = new EmptyPipelineDefinition() + .Match(matchFilter) + .Sort(sortBuilder) + .Group(f => f.Category, + g => new + { + name = g.Key, + avgPrice = g.Average(f => f.Price), + totalAvailable = g.Sum(f => f.Stock) + } + ); + +The preceding example creates the following pipeline: + +.. code-block:: json + + [{ "$match" : { "season" : "spring" } }, { "$sort" : { "category" : 1 } }, { "$group" : { "_id" : "$category", "avgPrice" : { "$avg" : "$price" }, "totalAvailable" : { "$sum" : "$stock" } } }] + +You can add stages to your pipeline that don't have corresponding type-safe +methods in the ``PipelineDefinitionBuilder`` interface by providing your query +as a ``BsonDocument`` to the `AppendStage() method +<{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.PipelineDefinitionBuilder.AppendStage.html>`__. + +.. code-block:: csharp + + var pipeline = new EmptyPipelineDefinition().AppendStage("{ $set: { field1: '$field2' } }"); + +.. note:: + + When using a ``BsonDocument`` to define your pipeline stage, the driver does + not take into account any ``BsonClassMap``, serialization attributes or + serialization conventions. The field names used in the ``BsonDocument`` must + match those stored on the server. + + For more information on providing a query as a ``BsonDocument``, see our + :ref:`FAQ page `. + +To learn more about the Aggregation Pipeline, see the +:manual:`Aggregation Pipeline ` server manual page. + +.. _csharp-builders-out: + +Write Pipeline Results to a Collection +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can write the documents returned from an aggregation pipeline to a +collection by creating an ``$out`` stage at the end of your aggregation +pipeline. To create an ``$out`` stage, call the ``Out()`` method on a +``PipelineStageDefinitionBuilder``. The ``Out()`` method requires the name of +the collection you want to write the documents to. + +The following example builds an aggregation pipeline that matches all documents +with a ``season`` field value of ``"Spring"`` and outputs them to +a ``springFlowers`` collection: + +.. code-block:: csharp + + var outputCollection = database.GetCollection("springFlowers"); + var matchFilter = Builders.Filter.AnyEq(f => f.Season, "spring"); + + // Creates an aggregation pipeline and outputs resulting documents to a new collection. + var pipeline = new EmptyPipelineDefinition() + .Match(matchFilter) + .Out(outputCollection); + +You can write the results of an aggregation pipeline to a time series collection +by specifying a ``TimeSeriesOption`` object and passing it as the second +parameter to the ``Out()`` method. + +Imagine that the documents in the ``plants.flowers`` collection contain a ``datePlanted`` field that +holds BSON date values. You can store the documents in this collection in a time +series collection by using the ``datePlanted`` field as the time field. + +The following example creates a ``TimeSeriesOptions`` object and specifies +``datePlanted`` as the ``timeField``. It then builds an aggregation pipeline that matches all documents +with a ``season`` field value of ``"Spring"`` and outputs them to a +time series collection called ``springFlowerTimes``. + +.. code-block:: csharp + + var timeSeriesOptions = new TimeSeriesOptions("datePlanted"); + var collectionName = "springFlowerTimes" + var matchFilter = Builders.Filter.AnyEq(f => f.Season, "spring"); + + // Creates an aggregation pipeline and outputs resulting documents to a time series collection. + var pipeline = new EmptyPipelineDefinition() + .Match(matchFilter) + .Out(collectionName, timeSeriesOptions); + +To learn more about time series collections, see :ref:`csharp-time-series`. + + +- `PipelineDefinitionBuilder <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.PipelineDefinitionBuilder.html>`__ + +.. TODO: integrate into existing page + +.. _csharp-linq: + +==== +LINQ +==== + .. facet:: :name: genre :values: reference diff --git a/source/fundamentals/atlas-search.txt b/source/atlas-search.txt similarity index 96% rename from source/fundamentals/atlas-search.txt rename to source/atlas-search.txt index 4dae38c5..770674ef 100644 --- a/source/fundamentals/atlas-search.txt +++ b/source/atlas-search.txt @@ -683,3 +683,33 @@ The search returns the following document: To learn more about the ``wildcard`` operator, see the :atlas:`wildcard ` Atlas guide. + +.. TODO: integrate into existing page + +Sample Class +------------ + +The code examples in this guide demonstrate how you can use builders to +create types to interact with documents in the sample collection ``plants.flowers``. +Documents in this collection are modeled by the following ``Flower`` class: + +.. literalinclude:: /includes/fundamentals/code-examples/builders.cs + :language: csharp + :dedent: + :start-after: start-model + :end-before: end-model + +Each builder class takes a generic type parameter +``TDocument`` which represents the type of document that you are working +with. In this guide, the ``Flower`` class is the document type used in +each builder class example. + +Build an Atlas Search Query +--------------------------- + +The ``Search`` class provides a type-safe interface for creating a +:manual:`$search ` +pipeline stage. + +To learn how to construct search queries with the ``Search`` class, see +:ref:`csharp-atlas-search`. diff --git a/source/fundamentals/builders.txt b/source/atlas-vector-search.txt similarity index 62% rename from source/fundamentals/builders.txt rename to source/atlas-vector-search.txt index 4ccf6189..73e37027 100644 --- a/source/fundamentals/builders.txt +++ b/source/atlas-vector-search.txt @@ -1,48 +1,21 @@ -.. _csharp-builders: +.. _csharp-atlas-vector-search: -======================== -Operations with Builders -======================== - -.. contents:: On this page - :local: - :backlinks: none - :depth: 2 - :class: singlecol +=================== +Atlas Vector Search +=================== .. facet:: :name: genre :values: reference - + .. meta:: - :keywords: aggregation, query, code example - -Overview --------- - -.. include:: /includes/linq-vs-builders.rst - -In this guide, you can learn about the helper classes, or **builders**, that -the {+driver-short+} provides to create types used in your operations. -Using builders helps you identify errors at compile time and avoid them -at runtime. This guide provides information on builder classes that you -can use for the following tasks: + :keywords: semantic -- Creating a filter definition -- Creating a projection -- Defining a sort order -- Defining an update operation -- Selecting index keys - -.. tip:: {+analyzer+} - - The {+analyzer-short+} is a tool that helps you analyze your - builders definitions and understand how your {+lang-framework+} code - translates into the {+query-api+}. For more information and - installation instructions, see the `{+analyzer-short+} reference page `__. - -You should read this guide if you want to learn more about how to -construct definitions and build up syntax using builders. +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol Sample Class ------------ @@ -62,371 +35,6 @@ Each builder class takes a generic type parameter with. In this guide, the ``Flower`` class is the document type used in each builder class example. -Construct a Filter ------------------- - -The ``FilterDefinitionBuilder`` class provides a type-safe interface for -building up queries. Suppose you want to query your collection for -documents matching the following criteria: - -- ``Price`` field value less than 20 -- ``Category`` field value is "Perennial" - -Use builders to create the filter definition with the typed variant: - -.. code-block:: csharp - :copyable: true - - var builder = Builders.Filter; - var filter = builder.Lt(f => f.Price, 20) & builder.Eq(f => f.Category, "Perennial"); - -Using the typed variant form provides compile-time safety. Additionally, -your IDE can provide refactoring support. - -Alternatively, you can use string-based field names to contruct the filter: - -.. code-block:: csharp - :copyable: true - - var builder = Builders.Filter; - var filter = builder.Lt("Price", 20) & builder.Eq("Category", "Perennial"); - -If you are using LINQ, you can also use the ``Inject()`` method to apply the filter -to a LINQ query: - -.. code-block:: csharp - :copyable: true - - var builder = Builders.Filter; - var filter = builder.Lt("Price", 20) & builder.Eq("Category", "Perennial"); - var query = collection.AsQueryable().Where(f => filter.Inject()); - -Array Operators -~~~~~~~~~~~~~~~ - -If your document has properties or fields that serialize to arrays, -you can use the methods beginning with ``Any``, such as ``AnyEq()`` or -``AnyLt()``, to compare the entire array against a single item. - -Use builders to check which documents in the collection have a -``Season`` array that includes "winter": - -.. code-block:: csharp - :copyable: true - - var builder = Builders.Filter; - var filter = builder.AnyEq(f => f.Season, "winter"); - -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: - -Create a Projection -------------------- - -The ``ProjectionDefinitionBuilder`` class provides a type-safe interface for -defining a projection. Suppose you want to create a projection on the -``Name`` and ``Price`` fields, but exclude the ``Id`` field. - -Use builders to create the projection definition with the typed variant: - -.. code-block:: csharp - :copyable: true - - var builder = Builders.Projection; - var projection = builder.Include(f => f.Name).Include(f => f.Price).Exclude(f => f.Id); - -You can also use string-based field names to define the projection: - -.. code-block:: csharp - :copyable: true - - var builder = Builders.Projection; - var projection = builder.Include("Name").Include("Price").Exclude("Id"); - -Finally, you can use the ``Expression()`` method to define the -projection: - -.. code-block:: csharp - :copyable: true - - var builder = Builders.Projection; - var projection = builder.Expression(f => new { Name = f.Name, Price = f.Price }); - -This definition has a return type of ``ProjectionDefinition`` whereas the others return a -``ProjectionDefinition``. - -Lambda Expressions -~~~~~~~~~~~~~~~~~~ - -The driver supports using lambda expressions to render projections. When -you define a ``Find()`` projection with the ``Expression()`` method to -create a lambda expression, the driver inspects the expression -to determine which fields are referenced and automatically constructs a -server-side projection to return only those fields. - -You can also use lambda expressions to create new fields by performing -operations on values in your documents. The following example shows how -you can use a lambda expression to project a new ``Profit`` field -using the ``Price`` and ``Stock`` fields: - -.. code-block:: csharp - :copyable: true - - var builder = Builders.Projection; - var projection = builder.Expression(f => new { Profit = f.Price * f.Stock }); - -.. note:: ``Id`` Field Exclusion - - When you create a projection using a lambda expression, the output - automatically excludes the ``Id`` field unless you explicitly include - is as a projection field. - -Define a Sort -------------- - -The ``SortDefinitionBuilder`` class provides a type-safe interface for -building up sort syntax. Suppose you want to define a sort with the -following order: - -- Ascending on ``Price`` -- Descending on ``Category`` - -Use builders to create the sort definition with the typed variant: - -.. code-block:: csharp - :copyable: true - - var builder = Builders.Sort; - var sort = builder.Ascending(f => f.Price).Descending(f => f.Category); - -Alternatively, you can use string-based field names to define the sort: - -.. code-block:: csharp - :copyable: true - - var builder = Builders.Sort; - var sort = builder.Ascending("Price").Descending("Category"); - -Define an Update ----------------- - -The ``UpdateDefinitionBuilder`` class provides a type-safe interface for -building up an update specification. Suppose you want to create an -update specification with the following criteria: - -- Create the new field ``SunRequirement`` -- Multiply the ``Price`` field value by 0.9 - -Use builders to create the update specification with the typed variant: - -.. code-block:: csharp - :copyable: true - - var builder = Builders.Update; - var update = builder.Set(f => f.SunRequirement, "Full sun").Mul(f => f.Price, 0.9); - -Alternatively, you can use string-based field names to define the update: - -.. code-block:: csharp - :copyable: true - - var builder = Builders.Update; - var update = builder.Set("SunRequirement", "Full sun").Mul("Price", 0.9); - -.. _csharp-builders-indexes: - -Define Index Keys ------------------ - -The ``IndexKeysDefinitionBuilder`` class provides a type-safe interface for -defining index keys. Suppose you want to select ``Category`` as an -ascending index key. - -Use builders to select the index key with the typed variant: - -.. code-block:: csharp - :copyable: true - - var builder = Builders.IndexKeys; - var keys = builder.Ascending(f => f.Category); - -Alternatively, you can use string-based field names to select the index key: - -.. code-block:: csharp - :copyable: true - - var builder = Builders.IndexKeys; - var keys = builder.Ascending("Category"); - -The ``IndexKeysDefinitionBuilder`` class also provides methods to build -a wildcard index. You can create a wildcard index using ``All field paths`` or ``A -single field path``, in this case using ``Category``: - -.. tabs:: - - .. tab:: ``All field paths`` - :tabid: all-wildcard-index - - .. code-block:: csharp - :copyable: true - - var builder = Builders.IndexKeys; - var keys = builder.Wildcard(); - - .. tab:: ``A single field path`` - :tabid: single-wildcard-index - - .. code-block:: csharp - :copyable: true - - var builder = Builders.IndexKeys; - - // Using the typed variant - var keys = builder.Wildcard(f => f.Category); - - // Using string-based field names - var keys = builder.Wildcard("Category"); - -For more information about how to use wildcard indexes, see -:manual:`Wildcard Indexes `. - -.. _csharp-builders-aggregation: - -Build an Aggregation Pipeline ------------------------------ - -The ``PipelineDefinitionBuilder`` class provides a type-safe interface for -defining an **aggregation pipeline**. An aggregation pipeline is a series of -stages that are used to transform a document. Suppose you want to create a -pipeline that performs the following operations: - -- Matches all documents with "spring" in the ``Season`` field -- Sorts the results by the ``Category`` field -- Groups the documents by category and shows the average price and total - available for all documents in that category - -Use ``PipelineDefinitionBuilder`` classes to build the pipeline: - -.. code-block:: csharp - - var sortBuilder = Builders.Sort.Ascending(f => f.Category); - var matchFilter = Builders.Filter.AnyEq(f => f.Season, "spring"); - - var pipeline = new EmptyPipelineDefinition() - .Match(matchFilter) - .Sort(sortBuilder) - .Group(f => f.Category, - g => new - { - name = g.Key, - avgPrice = g.Average(f => f.Price), - totalAvailable = g.Sum(f => f.Stock) - } - ); - -The preceding example creates the following pipeline: - -.. code-block:: json - - [{ "$match" : { "season" : "spring" } }, { "$sort" : { "category" : 1 } }, { "$group" : { "_id" : "$category", "avgPrice" : { "$avg" : "$price" }, "totalAvailable" : { "$sum" : "$stock" } } }] - -You can add stages to your pipeline that don't have corresponding type-safe -methods in the ``PipelineDefinitionBuilder`` interface by providing your query -as a ``BsonDocument`` to the `AppendStage() method -<{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.PipelineDefinitionBuilder.AppendStage.html>`__. - -.. code-block:: csharp - - var pipeline = new EmptyPipelineDefinition().AppendStage("{ $set: { field1: '$field2' } }"); - -.. note:: - - When using a ``BsonDocument`` to define your pipeline stage, the driver does - not take into account any ``BsonClassMap``, serialization attributes or - serialization conventions. The field names used in the ``BsonDocument`` must - match those stored on the server. - - For more information on providing a query as a ``BsonDocument``, see our - :ref:`FAQ page `. - -To learn more about the Aggregation Pipeline, see the -:manual:`Aggregation Pipeline ` server manual page. - -.. _csharp-builders-out: - -Write Pipeline Results to a Collection -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You can write the documents returned from an aggregation pipeline to a -collection by creating an ``$out`` stage at the end of your aggregation -pipeline. To create an ``$out`` stage, call the ``Out()`` method on a -``PipelineStageDefinitionBuilder``. The ``Out()`` method requires the name of -the collection you want to write the documents to. - -The following example builds an aggregation pipeline that matches all documents -with a ``season`` field value of ``"Spring"`` and outputs them to -a ``springFlowers`` collection: - -.. code-block:: csharp - - var outputCollection = database.GetCollection("springFlowers"); - var matchFilter = Builders.Filter.AnyEq(f => f.Season, "spring"); - - // Creates an aggregation pipeline and outputs resulting documents to a new collection. - var pipeline = new EmptyPipelineDefinition() - .Match(matchFilter) - .Out(outputCollection); - -You can write the results of an aggregation pipeline to a time series collection -by specifying a ``TimeSeriesOption`` object and passing it as the second -parameter to the ``Out()`` method. - -Imagine that the documents in the ``plants.flowers`` collection contain a ``datePlanted`` field that -holds BSON date values. You can store the documents in this collection in a time -series collection by using the ``datePlanted`` field as the time field. - -The following example creates a ``TimeSeriesOptions`` object and specifies -``datePlanted`` as the ``timeField``. It then builds an aggregation pipeline that matches all documents -with a ``season`` field value of ``"Spring"`` and outputs them to a -time series collection called ``springFlowerTimes``. - -.. code-block:: csharp - - var timeSeriesOptions = new TimeSeriesOptions("datePlanted"); - var collectionName = "springFlowerTimes" - var matchFilter = Builders.Filter.AnyEq(f => f.Season, "spring"); - - // Creates an aggregation pipeline and outputs resulting documents to a time series collection. - var pipeline = new EmptyPipelineDefinition() - .Match(matchFilter) - .Out(collectionName, timeSeriesOptions); - -To learn more about time series collections, see :ref:`csharp-time-series`. - -Build an Atlas Search Query ---------------------------- - -The ``Search`` class provides a type-safe interface for creating a -:manual:`$search ` -pipeline stage. - -To learn how to construct search queries with the ``Search`` class, see -:ref:`csharp-atlas-search`. - Perform an Atlas Vector Search ------------------------------ @@ -488,28 +96,4 @@ The results of the preceding example contain the following documents: { "_id" : ObjectId("573a13e5f29313caabdc40c9"), "plot" : "A dimension-traveling wizard gets stuck in the 21st century because cell-phone radiation interferes with his magic. With his home world on the brink of war, he seeks help from a jaded ...", "title" : "The Portal" } To learn more about Atlas Vector Search, see :atlas:`Atlas Vector Search Overview ` -in the Atlas manual. - -Troubleshooting ---------------- - -.. include:: /includes/troubleshooting/unsupported-filter-expression.rst - -Additional Information ----------------------- - -Find runnable examples using builders for various operations under -:ref:`Usage Examples `. - -API Documentation -~~~~~~~~~~~~~~~~~ - -To learn more about any of the methods or types discussed in this -guide, see the following API Documentation: - -- `FilterDefinitionBuilder <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.FilterDefinitionBuilder-1.html>`__ -- `ProjectionDefinitionBuilder <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ProjectionDefinitionBuilder-1.html>`__ -- `SortDefinitionBuilder <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.SortDefinitionBuilder-1.html>`__ -- `UpdateDefinitionBuilder <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateDefinitionBuilder-1.html>`__ -- `IndexKeysDefinitionBuilder <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IndexKeysDefinitionBuilder-1.html>`__ -- `PipelineDefinitionBuilder <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.PipelineDefinitionBuilder.html>`__ \ No newline at end of file +in the Atlas manual. \ No newline at end of file diff --git a/source/connect.txt b/source/connect.txt new file mode 100644 index 00000000..6f15db31 --- /dev/null +++ b/source/connect.txt @@ -0,0 +1,28 @@ +.. _csharp-connect: + +================== +Connect to MongoDB +================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :description: Learn how to use the {+driver-short+} to connect to MongoDB. + :keywords: client, ssl + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + Create a MongoClient + Choose a Connection Target + Specify Connection Options + Connection Troubleshooting \ No newline at end of file diff --git a/source/fundamentals/connection/connection-options.txt b/source/connect/connection-options.txt similarity index 97% rename from source/fundamentals/connection/connection-options.txt rename to source/connect/connection-options.txt index 21c26c7f..2d4198e0 100644 --- a/source/fundamentals/connection/connection-options.txt +++ b/source/connect/connection-options.txt @@ -17,6 +17,16 @@ Connection Options :depth: 2 :class: singlecol +.. toctree:: + :caption: Specify Connection Options + + Compress Network Traffic + Customize Server Selection + Stable API + Limit Server Execution Time + Connection Pools + Connect from AWS Lambda + This section describes the MongoDB connection and authentication options available in the {+driver-short+}. You can configure your connection using either the connection URI or a ``MongoClientSettings`` object. diff --git a/source/fundamentals/connection/connection-pools.txt b/source/connect/connection-options/connection-pools.txt similarity index 100% rename from source/fundamentals/connection/connection-pools.txt rename to source/connect/connection-options/connection-pools.txt diff --git a/source/connect/connection-options/csot.txt b/source/connect/connection-options/csot.txt new file mode 100644 index 00000000..e69de29b diff --git a/source/fundamentals/connection/network-compression.txt b/source/connect/connection-options/network-compression.txt similarity index 100% rename from source/fundamentals/connection/network-compression.txt rename to source/connect/connection-options/network-compression.txt diff --git a/source/fundamentals/connection/server-selection.txt b/source/connect/connection-options/server-selection.txt similarity index 100% rename from source/fundamentals/connection/server-selection.txt rename to source/connect/connection-options/server-selection.txt diff --git a/source/fundamentals/stable-api.txt b/source/connect/connection-options/stable-api.txt similarity index 100% rename from source/fundamentals/stable-api.txt rename to source/connect/connection-options/stable-api.txt diff --git a/source/connect/connection-targets.txt b/source/connect/connection-targets.txt new file mode 100644 index 00000000..e69de29b diff --git a/source/connection-troubleshooting.txt b/source/connect/connection-troubleshooting.txt similarity index 99% rename from source/connection-troubleshooting.txt rename to source/connect/connection-troubleshooting.txt index 6e0877a6..6c914198 100644 --- a/source/connection-troubleshooting.txt +++ b/source/connect/connection-troubleshooting.txt @@ -18,8 +18,6 @@ using the {+driver-long+} to connect to a MongoDB deployment. This page addresses only connection issues. If you encounter any other issues with MongoDB or the driver, visit the following resources: - - The :ref:`Frequently Asked Questions (FAQ) ` for the - {+driver-short+} - The :ref:`Issues & Help ` page, which has information about reporting bugs, contributing to the driver, and finding additional resources diff --git a/source/fundamentals/connection/connect.txt b/source/connect/mongoclient.txt similarity index 97% rename from source/fundamentals/connection/connect.txt rename to source/connect/mongoclient.txt index 2e8b8625..99dbfde5 100644 --- a/source/fundamentals/connection/connect.txt +++ b/source/connect/mongoclient.txt @@ -1,8 +1,9 @@ .. _csharp-connect-to-mongodb: +.. _csharp-create-mongoclient: -================ -Connection Guide -================ +==================== +Create a MongoClient +==================== .. facet:: :name: genre @@ -18,7 +19,7 @@ Connection Guide :class: singlecol This guide shows you how to connect to a MongoDB instance or replica set -deployment using the {+driver-short+}. +deployment by using the {+driver-short+}. .. _csharp_connection_uri: diff --git a/source/crud.txt b/source/crud.txt new file mode 100644 index 00000000..e18b8ec5 --- /dev/null +++ b/source/crud.txt @@ -0,0 +1,24 @@ +.. _csharp-crud: + +=============== +CRUD Operations +=============== + +.. meta:: + :description: Learn how to run create, read, update, delete (CRUD) MongoDB operations by using the {+driver-long+}. + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + Insert Documents + Query Documents + Update One Document + Update Many Documents + Replace Documents + Delete Documents + Bulk Write Operations + Transactions + Store Large Files + Configure CRUD Operations + Geospatial Queries diff --git a/source/fundamentals/crud/write-operations/bulk-write.txt b/source/crud/bulk-write.txt similarity index 100% rename from source/fundamentals/crud/write-operations/bulk-write.txt rename to source/crud/bulk-write.txt diff --git a/source/fundamentals/read-write-configuration.txt b/source/crud/configure.txt similarity index 100% rename from source/fundamentals/read-write-configuration.txt rename to source/crud/configure.txt diff --git a/source/fundamentals/crud/write-operations/delete.txt b/source/crud/delete.txt similarity index 100% rename from source/fundamentals/crud/write-operations/delete.txt rename to source/crud/delete.txt diff --git a/source/fundamentals/geo.txt b/source/crud/geo.txt similarity index 100% rename from source/fundamentals/geo.txt rename to source/crud/geo.txt diff --git a/source/fundamentals/gridfs.txt b/source/crud/gridfs.txt similarity index 100% rename from source/fundamentals/gridfs.txt rename to source/crud/gridfs.txt diff --git a/source/fundamentals/crud/write-operations/insert.txt b/source/crud/insert.txt similarity index 99% rename from source/fundamentals/crud/write-operations/insert.txt rename to source/crud/insert.txt index e7f3e53f..0530e7df 100644 --- a/source/fundamentals/crud/write-operations/insert.txt +++ b/source/crud/insert.txt @@ -228,8 +228,8 @@ The following code uses the ``InsertMany()`` method to insert five new The ``InsertMany()`` method has no return value. You can verify that your documents were successfully inserted by executing a ``Find()`` -operation on the collection. For an example on how to find a document, -see :ref:`csharp-find-one`. +operation on the collection. For an example of how to find a document, +see :ref:`csharp-find`. .. _csharp-ordered-behavior: diff --git a/source/crud/query.txt b/source/crud/query.txt new file mode 100644 index 00000000..93468c74 --- /dev/null +++ b/source/crud/query.txt @@ -0,0 +1,21 @@ +.. _csharp-crud-read-operations: +.. _csharp-crud-query: + +=============== +Read Operations +=============== + +.. meta:: + :description: Learn about the commands for running MongoDB read operations by using the {+driver-long+}. + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + Specify a Query + Find Documents + Specify Documents to Return + Specify Fields to Return + Count Documents + Distinct Field Values + Access Data from a Cursor \ No newline at end of file diff --git a/source/fundamentals/crud/read-operations/count.txt b/source/crud/query/count.txt similarity index 99% rename from source/fundamentals/crud/read-operations/count.txt rename to source/crud/query/count.txt index 53dcede1..cc2e4aa1 100644 --- a/source/fundamentals/crud/read-operations/count.txt +++ b/source/crud/query/count.txt @@ -231,7 +231,6 @@ guides: - :ref:`csharp-specify-query` - :ref:`csharp-bson` - :ref:`csharp-guids` -- :ref:`csharp-builders` - :ref:`csharp-poco` API Documentation diff --git a/source/crud/query/cursors.txt b/source/crud/query/cursors.txt new file mode 100644 index 00000000..e69de29b diff --git a/source/fundamentals/crud/read-operations/distinct.txt b/source/crud/query/distinct.txt similarity index 100% rename from source/fundamentals/crud/read-operations/distinct.txt rename to source/crud/query/distinct.txt diff --git a/source/fundamentals/crud/read-operations/retrieve.txt b/source/crud/query/find.txt similarity index 99% rename from source/fundamentals/crud/read-operations/retrieve.txt rename to source/crud/query/find.txt index 4527d807..f5f2526e 100644 --- a/source/fundamentals/crud/read-operations/retrieve.txt +++ b/source/crud/query/find.txt @@ -1,4 +1,4 @@ -.. _csharp-retrieve: +.. _csharp-find: ============= Retrieve Data diff --git a/source/fundamentals/crud/read-operations/project.txt b/source/crud/query/project.txt similarity index 66% rename from source/fundamentals/crud/read-operations/project.txt rename to source/crud/query/project.txt index 6ad03656..cd24ad2d 100644 --- a/source/fundamentals/crud/read-operations/project.txt +++ b/source/crud/query/project.txt @@ -142,4 +142,90 @@ guide, see the following API Documentation: - `Find() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollectionExtensions.Find.html>`_ - `Projection <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Builders-1.Projection.html>`_ - `Include() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ProjectionDefinitionBuilder-1.Include.html>`_ -- `Exclude() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ProjectionDefinitionBuilder-1.Exclude.html>`_ \ No newline at end of file +- `Exclude() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ProjectionDefinitionBuilder-1.Exclude.html>`_ + +.. TODO: integrate into existing page + +Sample Class +------------ + +The code examples in this guide demonstrate how you can use builders to +create types to interact with documents in the sample collection ``plants.flowers``. +Documents in this collection are modeled by the following ``Flower`` class: + +.. literalinclude:: /includes/fundamentals/code-examples/builders.cs + :language: csharp + :dedent: + :start-after: start-model + :end-before: end-model + +Each builder class takes a generic type parameter +``TDocument`` which represents the type of document that you are working +with. In this guide, the ``Flower`` class is the document type used in +each builder class example. + +.. _csharp-builders-projection: + +Create a Projection +------------------- + +The ``ProjectionDefinitionBuilder`` class provides a type-safe interface for +defining a projection. Suppose you want to create a projection on the +``Name`` and ``Price`` fields, but exclude the ``Id`` field. + +Use builders to create the projection definition with the typed variant: + +.. code-block:: csharp + :copyable: true + + var builder = Builders.Projection; + var projection = builder.Include(f => f.Name).Include(f => f.Price).Exclude(f => f.Id); + +You can also use string-based field names to define the projection: + +.. code-block:: csharp + :copyable: true + + var builder = Builders.Projection; + var projection = builder.Include("Name").Include("Price").Exclude("Id"); + +Finally, you can use the ``Expression()`` method to define the +projection: + +.. code-block:: csharp + :copyable: true + + var builder = Builders.Projection; + var projection = builder.Expression(f => new { Name = f.Name, Price = f.Price }); + +This definition has a return type of ``ProjectionDefinition`` whereas the others return a +``ProjectionDefinition``. + +Lambda Expressions +~~~~~~~~~~~~~~~~~~ + +The driver supports using lambda expressions to render projections. When +you define a ``Find()`` projection with the ``Expression()`` method to +create a lambda expression, the driver inspects the expression +to determine which fields are referenced and automatically constructs a +server-side projection to return only those fields. + +You can also use lambda expressions to create new fields by performing +operations on values in your documents. The following example shows how +you can use a lambda expression to project a new ``Profit`` field +using the ``Price`` and ``Stock`` fields: + +.. code-block:: csharp + :copyable: true + + var builder = Builders.Projection; + var projection = builder.Expression(f => new { Profit = f.Price * f.Stock }); + +.. note:: ``Id`` Field Exclusion + + When you create a projection using a lambda expression, the output + automatically excludes the ``Id`` field unless you explicitly include + is as a projection field. + +- `ProjectionDefinitionBuilder <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ProjectionDefinitionBuilder-1.html>`__ \ No newline at end of file diff --git a/source/fundamentals/crud/read-operations/specify-documents-to-return.txt b/source/crud/query/specify-documents-to-return.txt similarity index 89% rename from source/fundamentals/crud/read-operations/specify-documents-to-return.txt rename to source/crud/query/specify-documents-to-return.txt index 99e7d85f..54a3b1c7 100644 --- a/source/fundamentals/crud/read-operations/specify-documents-to-return.txt +++ b/source/crud/query/specify-documents-to-return.txt @@ -203,7 +203,7 @@ skipping the first ``10`` documents: Additional Information ---------------------- -For more information about retrieving documents, see the :ref:`csharp-retrieve` guide. +For more information about retrieving documents, see the :ref:`csharp-find` guide. For more information about specifying a query, see the :ref:`csharp-specify-query` guide. @@ -217,4 +217,26 @@ guide, see the following API documentation: - `IFindFluent <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IFindFluent-2.html>`_ - `Limit() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IFindFluent-2.Limit.html>`_ - `Sort() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IFindFluent-2.Sort.html>`_ -- `Skip() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IFindFluent-2.Skip.html>`_ \ No newline at end of file +- `Skip() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IFindFluent-2.Skip.html>`_ + +.. TODO: integrate into existing page + +Sample Class +------------ + +The code examples in this guide demonstrate how you can use builders to +create types to interact with documents in the sample collection ``plants.flowers``. +Documents in this collection are modeled by the following ``Flower`` class: + +.. literalinclude:: /includes/fundamentals/code-examples/builders.cs + :language: csharp + :dedent: + :start-after: start-model + :end-before: end-model + +Each builder class takes a generic type parameter +``TDocument`` which represents the type of document that you are working +with. In this guide, the ``Flower`` class is the document type used in +each builder class example. + +- `SortDefinitionBuilder <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.SortDefinitionBuilder-1.html>`__ \ No newline at end of file diff --git a/source/fundamentals/specify-query.txt b/source/crud/query/specify-query.txt similarity index 77% rename from source/fundamentals/specify-query.txt rename to source/crud/query/specify-query.txt index 22bfa38b..bf508679 100644 --- a/source/fundamentals/specify-query.txt +++ b/source/crud/query/specify-query.txt @@ -109,8 +109,6 @@ same documents as the preceding example: var result = _guitarsCollection.Find(Builders.Filter.Empty).ToList(); -To learn more about using builders, see :ref:`csharp-builders`. - Comparison Operators -------------------- @@ -171,9 +169,6 @@ same documents as the preceding example: { "_id" : 4, "make" : "Kiesel", "models" : ["Ares", "Vader", "Solo"], "establishedYear" : 2015, "rating" : null } - -To learn more about using builders, see :ref:`csharp-builders`. - Logical Operators ----------------- @@ -232,8 +227,6 @@ same documents as the preceding example: { "_id" : 3, "make" : "PRS", "models" : ["Silver Sky", "SE", "Custom"], "establishedYear" : 1985, "rating" : 9 } -To learn more about using builders, see :ref:`csharp-builders`. - Array Operators --------------- @@ -285,8 +278,6 @@ documents that have 3 elements in the ``models`` field: { "_id" : 3, "make" : "PRS", "models" : ["Silver Sky", "SE", "Custom"], "establishedYear" : 1985, "rating" : 9 } { "_id" : 4, "make" : "Kiesel", "models" : ["Ares", "Vader", "Solo"], "establishedYear" : 2015, "rating" : null } -To learn more about using builders, see :ref:`csharp-builders`. - Element Operators ----------------- @@ -313,8 +304,6 @@ documents that have a ``rating`` field: { "_id" : 3, "make" : "PRS", "models" : ["Silver Sky", "SE", "Custom"], "establishedYear" : 1985, "rating" : 9 } { "_id" : 5, "make" : "Ibanez", "models" : ["RG", "AZ"], "establishedYear" : 1957, "rating" : 7 } -To learn more about using builders, see :ref:`csharp-builders`. - Evaluation Operators -------------------- @@ -332,7 +321,7 @@ documents that have a value in the ``make`` field that starts with the letter .. io-code-block:: :copyable: - .. input:: ../../../includes/fundamentals/code-examples/specify-query/FindRegexBuilder.cs + .. input:: /includes/fundamentals/code-examples/specify-query/FindRegexBuilder.cs :language: csharp .. output:: @@ -341,8 +330,6 @@ documents that have a value in the ``make`` field that starts with the letter { "_id" : 2, "make" : "Gibson", "models" : ["Les Paul", "SG", "Explorer"], "establishedYear" : 1902, "rating" : 8 } -To learn more about using builders, see :ref:`csharp-builders`. - Additional Information ---------------------- @@ -355,6 +342,95 @@ following Server Manual Entries: - :manual:`Element Query Operators ` - :manual:`Evaluation Query Operators ` -To learn more about using Builders, see :ref:`csharp-builders`. - To learn how to specify queries using LINQ, see :ref:`csharp-linq`. + +.. TODO: integrate into existing page + +Sample Class +------------ + +The code examples in this guide demonstrate how you can use builders to +create types to interact with documents in the sample collection ``plants.flowers``. +Documents in this collection are modeled by the following ``Flower`` class: + +.. literalinclude:: /includes/fundamentals/code-examples/builders.cs + :language: csharp + :dedent: + :start-after: start-model + :end-before: end-model + +Each builder class takes a generic type parameter +``TDocument`` which represents the type of document that you are working +with. In this guide, the ``Flower`` class is the document type used in +each builder class example. + +Construct a Filter +------------------ + +The ``FilterDefinitionBuilder`` class provides a type-safe interface for +building up queries. Suppose you want to query your collection for +documents matching the following criteria: + +- ``Price`` field value less than 20 +- ``Category`` field value is "Perennial" + +Use builders to create the filter definition with the typed variant: + +.. code-block:: csharp + :copyable: true + + var builder = Builders.Filter; + var filter = builder.Lt(f => f.Price, 20) & builder.Eq(f => f.Category, "Perennial"); + +Using the typed variant form provides compile-time safety. Additionally, +your IDE can provide refactoring support. + +Alternatively, you can use string-based field names to contruct the filter: + +.. code-block:: csharp + :copyable: true + + var builder = Builders.Filter; + var filter = builder.Lt("Price", 20) & builder.Eq("Category", "Perennial"); + +If you are using LINQ, you can also use the ``Inject()`` method to apply the filter +to a LINQ query: + +.. code-block:: csharp + :copyable: true + + var builder = Builders.Filter; + var filter = builder.Lt("Price", 20) & builder.Eq("Category", "Perennial"); + var query = collection.AsQueryable().Where(f => filter.Inject()); + +Array Operators +~~~~~~~~~~~~~~~ + +If your document has properties or fields that serialize to arrays, +you can use the methods beginning with ``Any``, such as ``AnyEq()`` or +``AnyLt()``, to compare the entire array against a single item. + +Use builders to check which documents in the collection have a +``Season`` array that includes "winter": + +.. code-block:: csharp + :copyable: true + + var builder = Builders.Filter; + var filter = builder.AnyEq(f => f.Season, "winter"); + +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. + +- `FilterDefinitionBuilder <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.FilterDefinitionBuilder-1.html>`__ \ No newline at end of file diff --git a/source/fundamentals/crud/write-operations/replace.txt b/source/crud/replace.txt similarity index 100% rename from source/fundamentals/crud/write-operations/replace.txt rename to source/crud/replace.txt diff --git a/source/fundamentals/transactions.txt b/source/crud/transactions.txt similarity index 100% rename from source/fundamentals/transactions.txt rename to source/crud/transactions.txt diff --git a/source/fundamentals/crud/write-operations/update-many.txt b/source/crud/update-many.txt similarity index 67% rename from source/fundamentals/crud/write-operations/update-many.txt rename to source/crud/update-many.txt index 7d46dfce..d4db84ef 100644 --- a/source/fundamentals/crud/write-operations/update-many.txt +++ b/source/crud/update-many.txt @@ -20,8 +20,8 @@ Update Many .. toctree:: :caption: Update Documents - Fields - Arrays + Fields + Arrays .. include:: /includes/page-templates/update/update.rst @@ -126,4 +126,50 @@ Update Many :start-after: // start-pipeline-async :end-before: // end-pipeline-async +.. TODO: integrate into existing page + +Sample Class +------------ + +The code examples in this guide demonstrate how you can use builders to +create types to interact with documents in the sample collection ``plants.flowers``. +Documents in this collection are modeled by the following ``Flower`` class: + +.. literalinclude:: /includes/fundamentals/code-examples/builders.cs + :language: csharp + :dedent: + :start-after: start-model + :end-before: end-model + +Each builder class takes a generic type parameter +``TDocument`` which represents the type of document that you are working +with. In this guide, the ``Flower`` class is the document type used in +each builder class example. + +Define an Update +---------------- + +The ``UpdateDefinitionBuilder`` class provides a type-safe interface for +building up an update specification. Suppose you want to create an +update specification with the following criteria: + +- Create the new field ``SunRequirement`` +- Multiply the ``Price`` field value by 0.9 + +Use builders to create the update specification with the typed variant: + +.. code-block:: csharp + :copyable: true + + var builder = Builders.Update; + var update = builder.Set(f => f.SunRequirement, "Full sun").Mul(f => f.Price, 0.9); + +Alternatively, you can use string-based field names to define the update: +.. code-block:: csharp + :copyable: true + + var builder = Builders.Update; + var update = builder.Set("SunRequirement", "Full sun").Mul("Price", 0.9); + +- `UpdateDefinitionBuilder <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateDefinitionBuilder-1.html>`__ \ No newline at end of file diff --git a/source/fundamentals/crud/write-operations/update-many/arrays.txt b/source/crud/update-many/arrays.txt similarity index 100% rename from source/fundamentals/crud/write-operations/update-many/arrays.txt rename to source/crud/update-many/arrays.txt diff --git a/source/fundamentals/crud/write-operations/update-many/fields.txt b/source/crud/update-many/fields.txt similarity index 100% rename from source/fundamentals/crud/write-operations/update-many/fields.txt rename to source/crud/update-many/fields.txt diff --git a/source/fundamentals/crud/write-operations/update-one.txt b/source/crud/update-one.txt similarity index 61% rename from source/fundamentals/crud/write-operations/update-one.txt rename to source/crud/update-one.txt index 9afb9fd3..5bdd1db7 100644 --- a/source/fundamentals/crud/write-operations/update-one.txt +++ b/source/crud/update-one.txt @@ -20,8 +20,8 @@ Update One .. toctree:: :caption: Update Documents - Fields - Arrays + Fields + Arrays .. include:: /includes/page-templates/update/update.rst @@ -112,4 +112,52 @@ Update One :copyable: true :dedent: :start-after: // start-pipeline-async - :end-before: // end-pipeline-async \ No newline at end of file + :end-before: // end-pipeline-async + +.. TODO: integrate into existing page + +Sample Class +------------ + +The code examples in this guide demonstrate how you can use builders to +create types to interact with documents in the sample collection ``plants.flowers``. +Documents in this collection are modeled by the following ``Flower`` class: + +.. literalinclude:: /includes/fundamentals/code-examples/builders.cs + :language: csharp + :dedent: + :start-after: start-model + :end-before: end-model + +Each builder class takes a generic type parameter +``TDocument`` which represents the type of document that you are working +with. In this guide, the ``Flower`` class is the document type used in +each builder class example. + +Define an Update +---------------- + +The ``UpdateDefinitionBuilder`` class provides a type-safe interface for +building up an update specification. Suppose you want to create an +update specification with the following criteria: + +- Create the new field ``SunRequirement`` +- Multiply the ``Price`` field value by 0.9 + +Use builders to create the update specification with the typed variant: + +.. code-block:: csharp + :copyable: true + + var builder = Builders.Update; + var update = builder.Set(f => f.SunRequirement, "Full sun").Mul(f => f.Price, 0.9); + +Alternatively, you can use string-based field names to define the update: + +.. code-block:: csharp + :copyable: true + + var builder = Builders.Update; + var update = builder.Set("SunRequirement", "Full sun").Mul("Price", 0.9); + +- `UpdateDefinitionBuilder <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateDefinitionBuilder-1.html>`__ \ No newline at end of file diff --git a/source/fundamentals/crud/write-operations/update-one/arrays.txt b/source/crud/update-one/arrays.txt similarity index 100% rename from source/fundamentals/crud/write-operations/update-one/arrays.txt rename to source/crud/update-one/arrays.txt diff --git a/source/fundamentals/crud/write-operations/update-one/fields.txt b/source/crud/update-one/fields.txt similarity index 100% rename from source/fundamentals/crud/write-operations/update-one/fields.txt rename to source/crud/update-one/fields.txt diff --git a/source/data-formats.txt b/source/data-formats.txt new file mode 100644 index 00000000..7bd3b913 --- /dev/null +++ b/source/data-formats.txt @@ -0,0 +1,41 @@ +.. _csharp-data-formats: + +======================== +Specialized Data Formats +======================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: bson, guid, serialization, extended json, custom types, time series + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + BSON + Extended JSON + Custom Types + GUIDs + Time Series Data + +Overview +-------- + +You can use several types of specialized data formats in your {+driver-short+} +application. To learn how to work with these data formats, see the following +sections: + +- Learn how to work with BSON documents in the :ref:`csharp-bson` guide. +- Learn how to translate BSON to Extended JSON in the :ref:`csharp-extended-json` guide. +- Learn how to serialize custom types in the :ref:`csharp-custom-types` guide. +- Learn about globally unique identifiers (GUIDs) and how to maintain cross-language + compatibility while working with them in the :ref:`csharp-guids` guide. \ No newline at end of file diff --git a/source/fundamentals/bson.txt b/source/data-formats/bson.txt similarity index 100% rename from source/fundamentals/bson.txt rename to source/data-formats/bson.txt diff --git a/source/data-formats/custom-types.txt b/source/data-formats/custom-types.txt new file mode 100644 index 00000000..d05e1fc3 --- /dev/null +++ b/source/data-formats/custom-types.txt @@ -0,0 +1,26 @@ +.. _csharp-custom-types: + +============ +Custom Types +============ + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: polymorphism, serialization, deserialization, poco + +.. toctree:: + :caption: Custom Types + + Class Mapping + POCOs + Polymorphic Objects + Serialization \ No newline at end of file diff --git a/source/fundamentals/serialization/class-mapping.txt b/source/data-formats/custom-types/class-mapping.txt similarity index 100% rename from source/fundamentals/serialization/class-mapping.txt rename to source/data-formats/custom-types/class-mapping.txt diff --git a/source/fundamentals/serialization/poco.txt b/source/data-formats/custom-types/poco.txt similarity index 99% rename from source/fundamentals/serialization/poco.txt rename to source/data-formats/custom-types/poco.txt index 143d3059..196249ad 100644 --- a/source/fundamentals/serialization/poco.txt +++ b/source/data-formats/custom-types/poco.txt @@ -728,9 +728,6 @@ Additional Information For a full list of serialization-related attributes, see the `Serialization.Attributes API documentation <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.Serialization.Attributes.html>`__. -For additional read and write operation examples using POCOs, see the :ref:`Usage Examples -` or the :ref:`CRUD Fundamentals Pages `. - To learn more about how the driver maps BSON documents to POCOs, see :ref:`csharp-class-mapping`. diff --git a/source/fundamentals/serialization/polymorphic-objects.txt b/source/data-formats/custom-types/polymorphic-objects.txt similarity index 100% rename from source/fundamentals/serialization/polymorphic-objects.txt rename to source/data-formats/custom-types/polymorphic-objects.txt diff --git a/source/fundamentals/serialization.txt b/source/data-formats/custom-types/serialization.txt similarity index 96% rename from source/fundamentals/serialization.txt rename to source/data-formats/custom-types/serialization.txt index a144c98a..af352a0b 100644 --- a/source/fundamentals/serialization.txt +++ b/source/data-formats/custom-types/serialization.txt @@ -17,14 +17,6 @@ Serialization :depth: 2 :class: singlecol -.. toctree:: - :caption: Serialization - - Class Mapping - POCOs - Polymorphic Objects - GUIDs - Overview -------- diff --git a/source/data-formats/extended-json.txt b/source/data-formats/extended-json.txt new file mode 100644 index 00000000..c2a69aa8 --- /dev/null +++ b/source/data-formats/extended-json.txt @@ -0,0 +1,11 @@ +.. _csharp-extended-json: + +============= +Extended JSON +============= + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol \ No newline at end of file diff --git a/source/fundamentals/serialization/guid-serialization.txt b/source/data-formats/guids.txt similarity index 100% rename from source/fundamentals/serialization/guid-serialization.txt rename to source/data-formats/guids.txt diff --git a/source/fundamentals/time-series.txt b/source/data-formats/time-series.txt similarity index 99% rename from source/fundamentals/time-series.txt rename to source/data-formats/time-series.txt index b1b2e6c0..78384c13 100644 --- a/source/fundamentals/time-series.txt +++ b/source/data-formats/time-series.txt @@ -90,7 +90,7 @@ Query a Time Series Collection ------------------------------ To query a time series collection, follow the conventions for retrieving and aggregating -data. For more information about these conventions, see the :ref:`csharp-retrieve` and +data. For more information about these conventions, see the :ref:`csharp-find` and :ref:`csharp-aggregation` guides. Additional Information diff --git a/source/fundamentals/database-collection.txt b/source/databases-collections.txt similarity index 99% rename from source/fundamentals/database-collection.txt rename to source/databases-collections.txt index 919d9e03..9cf8ad93 100644 --- a/source/fundamentals/database-collection.txt +++ b/source/databases-collections.txt @@ -1,4 +1,5 @@ .. _csharp-db-coll: +.. _csharp-databases-collections: ========================= Databases and Collections @@ -17,9 +18,6 @@ Databases and Collections :depth: 2 :class: singlecol -.. toctree:: - /fundamentals/databases-collections/run-command - Overview -------- diff --git a/source/fundamentals.txt b/source/fundamentals.txt deleted file mode 100644 index fe326063..00000000 --- a/source/fundamentals.txt +++ /dev/null @@ -1,58 +0,0 @@ -.. _csharp-fundamentals: - -============ -Fundamentals -============ - -.. meta:: - :description: Learn how to use the (+driver-long+} to run commands on MongoDB. - -.. toctree:: - :titlesonly: - :maxdepth: 1 - - Connection - Databases & Collections - CRUD Operations - Operations with Builders - Atlas Search - Stable API - Authentication - Aggregation - LINQ - BSON Operations - Query - Serialization - Transactions - Indexes - Logging - Time Series Collections - In-Use Encryption - Search Geospatially - Store Large Files - Replica Set Operations - OData - Monitoring - -- :ref:`Connecting to MongoDB ` -- :ref:`csharp-db-coll` -- :ref:`csharp-crud` -- :ref:`csharp-builders` -- :ref:`csharp-atlas-search` -- :ref:`csharp-stable-api` -- :ref:`csharp-authentication-mechanisms` -- :ref:`csharp-aggregation` -- :ref:`csharp-linq` -- :ref:`csharp-bson` -- :ref:`csharp-specify-query` -- :ref:`csharp-serialization` -- :ref:`csharp-transactions` -- :ref:`csharp-indexes` -- :ref:`csharp-logging` -- :ref:`csharp-time-series` -- :ref:`Encrypt Fields ` -- :ref:`csharp-geo` -- :ref:`csharp-gridfs` -- :ref:`csharp-read-write-config` -- :ref:`csharp-odata` -- :ref:`csharp-monitoring` \ No newline at end of file diff --git a/source/fundamentals/aggregation.txt b/source/fundamentals/aggregation.txt deleted file mode 100644 index 96169dd5..00000000 --- a/source/fundamentals/aggregation.txt +++ /dev/null @@ -1,221 +0,0 @@ -.. _csharp-aggregation: - -=========== -Aggregation -=========== - -.. facet:: - :name: genre - :values: reference - -.. meta:: - :keywords: code example, transform, pipeline - -.. contents:: On this page - :local: - :backlinks: none - :depth: 2 - :class: singlecol - -Overview --------- - -In this guide, you can learn how to use the {+driver-long+} to perform -**aggregation operations**. - -Aggregation operations process data in your MongoDB collections and -return computed results. The MongoDB Aggregation framework is modeled on the -concept of data processing pipelines. Documents enter a pipeline comprised of one or -more stages, and this pipeline transforms the documents into an aggregated result. - -Analogy -~~~~~~~ - -Aggregation operations function similarly to car factories with assembly -lines. The assembly lines have stations with specialized tools to -perform specific tasks. For example, when building a car, the assembly -line begins with the frame. Then, as the car frame moves through the -assembly line, each station assembles a separate part. The result is a -transformed final product, the finished car. - -The assembly line represents the *aggregation pipeline*, the individual -stations represent the *aggregation stages*, the specialized tools -represent the *expression operators*, and the finished product -represents the *aggregated result*. - -Compare Aggregation and Find Operations ---------------------------------------- - -The following table lists the different tasks you can perform with find -operations, compared to what you can achieve with aggregation -operations. The aggregation framework provides expanded functionality -that allows you to transform and manipulate your data. - -.. list-table:: - :header-rows: 1 - :widths: 50 50 - - * - Find Operations - - Aggregation Operations - - * - | Select *certain* documents to return - | Select *which* fields to return - | Sort the results - | Limit the results - | Count the results - - | Select *certain* documents to return - | Select *which* fields to return - | Sort the results - | Limit the results - | Count the results - | Group the results - | Rename fields - | Compute new fields - | Summarize data - | Connect and merge data sets - -Server Limitations ------------------- - -Consider the following :manual:`limitations ` when -performing aggregation operations: - -- Returned documents must not violate the :manual:`BSON document size limit ` - of 16 megabytes. - -- Pipeline stages have a memory limit of 100 megabytes by default. If required, you can exceed this limit by setting - the `AllowDiskUse <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.AggregateOptions.AllowDiskUse.html#MongoDB_Driver_AggregateOptions_AllowDiskUse>`__ - property of the ``AggregateOptions`` object that you pass to the ``Aggregate()`` method. - -- The :manual:`$graphLookup ` stage has - a strict memory limit of 100 megabytes and ignores the ``AllowDiskUse`` property. - -Aggregation Example -------------------- - -To perform an aggregation, pass a list of aggregation stages to the -``IMongoCollection.Aggregate()`` method. - -.. note:: - - This example uses 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 :ref:`csharp-get-started`. - -The following code example produces a count of the number of bakeries in each borough -of New York City. To do so, it uses an aggregation pipeline that contains the following stages: - -- A :manual:`$match ` stage to filter for documents whose - ``cuisine`` field contains the value ``"Bakery"``. - -- A :manual:`$group ` stage to group the matching - documents by the ``borough`` field, accumulating a count of documents for each distinct value - of that field. - -The following sections implement this example by using LINQ, Builders, and BsonDocument -approaches to create and combine the aggregation stages used in the example pipeline. - -LINQ Approach -~~~~~~~~~~~~~ - -.. io-code-block:: - - .. input:: /includes/fundamentals/code-examples/LinqAggregation.cs - :language: csharp - :dedent: - :start-after: begin-aggregation - :end-before: end-aggregation - - .. output:: - :language: console - :visible: false - - { _id = Bronx, Count = 71 } - { _id = Brooklyn, Count = 173 } - { _id = Staten Island, Count = 20 } - { _id = Missing, Count = 2 } - { _id = Manhattan, Count = 221 } - { _id = Queens, Count = 204 } - -To learn more about using LINQ to construct aggregation pipelines, see the -:ref:`csharp-linq` guide. - -Builders Approach -~~~~~~~~~~~~~~~~~ - -.. io-code-block:: - - .. input:: /includes/fundamentals/code-examples/BuilderAggregation.cs - :language: csharp - :dedent: - :start-after: begin-aggregation - :end-before: end-aggregation - - .. output:: - :language: console - :visible: false - - { _id = Bronx, Count = 71 } - { _id = Brooklyn, Count = 173 } - { _id = Staten Island, Count = 20 } - { _id = Missing, Count = 2 } - { _id = Manhattan, Count = 221 } - { _id = Queens, Count = 204 } - -To learn more about using builders to construct aggregation pipelines, -see the :ref:`csharp-builders-aggregation` section of the Operations with Builders guide. - -BsonDocument Approach -~~~~~~~~~~~~~~~~~~~~~ - -.. io-code-block:: - - .. input:: /includes/fundamentals/code-examples/Aggregation.cs - :language: csharp - :dedent: - :start-after: begin-aggregation - :end-before: end-aggregation - - .. output:: - :language: console - :visible: false - - { "_id" : "Brooklyn", "count" : 173 } - { "_id" : "Manhattan", "count" : 221 } - { "_id" : "Bronx", "count" : 71 } - { "_id" : "Missing", "count" : 2 } - { "_id" : "Staten Island", "count" : 20 } - { "_id" : "Queens", "count" : 204 } - -Additional Information ----------------------- - -MongoDB Server Manual -~~~~~~~~~~~~~~~~~~~~~ - -To view a full list of expression operators, see -:manual:`Aggregation Operators `. - -To learn more about assembling an aggregation pipeline and view examples, see -:manual:`Aggregation Pipeline `. - -To learn more about creating pipeline stages, see -:manual:`Aggregation Stages `. - -To learn about explaining MongoDB aggregation operations, see -:manual:`Explain Results ` and -:manual:`Query Plans `. - -API Documentation -~~~~~~~~~~~~~~~~~ - -For more information about the aggregation operations discussed in this guide, see the -following API documentation: - -- `Aggregate() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.Aggregate.html>`__ -- `AggregateOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.AggregateOptions.html>`__ -- `Group() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.PipelineStageDefinitionBuilder.Group.html>`__ -- `Match() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.PipelineStageDefinitionBuilder.Match.html>`__ -- `Where() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Linq.MongoQueryable.Where.html>`__ -- `GroupBy() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Linq.MongoQueryable.GroupBy.html>`__ -- `Select() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Linq.MongoQueryable.Select.html>`__ diff --git a/source/fundamentals/connection.txt b/source/fundamentals/connection.txt deleted file mode 100644 index 3b0ec89a..00000000 --- a/source/fundamentals/connection.txt +++ /dev/null @@ -1,31 +0,0 @@ -.. _csharp-connection: - -========== -Connection -========== - -.. default-domain:: mongodb - -.. toctree:: - - Connection Guide - Connection Options - Configure TLS - Network Compression - Connect with AWS Lambda - -.. contents:: On this page - :local: - :backlinks: none - :depth: 1 - :class: singlecol - -Overview --------- - -In this section, you'll learn how to use the {+driver-short+} to connect your application to a MongoDB deployment. Click a link in the following list to jump to a topic: - -- :ref:`How to Connect to MongoDB ` -- :ref:`Connection Options ` -- :ref:`Enable TLS on a Connection ` -- :atlas:`Connect to MongoDB Atlas from AWS Lambda ` \ No newline at end of file diff --git a/source/fundamentals/crud.txt b/source/fundamentals/crud.txt deleted file mode 100644 index 9e3275dc..00000000 --- a/source/fundamentals/crud.txt +++ /dev/null @@ -1,17 +0,0 @@ -.. _csharp-crud: - -=============== -CRUD Operations -=============== - -.. meta:: - :description: Learn how to run create, read, update, delete (CRUD) MongoDB operations by using the {+driver-long+}. - -.. toctree:: - :caption: CRUD Operations - - Write - Read - -- :ref:`csharp-crud-read-operations` -- :ref:`csharp-crud-write-operations` diff --git a/source/fundamentals/crud/read-operations.txt b/source/fundamentals/crud/read-operations.txt deleted file mode 100644 index 6938a56a..00000000 --- a/source/fundamentals/crud/read-operations.txt +++ /dev/null @@ -1,25 +0,0 @@ -.. _csharp-crud-read-operations: - -=============== -Read Operations -=============== - -.. meta:: - :description: Learn about the commands for running MongoDB read operations by using the {+driver-long+}. - -.. toctree:: - :caption: Read Operations - - Retrieve Data - Specify Fields to Return - Count Documents - List Distinct Values - Monitor Data Changes - Specify Query Results - -- :ref:`csharp-retrieve` -- :ref:`csharp-project` -- :ref:`csharp-count-documents` -- :ref:`csharp-distinct` -- :ref:`csharp-change-streams` -- :ref:`csharp-specify-documents-to-return` diff --git a/source/fundamentals/crud/write-operations.txt b/source/fundamentals/crud/write-operations.txt deleted file mode 100644 index bb946729..00000000 --- a/source/fundamentals/crud/write-operations.txt +++ /dev/null @@ -1,25 +0,0 @@ -.. _csharp-crud-write-operations: - -================ -Write Operations -================ - -.. meta:: - :description: Learn about the commands for running MongoDB write operations by using the {+driver-long+}. - -.. toctree:: - :caption: Write Operations - - Insert - Update One - Update Many - Replace - Delete - Bulk Write Operations - -- :ref:`csharp-insert-guide` -- :ref:`csharp-update-one` -- :ref:`csharp-update-many` -- :ref:`csharp-replace-documents` -- :ref:`csharp-delete-guide` -- :ref:`csharp-bulk-write` diff --git a/source/get-started.txt b/source/get-started.txt index bab7ee64..2642c9ea 100644 --- a/source/get-started.txt +++ b/source/get-started.txt @@ -18,13 +18,6 @@ Get Started with the {+driver-short+} :description: Learn how to create an app to connect to MongoDB deployment by using the .NET/C# driver. :keywords: quick start, tutorial, basics -.. toctree:: - - Download the Driver - Deploy a Cluster - Create a Connection String - Run a Sample Query - Overview -------- @@ -42,3 +35,214 @@ MongoDB Atlas. Follow this guide to connect a sample {+language+} application to a MongoDB Atlas deployment. If you prefer to connect to MongoDB using a different driver or programming language, see our :driver:`list of official drivers <>`. + +.. _csharp-get-started-download-driver: + +Download the {+driver-short+} +---------------------------- + +.. procedure:: + :style: connected + + .. step:: Create a Project Directory + + In your shell, run the following commands to create a + directory called ``csharp-quickstart`` and initialize a {+framework+} project for + a new console application: + + .. code-block:: bash + + mkdir csharp-quickstart + cd csharp-quickstart + dotnet new console + + .. step:: Install the {+driver-short+} + + Run the following command to install the current version of the {+driver-short+} + as a dependency of your project: + + .. code-block:: bash + + dotnet add package MongoDB.Driver + +After you complete these steps, you have a new {+framework+} project +and the {+driver-short+} installed. + +.. _csharp-get-started-deploy-cluster: + +Deploy a MongoDB Atlas Cluster +------------------------------ + +You can create a free tier MongoDB deployment on MongoDB Atlas +to store and manage your data. MongoDB Atlas hosts and manages +your MongoDB database in the cloud. + +.. procedure:: + :style: connected + + .. step:: Create a Free MongoDB Deployment on Atlas + + Complete the :atlas:`Get Started with Atlas ` + guide to set up a new Atlas account and load sample data into a new free + tier MongoDB deployment. + + .. step:: Save your Credentials + + After you create your database user, save that user's + username and password to a safe location for use in an upcoming step. + +After you complete these steps, you have a new free tier MongoDB +deployment on Atlas, database user credentials, and sample data loaded +in your database. + +.. _csharp-get-started-connection-string: + +Create a Connection String +-------------------------- + +You can connect to your MongoDB deployment by providing a +**connection URI**, also called a *connection string*, which +instructs the driver on how to connect to a MongoDB deployment +and how to behave while connected. + +The connection string includes the hostname or IP address and +port of your deployment, the authentication mechanism, user credentials +when applicable, and connection options. + +.. tip:: + + To connect to a self-managed (non-Atlas) deployment, see + :ref:`csharp-connect-to-mongodb`. + +.. procedure:: + :style: connected + + .. step:: Find your MongoDB Atlas Connection String + + To retrieve your connection string for the deployment that + you created in the :ref:`previous step `, + log into your Atlas account and navigate to the + :guilabel:`Database` section and click the :guilabel:`Connect` button + for your new deployment. + + .. figure:: /includes/figures/atlas_connection_select_cluster.png + :alt: The connect button in the clusters section of the Atlas UI + + Proceed to the :guilabel:`Connect your application` section and select + "C# / .NET" from the :guilabel:`Driver` selection menu and the version + that best matches the version you installed from the :guilabel:`Version` + selection menu. + + Select the :guilabel:`Password (SCRAM)` authentication mechanism. + + Deselect the :guilabel:`Include full driver code example` option to view + the connection string. + + .. step:: Copy your Connection String + + Click the button on the right of the connection string to copy it to + your clipboard as shown in the following screenshot: + + .. figure:: /includes/figures/atlas_connection_copy_string.png + :alt: The connection string copy button in the Atlas UI + + .. step:: Update the Placeholders + + Paste this connection string into a file in your preferred text editor + and replace the ```` and ```` placeholders with + your database user's username and password. + + Save this file to a safe location for use in the next step. + + .. step:: Set an Environment Variable + + In your shell, run the following code to save your MongoDB + :ref:`connection string ` to an + environment variable. Replace ```` with the connection + string that you saved to a file in the previous step. + + .. code-block:: bash + + export MONGODB_URI="" + + .. note:: PowerShell + + If you're using Microsoft PowerShell, run the following command instead: + + .. code-block:: bash + + set MONGODB_URI="" + + Storing your credentials in an environment variable is safer than hardcoding them + in your source code. + +After completing these steps, you have a connection string that +contains your database username and password. + +.. _csharp-get-started-run-sample-query: + +Run a Sample Query +------------------ + +.. procedure:: + :style: connected + + .. step:: Create your {+lang-framework+} Application + + Copy and paste the following code into the ``Program.cs`` file in your application: + + .. literalinclude:: /includes/quick-start/Program.cs + :language: csharp + :dedent: + + .. step:: Run your Application + + In your shell, run the following command to start this application: + + .. code-block:: sh + + dotnet run csharp-quickstart.csproj + + The output includes details of the retrieved movie document: + + .. code-block:: none + + { + _id: ..., + plot: 'A young man is accidentally sent 30 years into the past...', + genres: [ 'Adventure', 'Comedy', 'Sci-Fi' ], + ... + title: 'Back to the Future', + ... + } + + .. tip:: + + If you encounter an error or see no output, ensure that you specified the + proper connection string, and that you loaded the + sample data. + +After you complete these steps, you have a working application that +uses the driver to connect to your MongoDB deployment, runs a query on +the sample data, and prints out the result. + +.. _csharp-get-started-next-steps: + +Next Steps +---------- + +Congratulations on completing the tutorial! + +In this tutorial, you created a {+language+} application that +connects to a MongoDB deployment hosted on MongoDB Atlas +and retrieves a document that matches a query. + +Learn more about the {+driver-short+} from the following resources: + +- Learn how to insert documents in the :ref:`` section. +- Learn how to find documents in the :ref:`` section. +- Learn how to update documents in the :ref:`` and + :ref:`` sections. +- Learn how to delete documents in the :ref:`` section. + +.. include:: /includes/get-started/quickstart-troubleshoot.rst \ No newline at end of file diff --git a/source/get-started/create-connection-string.txt b/source/get-started/create-connection-string.txt deleted file mode 100644 index 1a3524c5..00000000 --- a/source/get-started/create-connection-string.txt +++ /dev/null @@ -1,86 +0,0 @@ -.. _csharp-get-started-connection-string: - -========================== -Create a Connection String -========================== - -You can connect to your MongoDB deployment by providing a -**connection URI**, also called a *connection string*, which -instructs the driver on how to connect to a MongoDB deployment -and how to behave while connected. - -The connection string includes the hostname or IP address and -port of your deployment, the authentication mechanism, user credentials -when applicable, and connection options. - -.. tip:: - - To connect to a self-managed (non-Atlas) deployment, see - :ref:`csharp-connect-to-mongodb`. - -.. procedure:: - :style: connected - - .. step:: Find your MongoDB Atlas Connection String - - To retrieve your connection string for the deployment that - you created in the :ref:`previous step `, - log into your Atlas account and navigate to the - :guilabel:`Database` section and click the :guilabel:`Connect` button - for your new deployment. - - .. figure:: /includes/figures/atlas_connection_select_cluster.png - :alt: The connect button in the clusters section of the Atlas UI - - Proceed to the :guilabel:`Connect your application` section and select - "C# / .NET" from the :guilabel:`Driver` selection menu and the version - that best matches the version you installed from the :guilabel:`Version` - selection menu. - - Select the :guilabel:`Password (SCRAM)` authentication mechanism. - - Deselect the :guilabel:`Include full driver code example` option to view - the connection string. - - .. step:: Copy your Connection String - - Click the button on the right of the connection string to copy it to - your clipboard as shown in the following screenshot: - - .. figure:: /includes/figures/atlas_connection_copy_string.png - :alt: The connection string copy button in the Atlas UI - - .. step:: Update the Placeholders - - Paste this connection string into a file in your preferred text editor - and replace the ```` and ```` placeholders with - your database user's username and password. - - Save this file to a safe location for use in the next step. - - .. step:: Set an Environment Variable - - In your shell, run the following code to save your MongoDB - :ref:`connection string ` to an - environment variable. Replace ```` with the connection - string that you saved to a file in the previous step. - - .. code-block:: bash - - export MONGODB_URI="" - - .. note:: PowerShell - - If you're using Microsoft PowerShell, run the following command instead: - - .. code-block:: bash - - set MONGODB_URI="" - - Storing your credentials in an environment variable is safer than hardcoding them - in your source code. - -After completing these steps, you have a connection string that -contains your database username and password. - -.. include:: /includes/get-started/quickstart-troubleshoot.rst \ No newline at end of file diff --git a/source/get-started/deploy-cluster.txt b/source/get-started/deploy-cluster.txt deleted file mode 100644 index f3849975..00000000 --- a/source/get-started/deploy-cluster.txt +++ /dev/null @@ -1,29 +0,0 @@ -.. _csharp-get-started-deploy-cluster: - -============================== -Deploy a MongoDB Atlas Cluster -============================== - -You can create a free tier MongoDB deployment on MongoDB Atlas -to store and manage your data. MongoDB Atlas hosts and manages -your MongoDB database in the cloud. - -.. procedure:: - :style: connected - - .. step:: Create a Free MongoDB Deployment on Atlas - - Complete the :atlas:`Get Started with Atlas ` - guide to set up a new Atlas account and load sample data into a new free - tier MongoDB deployment. - - .. step:: Save your Credentials - - After you create your database user, save that user's - username and password to a safe location for use in an upcoming step. - -After you complete these steps, you have a new free tier MongoDB -deployment on Atlas, database user credentials, and sample data loaded -in your database. - -.. include:: /includes/get-started/quickstart-troubleshoot.rst \ No newline at end of file diff --git a/source/get-started/download-driver.txt b/source/get-started/download-driver.txt deleted file mode 100644 index 66aebe51..00000000 --- a/source/get-started/download-driver.txt +++ /dev/null @@ -1,34 +0,0 @@ -.. _csharp-get-started-download-driver: - -=========================== -Download the {+driver-short+} -=========================== - -.. procedure:: - :style: connected - - .. step:: Create a Project Directory - - In your shell, run the following commands to create a - directory called ``csharp-quickstart`` and initialize a {+framework+} project for - a new console application: - - .. code-block:: bash - - mkdir csharp-quickstart - cd csharp-quickstart - dotnet new console - - .. step:: Install the {+driver-short+} - - Run the following command to install the current version of the {+driver-short+} - as a dependency of your project: - - .. code-block:: bash - - dotnet add package MongoDB.Driver - -After you complete these steps, you have a new {+framework+} project -and the {+driver-short+} installed. - -.. include:: /includes/get-started/quickstart-troubleshoot.rst \ No newline at end of file diff --git a/source/get-started/run-sample-query.txt b/source/get-started/run-sample-query.txt deleted file mode 100644 index 0a79e9d3..00000000 --- a/source/get-started/run-sample-query.txt +++ /dev/null @@ -1,49 +0,0 @@ -.. _csharp-get-started-run-sample-query: - -================== -Run a Sample Query -================== - -.. procedure:: - :style: connected - - .. step:: Create your {+lang-framework+} Application - - Copy and paste the following code into the ``Program.cs`` file in your application: - - .. literalinclude:: /includes/quick-start/Program.cs - :language: csharp - :dedent: - - .. step:: Run your Application - - In your shell, run the following command to start this application: - - .. code-block:: sh - - dotnet run csharp-quickstart.csproj - - The output includes details of the retrieved movie document: - - .. code-block:: none - - { - _id: ..., - plot: 'A young man is accidentally sent 30 years into the past...', - genres: [ 'Adventure', 'Comedy', 'Sci-Fi' ], - ... - title: 'Back to the Future', - ... - } - - .. tip:: - - If you encounter an error or see no output, ensure that you specified the - proper connection string, and that you loaded the - sample data. - -After you complete these steps, you have a working application that -uses the driver to connect to your MongoDB deployment, runs a query on -the sample data, and prints out the result. - -.. include:: /includes/get-started/quickstart-troubleshoot.rst diff --git a/source/index.txt b/source/index.txt index 0730ca4c..50626999 100644 --- a/source/index.txt +++ b/source/index.txt @@ -1,3 +1,5 @@ +.. _csharp-index: + ================= MongoDB C# Driver ================= @@ -11,143 +13,116 @@ MongoDB C# Driver .. toctree:: - Previous Versions Get Started - Quick Reference - What's New - Usage Examples - Fundamentals - API Documentation <{+new-api-root+}/index.html> - FAQ - Connection Troubleshooting + Connect + Databases & Collections + CRUD Operations + Aggregation + Data Formats + Indexes + Run a Database Command + Atlas Search + Atlas Vector Search + Logging and Monitoring + Security + Integrations + Reference + API Documentation <{+api-root+}> Issues & Help - Compatibility - Upgrade - Entity Framework Provider - {+analyzer-short+} -Introduction ------------- +Overview +-------- Welcome to the documentation site for the official {+driver-long+}. You can add the driver to your application to work with MongoDB in {+language+}. -Download the driver using `NuGet `__, or set up a runnable -project by following our :ref:`Get Started ` guide. - -Previous Versions ------------------ - -For documentation on versions of the driver v2.18 and earlier, see the :ref:`csharp-previous-versions` section. - -Connect to a Compatible MongoDB Deployment ------------------------------------------- - -You can use the {+driver-short+} to connect to MongoDB -deployments running on one of the following hosted services or editions: - -.. include:: /includes/fact-environments.rst Get Started ----------- -Learn how to establish a connection to MongoDB Atlas and begin -working with data in the :ref:`csharp-get-started` section. - -Quick Reference ---------------- - -See driver syntax examples for common MongoDB commands in the -:ref:`Quick Reference ` section. +Learn how to install the driver, establish a connection to MongoDB, and begin +working with data in the :ref:`csharp-get-started` tutorial. -What's New ----------- +Connect to MongoDB +------------------ -For a list of new features and changes in each version, see the :ref:`What's New ` -section. - -Usage Examples --------------- - -For fully runnable code snippets and explanations for common -methods, see :ref:`csharp-usage-examples`. - -Fundamentals ------------- +Learn how to create and configure a connection to a MongoDB deployment +in the :ref:`csharp-connect` section. -For detailed information on key concepts of using the {+driver-short+}, see -:ref:`csharp-fundamentals`. +Databases and Collections +------------------------- -API Documentation ------------------ +Learn how to use the {+driver-short+} to work with MongoDB databases and collections +in the :ref:`csharp-databases-collections` section. -For detailed information about types and methods in the {+driver-short+}, see -the `{+driver-long+} API documentation -<{+new-api-root+}/index.html>`__. +Read and Write Data +------------------- -Take the Free Online Course Taught by MongoDB ---------------------------------------------- +Learn how to find, update, and delete data in the :ref:`csharp-crud` section. -.. list-table:: +Transform Your Data with Aggregation +------------------------------------ - * - .. figure:: /includes/figures/M220N.png - :alt: Banner for the C# MongoDB University Course +Learn how to use the {+driver-short+} to perform aggregation operations in the +:ref:`csharp-aggregation` section. - - `Using MongoDB with C# `__ +Data Formats +------------ - Learn the essentials of C# & ASP.NET application development with MongoDB. +Learn how to work with specialized data formats and custom types in the +:ref:`csharp-data-formats` section. -FAQ ---- +Optimize Queries with Indexes +----------------------------- -For answers to commonly asked questions about the {+driver-long+}, see the :ref:`csharp-faq` +Learn how to work with common types of indexes in the :ref:`csharp-indexes` section. -Connection Troubleshooting --------------------------- +Run a Database Command +---------------------- -For solutions to issues you might encounter when using the driver to connect to -a MongoDB deployment, see the :ref:`csharp-connection-troubleshooting` section. +Learn how to run a database command in the :ref:`csharp-run-command` section. -Issues & Help -------------- +Atlas Search +------------ -Learn how to report bugs, contribute to the driver, and find -additional resources for asking questions in the :ref:`csharp-issues-help` section. +Learn how to use Atlas Search to build full-text search capabilities in the +:ref:`csharp-atlas-search` section. -Compatibility -------------- +Atlas Vector Search +------------------- -For the compatibility charts that show the recommended {+driver-short+} version -for each {+mdb-server+} version, see :ref:`csharp-compatibility-tables`. +Learn how to use Atlas Vector Search to query your Atlas data based on semantic meaning +rather than keyword matches in the +`Atlas Vector Search `__ +documentation. -Upgrade Driver Versions ------------------------ +Logging and Monitoring +---------------------- -Learn what changes you may need to make to your application to upgrade -driver versions in the :ref:`Upgrade Driver Versions ` -section. +Learn how to monitor changes to your application and write them to logs in the +:ref:`csharp-logging-monitoring` section. -Entity Framework Provider -------------------------- +Secure Your Data +---------------- -The MongoDB Entity Framework Provider is an object-relational mapper (ORM) that lets you -use Microsoft's Entity Framework to work with MongoDB data. ORMs provide an -object-oriented interface for data management. +Learn about ways you can authenticate your application and encrypt your data in +the :ref:`csharp-security` section. -The provider includes features such as the following: +Reference +--------- -- Intelligent object tracking -- Entity-based LINQ operations -- Entity Framework modeling and mapping with the fluent API -- Automatic database updates through change tracking +Find more information about {+driver-short+} versions, compatibility, and upgrading driver +versions in the :ref:`csharp-reference` section. -To learn more, see the -`MongoDB Entity Framework Provider documentation `__. +API Documentation +----------------- -{+analyzer+} -------------------- +For detailed information about types and methods in the {+driver-short+}, see +the `{+driver-long+} API documentation +<{+new-api-root+}/index.html>`__. + +Issues & Help +------------- -The {+analyzer-short+} is a tool that helps you understand how your -{+driver-short+} code translates into the {+query-api+} and if your code -includes any unsupported LINQ or builder expressions. To learn more, see the -`{+analyzer-short+} documentation `__. \ No newline at end of file +Learn how to report bugs, contribute to the driver, and find help in the +:ref:`` section. \ No newline at end of file diff --git a/source/fundamentals/indexes.txt b/source/indexes.txt similarity index 86% rename from source/fundamentals/indexes.txt rename to source/indexes.txt index 01643254..62c52fe1 100644 --- a/source/fundamentals/indexes.txt +++ b/source/indexes.txt @@ -432,3 +432,82 @@ all indexes in a collection: :start-after: begin-list-indexes :end-before: end-list-indexes :dedent: + +.. TODO: integrate into existing page + +Sample Class +------------ + +The code examples in this guide demonstrate how you can use builders to +create types to interact with documents in the sample collection ``plants.flowers``. +Documents in this collection are modeled by the following ``Flower`` class: + +.. literalinclude:: /includes/fundamentals/code-examples/builders.cs + :language: csharp + :dedent: + :start-after: start-model + :end-before: end-model + +Each builder class takes a generic type parameter +``TDocument`` which represents the type of document that you are working +with. In this guide, the ``Flower`` class is the document type used in +each builder class example. + +.. _csharp-builders-indexes: + +Define Index Keys +----------------- + +The ``IndexKeysDefinitionBuilder`` class provides a type-safe interface for +defining index keys. Suppose you want to select ``Category`` as an +ascending index key. + +Use builders to select the index key with the typed variant: + +.. code-block:: csharp + :copyable: true + + var builder = Builders.IndexKeys; + var keys = builder.Ascending(f => f.Category); + +Alternatively, you can use string-based field names to select the index key: + +.. code-block:: csharp + :copyable: true + + var builder = Builders.IndexKeys; + var keys = builder.Ascending("Category"); + +The ``IndexKeysDefinitionBuilder`` class also provides methods to build +a wildcard index. You can create a wildcard index using ``All field paths`` or ``A +single field path``, in this case using ``Category``: + +.. tabs:: + + .. tab:: ``All field paths`` + :tabid: all-wildcard-index + + .. code-block:: csharp + :copyable: true + + var builder = Builders.IndexKeys; + var keys = builder.Wildcard(); + + .. tab:: ``A single field path`` + :tabid: single-wildcard-index + + .. code-block:: csharp + :copyable: true + + var builder = Builders.IndexKeys; + + // Using the typed variant + var keys = builder.Wildcard(f => f.Category); + + // Using string-based field names + var keys = builder.Wildcard("Category"); + +For more information about how to use wildcard indexes, see +:manual:`Wildcard Indexes `. + +- `IndexKeysDefinitionBuilder <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IndexKeysDefinitionBuilder-1.html>`__ \ No newline at end of file diff --git a/source/integrations.txt b/source/integrations.txt new file mode 100644 index 00000000..65fe78ad --- /dev/null +++ b/source/integrations.txt @@ -0,0 +1,62 @@ +.. _csharp-integrations: + +====================== +Integrations and Tools +====================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :description: Learn about {+driver-short+} integrations and tools. + :keywords: third-party + +.. toctree:: + :maxdepth: 1 + + OData + Entity Framework Provider + {+analyzer-short+} + +OData +----- + +OData (Open Data Protocol) is a standardized protocol for building and consuming +RESTful APIs that allows for the querying and manipulation of data by using +HTTP requests. It provides a uniform way to expose and interact +with data from multiple sources. + +To learn how to integrate OData with your MongoDB application, see the +:ref:`OData ` tutorial. + +Entity Framework Provider +------------------------- + +The MongoDB Entity Framework Provider is an object-relational mapper (ORM) that lets you +use Microsoft's Entity Framework to work with MongoDB data. ORMs provide an +object-oriented interface for data management. + +The provider includes features such as the following: + +- Intelligent object tracking +- Entity-based LINQ operations +- Entity Framework modeling and mapping with the fluent API +- Automatic database updates through change tracking + +To learn more, see the +`MongoDB Entity Framework Provider documentation `__. + +{+analyzer+} +------------------- + +The {+analyzer-short+} is a tool that helps you understand how your +{+driver-short+} code translates into the {+query-api+} and if your code +includes any unsupported LINQ or builder expressions. To learn more, see the +`{+analyzer-short+} documentation `__. \ No newline at end of file diff --git a/source/fundamentals/odata.txt b/source/integrations/odata.txt similarity index 100% rename from source/fundamentals/odata.txt rename to source/integrations/odata.txt diff --git a/source/logging-and-monitoring.txt b/source/logging-and-monitoring.txt new file mode 100644 index 00000000..f459fe79 --- /dev/null +++ b/source/logging-and-monitoring.txt @@ -0,0 +1,18 @@ +.. _csharp-logging-monitoring: + +====================== +Logging and Monitoring +====================== + +.. facet:: + :name: programming_language + :values: csharp + +.. meta:: + :keywords: dotnet + +.. toctree:: + + Logging + Monitoring + Change Streams \ No newline at end of file diff --git a/source/fundamentals/crud/read-operations/change-streams.txt b/source/logging-and-monitoring/change-streams.txt similarity index 100% rename from source/fundamentals/crud/read-operations/change-streams.txt rename to source/logging-and-monitoring/change-streams.txt diff --git a/source/fundamentals/logging.txt b/source/logging-and-monitoring/logging.txt similarity index 100% rename from source/fundamentals/logging.txt rename to source/logging-and-monitoring/logging.txt diff --git a/source/fundamentals/monitoring.txt b/source/logging-and-monitoring/monitoring.txt similarity index 100% rename from source/fundamentals/monitoring.txt rename to source/logging-and-monitoring/monitoring.txt diff --git a/source/reference.txt b/source/reference.txt new file mode 100644 index 00000000..d1d5e55b --- /dev/null +++ b/source/reference.txt @@ -0,0 +1,25 @@ +.. _csharp-reference: + +========= +Reference +========= + +.. facet:: + :name: programming_language + :values: csharp + +.. meta:: + :keywords: dotnet + +.. toctree:: + + Quick Reference + Release Notes + Compatibility + Upgrade + Versions 2.0 to 2.18 + +Previous Versions +----------------- + +For documentation on versions of the driver v2.18 and earlier, see the :ref:`csharp-previous-versions` section. \ No newline at end of file diff --git a/source/compatibility.txt b/source/reference/compatibility.txt similarity index 100% rename from source/compatibility.txt rename to source/reference/compatibility.txt diff --git a/source/previous-versions.txt b/source/reference/previous-versions.txt similarity index 95% rename from source/previous-versions.txt rename to source/reference/previous-versions.txt index 1fdfc547..a1b74602 100644 --- a/source/previous-versions.txt +++ b/source/reference/previous-versions.txt @@ -1,8 +1,8 @@ .. _csharp-previous-versions: -================= -Previous Versions -================= +==================== +Versions 2.0 to 2.18 +==================== The following links direct you to documentation for previous versions of the driver. diff --git a/source/quick-reference.txt b/source/reference/quick-reference.txt similarity index 95% rename from source/quick-reference.txt rename to source/reference/quick-reference.txt index dc82f454..8b03bd9e 100644 --- a/source/quick-reference.txt +++ b/source/reference/quick-reference.txt @@ -23,7 +23,6 @@ their related reference and API documentation. * - | **Find a Document** | | `API Documentation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollectionExtensions.Find.html>`__ - | :ref:`Usage Example ` | :ref:`Fundamentals ` - .. io-code-block:: @@ -47,7 +46,6 @@ their related reference and API documentation. * - | **Find a Document (Async)** | | `API Documentation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollectionExtensions.FindAsync.html>`__ - | :ref:`Usage Example ` | :ref:`Fundamentals ` - .. io-code-block:: @@ -72,7 +70,6 @@ their related reference and API documentation. * - | **Find Multiple Documents** | | `API Documentation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollectionExtensions.Find.html>`__ - | :ref:`Usage Example ` | :ref:`Fundamentals ` - .. io-code-block:: @@ -100,7 +97,6 @@ their related reference and API documentation. * - | **Find Multiple Documents (Async)** | | `API Documentation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollectionExtensions.Find.html>`__ - | :ref:`Usage Example ` | :ref:`Fundamentals ` - .. io-code-block:: @@ -128,7 +124,6 @@ their related reference and API documentation. * - | **Insert a Document** | | `API Documentation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.InsertOne.html>`__ - | :ref:`Usage Example ` | :ref:`Fundamentals ` - .. code-block:: csharp @@ -139,7 +134,6 @@ their related reference and API documentation. * - | **Insert a Document (Async)** | | `API Documentation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.InsertOneAsync.html>`__ - | :ref:`Usage Example ` | :ref:`Fundamentals ` - .. code-block:: csharp @@ -150,7 +144,6 @@ their related reference and API documentation. * - | **Insert Multiple Documents** | | `API Documentation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.InsertMany.html>`__ - | :ref:`Usage Example ` | :ref:`Fundamentals ` - .. code-block:: csharp @@ -165,7 +158,6 @@ their related reference and API documentation. * - | **Insert Multiple Documents (Async)** | | `API Documentation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.InsertManyAsync.html>`__ - | :ref:`Usage Example ` | :ref:`Fundamentals ` - .. code-block:: csharp @@ -180,7 +172,6 @@ their related reference and API documentation. * - | **Update a Document** | | `API Documentation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.UpdateOne.html>`__ - | :ref:`Usage Example ` | :ref:`Fundamentals ` - .. code-block:: csharp @@ -197,7 +188,6 @@ their related reference and API documentation. * - | **Update a Document (Async)** | | `API Documentation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.UpdateOneAsync.html>`__ - | :ref:`Usage Example ` | :ref:`Fundamentals ` - .. code-block:: csharp @@ -214,7 +204,6 @@ their related reference and API documentation. * - | **Update Multiple Documents** | | `API Documentation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.UpdateMany.html>`__ - | :ref:`Usage Example ` | :ref:`Fundamentals ` - .. code-block:: csharp @@ -231,7 +220,6 @@ their related reference and API documentation. * - | **Update Multiple Documents (Async)** | | `API Documentation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.UpdateManyAsync.html>`__ - | :ref:`Usage Example ` | :ref:`Fundamentals ` - .. code-block:: csharp @@ -270,7 +258,6 @@ their related reference and API documentation. * - | **Replace a Document** | | `API Documentation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.ReplaceOne.html>`__ - | :ref:`Usage Example ` | :ref:`Fundamentals ` - .. code-block:: csharp @@ -303,7 +290,6 @@ their related reference and API documentation. * - | **Replace a Document (Async)** | | `API Documentation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.ReplaceOneAsync.html>`__ - | :ref:`Usage Example ` | :ref:`Fundamentals ` - .. code-block:: csharp @@ -336,7 +322,6 @@ their related reference and API documentation. * - | **Delete a Document** | | `API Documentation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.DeleteOne.html>`__ - | :ref:`Usage Example ` | :ref:`Fundamentals ` - .. code-block:: csharp @@ -350,7 +335,6 @@ their related reference and API documentation. * - | **Delete a Document (Async)** | | `API Documentation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.DeleteOneAsync.html>`__ - | :ref:`Usage Example ` | :ref:`Fundamentals ` - .. code-block:: csharp @@ -364,7 +348,6 @@ their related reference and API documentation. * - | **Delete Multiple Documents** | | `API Documentation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.DeleteMany.html>`__ - | :ref:`Usage Example ` | :ref:`Fundamentals ` - .. code-block:: csharp @@ -378,7 +361,6 @@ their related reference and API documentation. * - | **Delete Multiple Documents (Async)** | | `API Documentation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.DeleteManyAsync.html>`__ - | :ref:`Usage Example ` | :ref:`Fundamentals ` - .. code-block:: csharp diff --git a/source/whats-new.txt b/source/reference/release-notes.txt similarity index 98% rename from source/whats-new.txt rename to source/reference/release-notes.txt index 263e0fc9..28687c76 100644 --- a/source/whats-new.txt +++ b/source/reference/release-notes.txt @@ -1,8 +1,9 @@ .. _csharp-whats-new: +.. _csharp-release-notes: -========== -What's New -========== +============= +Release Notes +============= .. contents:: On this page :local: @@ -61,7 +62,8 @@ The 3.1 driver release includes the following new features: in the Atlas Search documentation. - Adds support for the ``sort`` option to be passed to update commands. To learn more about - using update commands with the {+driver-short+}, see :ref:`csharp-crud-write-operations`. + using update commands with the {+driver-short+}, see the :ref:`csharp-update-one` and + :ref:`csharp-update-many` guides. For more information about this release, see the :github:`v3.1 release notes `. diff --git a/source/upgrade.txt b/source/reference/upgrade.txt similarity index 92% rename from source/upgrade.txt rename to source/reference/upgrade.txt index fd55892c..d4d41064 100644 --- a/source/upgrade.txt +++ b/source/reference/upgrade.txt @@ -21,8 +21,8 @@ Upgrade Driver Versions :titlesonly: :maxdepth: 1 - Version 2.x - Version 3.0 + Version 2.x + Version 3.0 Overview -------- diff --git a/source/upgrade/v2.txt b/source/reference/upgrade/v2.txt similarity index 100% rename from source/upgrade/v2.txt rename to source/reference/upgrade/v2.txt diff --git a/source/upgrade/v3.txt b/source/reference/upgrade/v3.txt similarity index 100% rename from source/upgrade/v3.txt rename to source/reference/upgrade/v3.txt diff --git a/source/fundamentals/databases-collections/run-command.txt b/source/run-command.txt similarity index 100% rename from source/fundamentals/databases-collections/run-command.txt rename to source/run-command.txt diff --git a/source/security.txt b/source/security.txt new file mode 100644 index 00000000..56e5458a --- /dev/null +++ b/source/security.txt @@ -0,0 +1,18 @@ +.. _csharp-security: + +======== +Security +======== + +.. facet:: + :name: programming_language + :values: csharp + +.. meta:: + :keywords: dotnet + +.. toctree:: + + Authentication + In-Use Encryption + TLS/SSL \ No newline at end of file diff --git a/source/fundamentals/authentication.txt b/source/security/authentication.txt similarity index 85% rename from source/fundamentals/authentication.txt rename to source/security/authentication.txt index e6a52726..c7944be5 100644 --- a/source/fundamentals/authentication.txt +++ b/source/security/authentication.txt @@ -20,12 +20,12 @@ Authentication Mechanisms .. toctree:: :caption: Authentication - SCRAM - X.509 - AWS IAM - OIDC - LDAP (PLAIN) - Kerberos (GSSAPI) + SCRAM + X.509 + AWS IAM + OIDC + LDAP (PLAIN) + Kerberos (GSSAPI) Overview -------- diff --git a/source/fundamentals/authentication/aws-iam.txt b/source/security/authentication/aws-iam.txt similarity index 100% rename from source/fundamentals/authentication/aws-iam.txt rename to source/security/authentication/aws-iam.txt diff --git a/source/fundamentals/authentication/kerberos.txt b/source/security/authentication/kerberos.txt similarity index 100% rename from source/fundamentals/authentication/kerberos.txt rename to source/security/authentication/kerberos.txt diff --git a/source/fundamentals/authentication/ldap.txt b/source/security/authentication/ldap.txt similarity index 100% rename from source/fundamentals/authentication/ldap.txt rename to source/security/authentication/ldap.txt diff --git a/source/fundamentals/authentication/oidc.txt b/source/security/authentication/oidc.txt similarity index 100% rename from source/fundamentals/authentication/oidc.txt rename to source/security/authentication/oidc.txt diff --git a/source/fundamentals/authentication/scram.txt b/source/security/authentication/scram.txt similarity index 100% rename from source/fundamentals/authentication/scram.txt rename to source/security/authentication/scram.txt diff --git a/source/fundamentals/authentication/x509.txt b/source/security/authentication/x509.txt similarity index 100% rename from source/fundamentals/authentication/x509.txt rename to source/security/authentication/x509.txt diff --git a/source/fundamentals/encrypt-fields.txt b/source/security/in-use-encryption.txt similarity index 77% rename from source/fundamentals/encrypt-fields.txt rename to source/security/in-use-encryption.txt index f519dca0..1939074c 100644 --- a/source/fundamentals/encrypt-fields.txt +++ b/source/security/in-use-encryption.txt @@ -1,4 +1,5 @@ .. _csharp-fle: +.. _csharp-in-use-encryption: .. sharedinclude:: dbx/encrypt-fields.rst diff --git a/source/fundamentals/connection/tls.txt b/source/security/tls-ssl.txt similarity index 100% rename from source/fundamentals/connection/tls.txt rename to source/security/tls-ssl.txt diff --git a/source/usage-examples.txt b/source/usage-examples.txt deleted file mode 100644 index 1096d1e9..00000000 --- a/source/usage-examples.txt +++ /dev/null @@ -1,105 +0,0 @@ -.. _csharp-usage-examples: - -============== -Usage Examples -============== - -.. facet:: - :name: genre - :values: reference - -.. meta:: - :keywords: code, .NET, operation - -.. contents:: On this page - :local: - :backlinks: none - :depth: 1 - :class: singlecol - -.. toctree:: - - Find a Document - Find Multiple Documents - Insert a Document - Insert Multiple Documents - Update a Document - Update Many Documents - Replace a Document - Delete a Document - Delete Many Documents - -Overview --------- - -Usage examples provide convenient starting points for popular MongoDB -operations. Each example provides the following information: - -- A code snippet that shows how to perform the operation in synchronous and - asynchronous frameworks - -- A link to a fully runnable console application using the operation - -- The expected result after running the example - -.. tip:: - - Whether you use a synchronous or asynchronous framework in your application depends - on your use case. Synchronous calls are more suitable for simple query workflows or - when you must implement sequential logic. Consider using asynchronous calls if - your application relies on multiple concurrent database requests or if your - program doesn't require an immediate response from the database to continue - executing. - - We encourage experimenting with both approaches to determine the most - suitable framework for your purposes. - -How to Use the Usage Examples ------------------------------ - -These examples use the :atlas:`sample datasets ` -provided by Atlas. You can load them into your database on the free tier of -MongoDB Atlas by following the -:atlas:`Get Started with Atlas Guide ` -or you can -:guides:`import the sample dataset into a local MongoDB instance -`. - -Once you have imported the dataset, you can copy and paste a usage -example into your development environment of choice. You can follow the -:ref:`csharp-get-started` to learn more about getting -started with the {+driver-long+}. Once you've copied a usage example, -you'll need to edit the connection URI to get the example connected to -your MongoDB instance: - -.. code-block:: csharp - - // Replace the following with your MongoDB deployment's connection string. - private static string _mongoConnectionString = ""; - -For more information about connecting to your MongoDB instance, see the -:ref:`Connection Guide `. - -Example Classes ---------------- - -The usage examples in this section show how to perform operations on documents -in the ``restaurants`` collection. The examples use the following ``Restaurant``, -``Address``, and ``GradeEntry`` classes to model the data in this collection: - -.. literalinclude:: /includes/code-examples/Restaurant.cs - :language: csharp - :copyable: - :dedent: - -.. literalinclude:: /includes/code-examples/Address.cs - :language: csharp - :copyable: - :dedent: - -.. literalinclude:: /includes/code-examples/GradeEntry.cs - :language: csharp - :copyable: - :dedent: - -.. include:: /includes/convention-pack-note.rst From 3f2c2aece93ea9c921d014bb997b34d38e0eb2e3 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Tue, 8 Apr 2025 11:54:24 -0500 Subject: [PATCH 05/35] DOCSP-48984 - Add redirects for new TOC (#578) --- config/redirects | 73 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/config/redirects b/config/redirects index 5952244a..b593fff5 100644 --- a/config/redirects +++ b/config/redirects @@ -22,4 +22,75 @@ raw: ${prefix}/master -> ${base}/upcoming/ [v3.0-*]: ${prefix}/${version}/fundamentals/enterprise-authentication/ -> ${base}/${version}/fundamentals/authentication/ [*-v2.30]: ${prefix}/${version}/fundamentals/odata/ -> ${base}/${version}/ [*-v2.30]: ${prefix}/${version}/fundamentals/crud/write-operations/bulk-write/ -> ${base}/${version}/fundamentals/crud/write-operations/ -[v2.22-v2.24]: ${prefix}/${version}/fundamentals/authentication/oidc/ -> ${base}/${version}/fundamentals/authentication/ \ No newline at end of file +[v2.22-v2.24]: ${prefix}/${version}/fundamentals/authentication/oidc/ -> ${base}/${version}/fundamentals/authentication/ + +# comprehensive coverage reorg +[*-master]: ${prefix}/${version}/fundamentals/ -> ${base}/${version}/ +[*-master]: ${prefix}/${version}/fundamentals/connection/ -> ${base}/${version}/ +[*-master]: ${prefix}/${version}/fundamentals/crud/ -> ${base}/${version}/ +[*-master]: ${prefix}/${version}/fundamentals/crud/read-operations/ -> ${base}/${version}/ +[*-master]: ${prefix}/${version}/fundamentals/crud/write-operations/ -> ${base}/${version}/ +[*-master]: ${prefix}/${version}/usage-examples/ -> ${base}/${version}/ +[*-master]: ${prefix}/${version}/get-started/create-connection-string/ -> ${base}/${version}/get-started/ +[*-master]: ${prefix}/${version}/get-started/deploy-cluster/ -> ${base}/${version}/get-started/ +[*-master]: ${prefix}/${version}/get-started/download-driver/ -> ${base}/${version}/get-started/ +[*-master]: ${prefix}/${version}/get-started/run-sample-query/ -> ${base}/${version}/get-started/ +[*-master]: ${prefix}/${version}/compatibility/ -> ${base}/${version}/reference/compatibility/ +[*-master]: ${prefix}/${version}/previous-versions/ -> ${base}/${version}/reference/previous-versions/ +[*-master]: ${prefix}/${version}/quick-reference/ -> ${base}/${version}/reference/quick-reference/ +[*-master]: ${prefix}/${version}/whats-new/ -> ${base}/${version}/reference/release-notes/ +[*-master]: ${prefix}/${version}/upgrade/ -> ${base}/${version}/reference/upgrade/ +[*-master]: ${prefix}/${version}/upgrade/v2/ -> ${base}/${version}/reference/upgrade/v2/ +[*-master]: ${prefix}/${version}/upgrade/v3/ -> ${base}/${version}/reference/upgrade/v3/ +[*-master]: ${prefix}/${version}/fundamentals/linq/ -> ${base}/${version}/aggregation/ +[*-master]: ${prefix}/${version}/fundamentals/aggregation/ -> ${base}/${version}/aggregation/ +[*-master]: ${prefix}/${version}/fundamentals/odata/ -> ${base}/${version}/integrations/odata/ +[*-master]: ${prefix}/${version}/fundamentals/indexes/ -> ${base}/${version}/indexes/ +[*-master]: ${prefix}/${version}/fundamentals/atlas-search/ -> ${base}/${version}/atlas-search/ +[*-master]: ${prefix}/${version}/fundamentals/builders/ -> ${base}/${version}/ +[*-master]: ${prefix}/${version}/fundamentals/connection/connection-options/ -> ${base}/${version}/connect/connection-options/ +[*-master]: ${prefix}/${version}/fundamentals/connection/connection-pools/ -> ${base}/${version}/connect/connection-options/connection-pools/ +[*-master]: ${prefix}/${version}/fundamentals/connection/network-compression/ -> ${base}/${version}/connect/connection-options/network-compression/ +[*-master]: ${prefix}/${version}/fundamentals/connection/server-selection/ -> ${base}/${version}/connect/connection-options/server-selection/ +[*-master]: ${prefix}/${version}/fundamentals/connection/connect/ -> ${base}/${version}/connect/mongoclient/ +[*-master]: ${prefix}/${version}/fundamentals/connection/tls/ -> ${base}/${version}/security/tls-ssl/ +[*-master]: ${prefix}/${version}/fundamentals/read-write-configuration/ -> ${base}/${version}/crud/configure/ +[*-master]: ${prefix}/${version}/connection-troubleshooting/ -> ${base}/${version}/connect/connection-troubleshooting/ +[*-master]: ${prefix}/${version}/fundamentals/geo/ -> ${base}/${version}/crud/geo/ +[*-master]: ${prefix}/${version}/fundamentals/stable-api/ -> ${base}/${version}/connect/connection-options/stable-api/ +[*-master]: ${prefix}/${version}/fundamentals/gridfs/ -> ${base}/${version}/crud/gridfs/ +[*-master]: ${prefix}/${version}/fundamentals/specify-query/ -> ${base}/${version}/crud/query/specify-query/ +[*-master]: ${prefix}/${version}/fundamentals/transactions/ -> ${base}/${version}/crud/transactions/ +[*-master]: ${prefix}/${version}/fundamentals/bson/ -> ${base}/${version}/data-formats/bson/ +[*-master]: ${prefix}/${version}/fundamentals/time-series/ -> ${base}/${version}/data-formats/time-series/ +[*-master]: ${prefix}/${version}/fundamentals/logging/ -> ${base}/${version}/logging-and-monitoring/logging/ +[*-master]: ${prefix}/${version}/fundamentals/monitoring/ -> ${base}/${version}/logging-and-monitoring/monitoring/ +[*-master]: ${prefix}/${version}/fundamentals/database-collection/ -> ${base}/${version}/databases-collections/ +[*-master]: ${prefix}/${version}/fundamentals/encrypt-fields/ -> ${base}/${version}/security/in-use-encryption/ +[*-master]: ${prefix}/${version}/fundamentals/crud/read-operations/distinct/ -> ${base}/${version}/crud/query/distinct/ +[*-master]: ${prefix}/${version}/fundamentals/crud/read-operations/retrieve/ -> ${base}/${version}/crud/query/find/ +[*-master]: ${prefix}/${version}/fundamentals/crud/read-operations/project/ -> ${base}/${version}/crud/query/project/ +[*-master]: ${prefix}/${version}/fundamentals/crud/read-operations/specify-documents-to-return/ -> ${base}/${version}/crud/query/specify-documents-to-return/ +[*-master]: ${prefix}/${version}/fundamentals/crud/read-operations/change-streams/ -> ${base}/${version}/logging-and-monitoring/change-streams/ +[*-master]: ${prefix}/${version}/fundamentals/crud/write-operations/insert/ -> ${base}/${version}/crud/insert/ +[*-master]: ${prefix}/${version}/fundamentals/crud/write-operations/delete/ -> ${base}/${version}/crud/delete/ +[*-master]: ${prefix}/${version}/fundamentals/crud/write-operations/bulk-write/ -> ${base}/${version}/bulk-write/ +[*-master]: ${prefix}/${version}/fundamentals/crud/write-operations/replace/ -> ${base}/${version}/crud/replace/ +[*-master]: ${prefix}/${version}/fundamentals/crud/write-operations/update-many/ -> ${base}/${version}/crud/update-many/ +[*-master]: ${prefix}/${version}/fundamentals/crud/write-operations/update-many/arrays/ -> ${base}/${version}/crud/update-many/arrays/ +[*-master]: ${prefix}/${version}/fundamentals/crud/write-operations/update-many/fields/ -> ${base}/${version}/crud/update-many/fields/ +[*-master]: ${prefix}/${version}/fundamentals/crud/write-operations/update-one/ -> ${base}/${version}/crud/update-one/ +[*-master]: ${prefix}/${version}/fundamentals/crud/write-operations/update-one/arrays/ -> ${base}/${version}/crud/update-one/arrays/ +[*-master]: ${prefix}/${version}/fundamentals/crud/write-operations/update-one/fields/ -> ${base}/${version}/crud/update-one/fields/ +[*-master]: ${prefix}/${version}/fundamentals/serialization/class-mapping/ -> ${base}/${version}/data-formats/custom-types/class-mapping/ +[*-master]: ${prefix}/${version}/fundamentals/serialization/poco/ -> ${base}/${version}/data-formats/custom-types/poco/ +[*-master]: ${prefix}/${version}/fundamentals/serialization/polymorphic-objects/ -> ${base}/${version}/data-formats/custom-types/polymorphic-objects/ +[*-master]: ${prefix}/${version}/fundamentals/serialization/ -> ${base}/${version}/data-formats/custom-types/serialization/ +[*-master]: ${prefix}/${version}/fundamentals/databases-collections/run-command/ -> ${base}/${version}/run-command/ +[*-master]: ${prefix}/${version}/fundamentals/authentication/ -> ${base}/${version}/security/authentication/ +[*-master]: ${prefix}/${version}/fundamentals/authentication/aws-iam/ -> ${base}/${version}/security/authentication/aws-iam/ +[*-master]: ${prefix}/${version}/fundamentals/authentication/kerberos/ -> ${base}/${version}/security/authentication/kerberos/ +[*-master]: ${prefix}/${version}/fundamentals/authentication/ldap/ -> ${base}/${version}/security/authentication/ldap/ +[*-master]: ${prefix}/${version}/fundamentals/authentication/oidc/ -> ${base}/${version}/security/authentication/oidc/ +[*-master]: ${prefix}/${version}/fundamentals/authentication/scram/ -> ${base}/${version}/security/authentication/scram/ +[*-master]: ${prefix}/${version}/fundamentals/authentication/x509/ -> ${base}/${version}/security/authentication/x509/ \ No newline at end of file From dae52bf6e372c1c8a4061c7cb2b253ca58d21e61 Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Wed, 16 Apr 2025 09:04:30 -0400 Subject: [PATCH 06/35] DOCSP-49067: Cursors (#584) --- source/crud/query/cursors.txt | 179 ++++++++++++++++++ .../fundamentals/code-examples/Cursor.cs | 155 +++++++++++++++ 2 files changed, 334 insertions(+) create mode 100644 source/includes/fundamentals/code-examples/Cursor.cs diff --git a/source/crud/query/cursors.txt b/source/crud/query/cursors.txt index e69de29b..a3307199 100644 --- a/source/crud/query/cursors.txt +++ b/source/crud/query/cursors.txt @@ -0,0 +1,179 @@ +.. _csharp-cursors: + +========================= +Access Data From a Cursor +========================= + +.. contents:: On this page + :local: + :backlinks: none + :depth: 1 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: read, results, oplog + +Overview +-------- + +In this guide, you can learn how to access data from a **cursor** by using the +{+driver-short+}. + +A cursor is a tool that returns the results of a read operation in iterable +batches. Because a cursor holds only a subset of documents at any given time, +cursors reduce both memory consumption and network bandwidth usage. + +You can retrieve a cursor by using the ``FindSync()`` or ``FindAsync()`` method. You can +also convert the results of the ``Find()`` method to a cursor by chaining the ``ToCursor()`` +or ``ToCursorAsync()`` method. + +Sample Data +~~~~~~~~~~~ + +The examples in this guide use the ``restaurants`` collection +in the ``sample_restaurants`` database provided in the :atlas:`Atlas sample datasets `. +To learn how to create a free MongoDB Atlas cluster and load the sample datasets, +see the :ref:`` tutorial. + +The examples on this page use the following ``Restaurant`` object to model the documents +in the ``restaurants`` collection: + +.. literalinclude:: /includes/fundamentals/code-examples/Cursor.cs + :start-after: start-restaurant-class + :end-before: end-restaurant-class + :language: csharp + +.. _csharp-cursors-iterate: + +Access Cursor Contents Iteratively +---------------------------------- + +To iterate over the contents of a cursor, use a ``foreach`` loop inside a ``using`` block. +The following example retrieves documents from the ``restaurants`` collection in which the +value of the ``name`` field is ``"Starbucks"``, then iterates over the results. +Select the :guilabel:`Synchronous` or :guilabel:`Asynchronous` tab to see the corresponding +code: + +.. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. literalinclude:: /includes/fundamentals/code-examples/Cursor.cs + :start-after: start-cursor-iterate + :end-before: end-cursor-iterate + :language: csharp + :dedent: + + .. tab:: Asynchronous + :tabid: async + + .. literalinclude:: /includes/fundamentals/code-examples/Cursor.cs + :start-after: start-cursor-iterate-async + :end-before: end-cursor-iterate-async + :language: csharp + :dedent: + +The following example performs the same operation but uses the ``ToCursor()`` method. +Select the :guilabel:`Synchronous` or :guilabel:`Asynchronous` +tab to see the corresponding code: + +.. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. literalinclude:: /includes/fundamentals/code-examples/Cursor.cs + :start-after: start-cursor-iterate-to-cursor + :end-before: end-cursor-iterate-to-cursor + :language: csharp + :dedent: + + .. tab:: Asynchronous + :tabid: async + + .. literalinclude:: /includes/fundamentals/code-examples/Cursor.cs + :start-after: start-cursor-iterate-to-cursor-async + :end-before: end-cursor-iterate-to-cursor-async + :language: csharp + :dedent: + +Retrieve All Documents +---------------------- + +.. warning:: + + If the number and size of documents returned by your query exceeds available + application memory, your program might crash. If you expect a large result + set, :ref:`access your cursor iteratively `. + +To retrieve all documents from a cursor, use the ``ToList()`` method, as shown in the +following example. Select the :guilabel:`Synchronous` or :guilabel:`Asynchronous` +tab to see the corresponding code: + +.. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. literalinclude:: /includes/fundamentals/code-examples/Cursor.cs + :start-after: start-cursor-to-list + :end-before: end-cursor-to-list + :language: csharp + :dedent: + + .. tab:: Asynchronous + :tabid: async + + .. literalinclude:: /includes/fundamentals/code-examples/Cursor.cs + :start-after: start-cursor-to-list-async + :end-before: end-cursor-to-list-async + :language: csharp + :dedent: + +Tailable Cursors +---------------- + +When querying on a :manual:`capped collection `, you +can use a **tailable cursor** that remains open after the client exhausts the +results in a cursor. To create a tailable cursor, create a ``FindOptions`` object and set the +``CursorType`` property to ``CursorType.TailableAwait``. Then, pass the ``FindOptions`` object +to one of the find operation methods. The following example shows how to create a tailable +cursor on a capped collection. Select the :guilabel:`Synchronous` or +:guilabel:`Asynchronous` tab to see the corresponding code: + +.. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. literalinclude:: /includes/fundamentals/code-examples/Cursor.cs + :start-after: start-tailable-cursor + :end-before: end-tailable-cursor + :language: csharp + :dedent: + + .. tab:: Asynchronous + :tabid: async + + .. literalinclude:: /includes/fundamentals/code-examples/Cursor.cs + :start-after: start-tailable-cursor-async + :end-before: end-tailable-cursor-async + :language: csharp + :dedent: + +API Documentation +----------------- + +To learn more about the methods and classes used in this guide, see the +following API documentation: + +- `FindSync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.FindSync.html>`__ +- `FindAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.FindAsync.html>`__ +- `Find() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollectionExtensions.Find.html>`__ +- `IAsyncCursor <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IAsyncCursor-1.html>`__ +- `FindOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.FindOptions.html>`__ diff --git a/source/includes/fundamentals/code-examples/Cursor.cs b/source/includes/fundamentals/code-examples/Cursor.cs new file mode 100644 index 00000000..c8de98a2 --- /dev/null +++ b/source/includes/fundamentals/code-examples/Cursor.cs @@ -0,0 +1,155 @@ +using System.Threading.Tasks; +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; +using MongoDB.Driver; + +public class Cursor +{ + // Replace with your connection string + private const string MongoConnectionString = ""; + + public static async Task Main(string[] args) + { + var mongoClient = new MongoClient(MongoConnectionString); + var database = mongoClient.GetDatabase("sample_restaurants"); + var collection = database.GetCollection("restaurants"); + + { + // start-cursor-iterate + var filter = Builders.Filter.Eq(r => r.Name, "Starbucks"); + + using (var cursor = collection.FindSync(filter)) + { + while (cursor.MoveNext()) + { + foreach (var restaurant in cursor.Current) + { + Console.WriteLine(restaurant.Name); + } + } + } + // end-cursor-iterate + } + + { + // start-cursor-iterate-async + var filter = Builders.Filter.Eq(r => r.Name, "Starbucks"); + + using (var cursor = await collection.FindAsync(filter)) + { + while (await cursor.MoveNextAsync()) + { + foreach (var restaurant in cursor.Current) + { + Console.WriteLine(restaurant.Name); + } + } + } + // end-cursor-iterate-async + } + + { + // start-cursor-iterate-to-cursor + var filter = Builders.Filter.Eq(r => r.Name, "Starbucks"); + + using (var cursor = collection.Find(filter).ToCursor()) + { + while (cursor.MoveNext()) + { + foreach (var restaurant in cursor.Current) + { + Console.WriteLine(restaurant.Name); + } + } + } + // end-cursor-iterate-to-cursor + } + + { + // start-cursor-iterate-to-cursor-async + var filter = Builders.Filter.Eq(r => r.Name, "Starbucks"); + + using (var cursor = await collection.Find(filter).ToCursorAsync()) + { + while (await cursor.MoveNextAsync()) + { + foreach (var restaurant in cursor.Current) + { + Console.WriteLine(restaurant.Name); + } + } + } + // end-cursor-iterate-to-cursor-async + } + + { + // start-cursor-to-list + var filter = Builders.Filter.Eq(r => r.Name, "Dunkin' Donuts"); + var results = collection.FindSync(filter).ToList(); + // end-cursor-to-list + } + + { + // start-cursor-to-list-async + var filter = Builders.Filter.Eq(r => r.Name, "Dunkin' Donuts"); + var results = (await collection.FindAsync(filter)).ToList(); + // end-cursor-to-list-async + } + + { + // start-tailable-cursor + var filter = Builders.Filter.Eq(r => r.Name, "Dunkin' Donuts"); + var options = new FindOptions + { + CursorType = CursorType.TailableAwait + }; + + using (var cursor = collection.FindSync(filter, options)) + { + while (cursor.MoveNext()) + { + foreach (var restaurant in cursor.Current) + { + Console.WriteLine(restaurant.Name); + } + } + } + // end-tailable-cursor + } + + { + { + // start-tailable-cursor-async + var filter = Builders.Filter.Eq(r => r.Name, "Dunkin' Donuts"); + var options = new FindOptions + { + CursorType = CursorType.TailableAwait + }; + + using (var cursor = await collection.FindAsync(filter, options)) + { + while (await cursor.MoveNext()) + { + foreach (var restaurant in cursor.Current) + { + Console.WriteLine(restaurant.Name); + } + } + } + // end-tailable-cursor-async + } + } + + } +} + +// start-restaurant-class +[BsonIgnoreExtraElements] +public class Restaurant +{ + public ObjectId Id { get; set; } + + [BsonElement("name")] + public string Name { get; set; } +} +// end-restaurant-class \ No newline at end of file From c0ae6983b0aff8fb5df5b4cdc221c762d97ba927 Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Wed, 16 Apr 2025 10:03:26 -0400 Subject: [PATCH 07/35] DOCSP-49095: Retryable Reads and Writes (#585) --- source/crud/configure.txt | 41 +++++++++++++++++++ .../code-examples/ReplicaSetConfigs.cs | 23 +++++++++-- 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/source/crud/configure.txt b/source/crud/configure.txt index 01ea55ed..bcaa7ddc 100644 --- a/source/crud/configure.txt +++ b/source/crud/configure.txt @@ -191,6 +191,47 @@ The following example sets the read preference to ``ReadPreference.Secondary`` f For more information about read preference, see :manual:`Read Preference ` in the {+mdb-server+} manual. +Retryable Reads and Writes +-------------------------- + +The {+driver-short+} automatically retries certain read and write operations a single time +if they fail due to a network or server error. + +You can explicitly disable retryable reads or retryable writes by setting the ``RetryReads`` +or ``RetryWrites`` options on a ``MongoClientSettings`` object and passing this object to the +``MongoClient`` constructor. You can also set the ``retryReads`` or ``retryWrites`` options +in a connection string. + +The following example disables retryable reads and writes for +a client. Select the :guilabel:`MongoClientSettings` or :guilabel:`Connection String` +tab to see the corresponding code. + +.. tabs:: + + .. tab:: MongoClientSettings + :tabid: mongoclientsettings + + .. literalinclude:: /includes/fundamentals/code-examples/ReplicaSetConfigs.cs + :start-after: start-retry-reads-writes + :end-before: end-retry-reads-writes + :emphasize-lines: 2-3 + :language: csharp + :dedent: + + .. tab:: Connection String + :tabid: connectionstring + + .. literalinclude:: /includes/fundamentals/code-examples/ReplicaSetConfigs.cs + :start-after: start-retry-reads-writes-connection-string + :end-before: end-retry-reads-writes-connection-string + :emphasize-lines: 1 + :language: csharp + :dedent: + +To learn more about supported retryable read and retryable write operations, see +:manual:`Retryable Reads ` +and :manual:`Retryable Writes ` in the {+mdb-server+} manual. + API Documentation ----------------- diff --git a/source/includes/fundamentals/code-examples/ReplicaSetConfigs.cs b/source/includes/fundamentals/code-examples/ReplicaSetConfigs.cs index fcb35edd..cf7c2163 100644 --- a/source/includes/fundamentals/code-examples/ReplicaSetConfigs.cs +++ b/source/includes/fundamentals/code-examples/ReplicaSetConfigs.cs @@ -8,7 +8,7 @@ public static void Main(string[] args) var client = new MongoClient("mongodb://localhost:27017"); { // start-write-concern-client - var mongoClientSettings = MongoClientSettings.FromConnectionString(""); + var mongoClientSettings = MongoClientSettings.FromConnectionString(""); mongoClientSettings.WriteConcern = WriteConcern.WMajority; var mongoClient = new MongoClient(mongoClientSettings); // end-write-concern-client @@ -24,7 +24,7 @@ public static void Main(string[] args) { // start-read-concern-client - var mongoClientSettings = MongoClientSettings.FromConnectionString(""); + var mongoClientSettings = MongoClientSettings.FromConnectionString(""); mongoClientSettings.ReadConcern = ReadConcern.Majority; var mongoClient = new MongoClient(mongoClientSettings); // end-read-concern-client @@ -40,7 +40,7 @@ public static void Main(string[] args) { // start-read-preference-client - var mongoClientSettings = MongoClientSettings.FromConnectionString(""); + var mongoClientSettings = MongoClientSettings.FromConnectionString(""); mongoClientSettings.ReadPreference = ReadPreference.Secondary; var mongoClient = new MongoClient(mongoClientSettings); // end-read-preference-client @@ -53,5 +53,22 @@ public static void Main(string[] args) .WithReadPreference(ReadPreference.Secondary); // end-read-preference-collection } + + { + // start-retry-reads-writes + var mongoClientSettings = MongoClientSettings.FromConnectionString(""); + mongoClientSettings.RetryReads = false; + mongoClientSettings.RetryWrites = false; + var mongoClient = new MongoClient(mongoClientSettings); + // end-retry-reads-writes + } + + { + // start-retry-reads-writes-connection-string + var connectionString = "mongodb://localhost:27017/?retryReads=false&retryWrites=false"; + var mongoClientSettings = MongoClientSettings.FromConnectionString(connectionString); + var mongoClient = new MongoClient(mongoClientSettings); + // end-retry-reads-writes-connection-string + } } } \ No newline at end of file From 012b476ada7c5b166ed92b29523b283903929731 Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Tue, 22 Apr 2025 15:20:03 -0400 Subject: [PATCH 08/35] DOCSP-49056: Server Selection (#618) --- .../connection-options/server-selection.txt | 263 +++++++++++++----- .../connection/ServerSelection.cs | 38 +++ .../server-selection-timeout.rst | 66 +++++ 3 files changed, 299 insertions(+), 68 deletions(-) create mode 100644 source/includes/fundamentals/code-examples/connection/ServerSelection.cs create mode 100644 source/includes/troubleshooting/server-selection-timeout.rst diff --git a/source/connect/connection-options/server-selection.txt b/source/connect/connection-options/server-selection.txt index 57772394..2e32a90e 100644 --- a/source/connect/connection-options/server-selection.txt +++ b/source/connect/connection-options/server-selection.txt @@ -1,68 +1,195 @@ -.. TODO: Server Selection page - -Why Does the Driver Throw a Timeout During Server Selection? ------------------------------------------------------------- - -Each driver operation requires that you choose a healthy server -satisfying the :manual:`server selection criteria -`. If you do not select an appropriate -server within the `server selection timeout <{+new-api-root+}/MongoDB.Driver.Legacy/MongoDB.Driver.MongoServerSettings.ServerSelectionTimeout.html>`__, the driver throws a -server selection timeout exception. The exception looks similar to the -following: - -.. code-block:: none - - A timeout occurred after 30000ms selecting a server using CompositeServerSelector{ Selectors = MongoDB.Driver.MongoClient+AreSessionsSupportedServerSelector, LatencyLimitingServerSelector{ AllowedLatencyRange = 00:00:00.0150000 }, OperationsCountServerSelector }. - Client view of cluster state is - { - ClusterId : "1", - Type : "Unknown", - State : "Disconnected", - Servers : - [{ - ServerId: "{ ClusterId : 1, EndPoint : "Unspecified/localhost:27017" }", - EndPoint: "Unspecified/localhost:27017", - ReasonChanged: "Heartbeat", - State: "Disconnected", - ServerVersion: , - TopologyVersion: , - Type: "Unknown", - HeartbeatException: "" - }] - }. - -The error message consists of multiple parts: - -1. The server selection timeout (30000 ms). -#. The server selectors considered (``CompositeServerSelector`` - containing ``AreSessionsSupportedServerSelector``, - ``LatencyLimitingServerSelector``, and - ``OperationsCountServerSelector``). -#. The driver’s current view of the cluster topology. The list of - servers that the driver is aware of is a key part of this view. Each - server description contains an exhaustive description of its current - state including information about an endpoint, a server version, a - server type, and its current health state. If the server encounters issues in - reporting its health, ``HeartbeatException`` contains the exception from the - last failed heartbeat. Analyzing the ``HeartbeatException`` on each - cluster node can assist in diagnosing most server selection issues. - The following heartbeat exceptions are common: - - * ``No connection could be made because the target machine actively - refused it``: The driver cannot see this cluster node. This can be - because the cluster node has crashed, a firewall is preventing - network traffic from reaching the cluster node or port, or some other - network error is preventing traffic from being successfully routed to - the cluster node. - * ``Attempted to read past the end of the stream``: This error - happens when the driver cannot connect to the cluster nodes due to a - network error, misconfigured firewall, or other network issue. To - address this exception, ensure that all cluster nodes are reachable. - This error commonly occurs when the client machine’s IP address is - not configured in the Atlas IPs Access List, which can be found under - the :guilabel:`Network Access` tab for your Atlas Project. - * ``The remote certificate is invalid according to the validation - procedure``: This error typically indicates a TLS/SSL-related problem - such as an expired/invalid certificate or an untrusted root CA. You - can use tools like ``openssl s_client`` to debug TLS/SSL-related - certificate problems. \ No newline at end of file +.. _csharp-server-selection: + +========================== +Customize Server Selection +========================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 1 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: code example, read preference, write + +Overview +-------- + +All MongoDB drivers follow a defined algorithm when selecting a server to read or write +from. By using the ``ClusterConfigurator`` property of a ``MongoClient`` object, you can +customize this algorithm to choose the server that works best for your application. + +.. important:: + + Customizing the server selection algorithm might have unintended consequences, + such as degraded read or write performance. + +Default Algorithm +----------------- + +When the {+driver-short+} executes a read operation, it performs the following steps, +in order, to select a MongoDB deployment: + +1. Selects all servers that match the active read preference from the list of known servers. + +#. If at least one readable server exists, the driver calls the user-defined + server-selector function and passes in the list from the previous step. + +#. Applies the ``LocalThreshold`` connection setting to the list of + servers returned from the function. + +#. Selects a server at random from the servers still on the list and + executes the operation against this server. + +When the {+driver-short+} executes a write operation, it begins by selecting all writeable +servers, not just those that match the active read preference. The remaining steps are +identical. + +To learn more about the default server selection algorithm, which the driver follows +when you don't specify any custom server selection logic, see +:manual:`Server Selection Algorithm ` in the +{+mdb-server+} manual. + +.. _csharp-server-selection-algorithm: + +Specifying Other Server Selection Algorithms +-------------------------------------------- + +You can specify different server selection logic by passing an instance of a server selector +class to the ``PreServerSelector`` or ``PostServerSelector`` property of the ``ClusterConfigurator``. The +``PreServerSelector`` property specifies a server selector that runs before the +standard server selection logic runs, while the ``PostServerSelector`` property +specifies a server selector that runs after standard server selection logic runs. You can +then pass your ``ClusterConfigurator`` instance to the ``MongoClientSettings`` object when you create a +``MongoClient`` instance to apply your custom server selection logic. + +The following table lists the different types of server selectors you can pass to the +``ClusterConfigurator`` property: + +.. list-table:: + :header-rows: 1 + :widths: 40 60 + + * - Server Selector + - Description + + * - ``CompositeServerSelector`` + - Selects servers based on multiple partial selectors + + * - ``DelegateServerSelector`` + - Wraps a delegate server selector + + * - ``EndPointServerSelector`` + - Selects servers based on their endpoint + + * - ``LatencyLimitingServerSelector`` + - Selects servers within an acceptable latency range + + * - ``PriorityServerSelector`` + - Selects a server based on a collection of servers to deprioritize + + * - ``RandomServerSelector`` + - Selects a random server + + * - ``ReadPreferenceServerSelector`` + - Selects servers based on a specified read preference + +The following example instructs a ``MongoClient`` to use the ``RandomServerSelector`` +class to select a server at random before the standard server selection logic runs: + +.. literalinclude:: /includes/fundamentals/code-examples/connection/ServerSelection.cs + :start-after: start-server-selector + :end-before: end-server-selector + :language: csharp + :dedent: + +To learn more about the different server selector classes, see the +`ServerSelectors API documentation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Core.Clusters.ServerSelectors.html>`__. + +Implementing Custom Server Selection Logic +------------------------------------------ + +You can implement your own custom server selection logic by creating a class that +inherits from the ``IServerSelector`` interface and overrides the +``SelectServers()`` method. The following example shows a simple custom server +selection class that selects servers with a ``ServerType`` of +``ServerType.ReplicaSetSecondary``: + +.. literalinclude:: /includes/fundamentals/code-examples/connection/ServerSelection.cs + :start-after: start-custom-class + :end-before: end-custom-class + :language: csharp + :dedent: + +You can then pass an instance of this class to the ``PreServerSelector`` or +``PostServerSelector`` property of a ``ClusterConfigurator`` instance, as shown in the +:ref:`csharp-server-selection-algorithm` section. + +Using Settings to Configure Server Selection +-------------------------------------------- + +You can specify the following server selection settings in your ``MongoClient`` object or +in your connection URI: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Setting + - Description + + * - ``LocalThreshold`` + - | The latency window for server eligibility. If a server's round trip takes longer + | than the fastest server's round-trip time plus this value, the server isn't + | eligible for selection. + | + | **Data Type**: ``TimeSpan`` + | **Default**: 15 milliseconds + | **Connection URI Example**: ``localThresholdMS=0`` + + * - ``ReadPreference`` + - | The client's default read-preference settings. ``MaxStaleness`` represents the + | longest replication lag (in real time) that a secondary can experience and + | still be eligible for server selection. Specifying ``-1`` means no maximum. + | See :ref:`read preference ` for more information. + | + | **Data Type**: `ReadPreference <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ReadPreference.html>`__ + | **Default**: ``ReadPreference.Primary`` + | **Connection URI Example**: + + .. code-block:: none + :copyable: false + + readPreference=primaryPreferred + &maxStalenessSeconds=90 + &readPreferenceTags=dc:ny,rack:1 + + * - ``ServerSelectionTimeout`` + - | The length of time the driver tries to select a server before timing out. + | + | **Data Type**: ``TimeSpan`` + | **Default**: 30 seconds + | **Connection URI Example**: ``serverSelectionTimeoutMS=15000`` + +Troubleshooting +--------------- + +.. include:: /includes/troubleshooting/server-selection-timeout.rst + +API Documentation +----------------- + +To learn more about the classes and methods used in this guide, see the following API +documentation: + +- `MongoClient <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.MongoClient.html>`__ +- `MongoClientSettings <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.MongoClientSettings.html>`__ +- `ClusterConfigurator <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.MongoClientSettings.ClusterConfigurator.html>`__ +- `ServerSelectors <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Core.Clusters.ServerSelectors.html>`__ +- `IServerSelector <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Core.Clusters.ServerSelectors.IServerSelector.html>`__ +- `SelectServer() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Core.Clusters.ServerSelectors.IServerSelector.SelectServers.html>`__ \ No newline at end of file diff --git a/source/includes/fundamentals/code-examples/connection/ServerSelection.cs b/source/includes/fundamentals/code-examples/connection/ServerSelection.cs new file mode 100644 index 00000000..eaaabe17 --- /dev/null +++ b/source/includes/fundamentals/code-examples/connection/ServerSelection.cs @@ -0,0 +1,38 @@ +using MongoDB.Driver; +using MongoDB.Driver.Core.Clusters; +using MongoDB.Driver.Core.Clusters.ServerSelectors; +using MongoDB.Driver.Core.Servers; + +public class ServerSelection +{ + // Replace with your connection string + private const string MongoConnectionString = ""; + + public static void Main(string[] args) + { + { + // start-server-selector + var settings = MongoClientSettings.FromConnectionString(""); + var clusterConfigurator = builder => + { + builder.ConfigureCluster(c => + c.With(PreServerSelector: new RandomServerSelector())); + }; + + settings.ClusterConfigurator = clusterConfigurator; + var client = new MongoClient(settings); + // end-server-selector + } + } +} + +// start-custom-class +public class CustomServerSelector : IServerSelector +{ + public IEnumerable SelectServers(ClusterDescription cluster, + IEnumerable servers) + { + return servers.Where(server => server.Type == ServerType.ReplicaSetSecondary); + } +} +// end-custom-class diff --git a/source/includes/troubleshooting/server-selection-timeout.rst b/source/includes/troubleshooting/server-selection-timeout.rst new file mode 100644 index 00000000..1f1b67f9 --- /dev/null +++ b/source/includes/troubleshooting/server-selection-timeout.rst @@ -0,0 +1,66 @@ +Driver Throws a Timeout During Server Selection +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Each driver operation requires that you choose a server that +satisfies the :manual:`server selection criteria +`. If you do not select an appropriate +server within the `server selection timeout <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.MongoClientSettings.ServerSelectionTimeout.html>`__, the driver throws a +server selection timeout exception. The exception looks similar to the +following: + +.. code-block:: none + + A timeout occurred after 30000ms selecting a server using CompositeServerSelector{ Selectors = MongoDB.Driver.MongoClient+AreSessionsSupportedServerSelector, LatencyLimitingServerSelector{ AllowedLatencyRange = 00:00:00.0150000 }, OperationsCountServerSelector }. + Client view of cluster state is + { + ClusterId : "1", + Type : "Unknown", + State : "Disconnected", + Servers : + [{ + ServerId: "{ ClusterId : 1, EndPoint : "Unspecified/localhost:27017" }", + EndPoint: "Unspecified/localhost:27017", + ReasonChanged: "Heartbeat", + State: "Disconnected", + ServerVersion: , + TopologyVersion: , + Type: "Unknown", + HeartbeatException: "" + }] + }. + +The error message consists of multiple parts: + +1. The server selection timeout (30000 ms). +#. The server selectors considered (``CompositeServerSelector`` + containing ``AreSessionsSupportedServerSelector``, + ``LatencyLimitingServerSelector``, and + ``OperationsCountServerSelector``). +#. The driver’s current view of the cluster topology. The list of + servers that the driver is aware of is a key part of this view. Each + server description contains an exhaustive description of its current + state including information about an endpoint, a server version, a + server type, and its current health state. If the server encounters issues in + reporting its health, ``HeartbeatException`` contains the exception from the + last failed heartbeat. Analyzing the ``HeartbeatException`` on each + cluster node can assist in diagnosing most server selection issues. + The following heartbeat exceptions are common: + + * ``No connection could be made because the target machine actively + refused it``: The driver cannot see this cluster node. This might be + because the cluster node has crashed, a firewall is preventing + network traffic from reaching the cluster node or port, or some other + network error is preventing traffic from being successfully routed to + the cluster node. + * ``Attempted to read past the end of the stream``: This error + happens when the driver cannot connect to the cluster nodes due to a + network error, misconfigured firewall, or other network issue. To + address this exception, ensure that all cluster nodes are reachable. + This error commonly occurs when the client machine’s IP address is + not configured in the Atlas IPs Access List, which you can find under + the :guilabel:`Network Access` tab for your Atlas Project. + * ``The remote certificate is invalid according to the validation + procedure``: This error typically indicates a TLS/SSL-related problem + such as an expired/invalid certificate or an untrusted root CA. You + can use tools like ``openssl s_client`` to debug TLS/SSL-related + certificate problems. From 0d3188796364b46f5053e55911efec5290220136 Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Thu, 24 Apr 2025 11:24:10 -0400 Subject: [PATCH 09/35] DOCSP-49058: Connection Pools (#616) --- .../connection-options/connection-pools.txt | 207 ++++++++++++------ 1 file changed, 136 insertions(+), 71 deletions(-) diff --git a/source/connect/connection-options/connection-pools.txt b/source/connect/connection-options/connection-pools.txt index db9a3a7e..e2d7d3d0 100644 --- a/source/connect/connection-options/connection-pools.txt +++ b/source/connect/connection-options/connection-pools.txt @@ -1,86 +1,151 @@ -.. TODO: Connection Pools page - .. _csharp-faq-connection-pool: .. _csharp-connection-pools: -How Does Connection Pooling Work in the {+driver-short+}? ---------------------------------------------------------- +================ +Connection Pools +================ + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: connection, client, latency + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol -Every ``MongoClient`` instance has a built-in connection pool for each server -in your MongoDB topology. Connection pools open sockets on demand to -support concurrent MongoDB operations in your multi-threaded application. +Overview +-------- -The maximum size of each connection pool is set by the ``MaxConnectionPoolSize`` option, which -defaults to ``100``. If the number of in-use connections to a server reaches -the value of ``MaxConnectionPoolSize``, the next request to that server will wait -until a connection becomes available. The following diagram illustrates a high-level view +In this guide, you can learn about how the {+driver-short+} uses connection pools to manage +connections to a MongoDB deployment and how you can configure connection pool settings +in your application. + +A connection pool is a cache of open database connections maintained by the {+driver-short+}. +When your application requests a connection to MongoDB, the {+driver-short+} seamlessly +gets a connection from the pool, performs operations, and returns the connection +to the pool for reuse. + +Connection pools help reduce application latency and the number of times new connections +are created by the {+driver-short+}. The following diagram illustrates a high-level view of how the ``MongoClient`` manages a connection pool: .. figure:: /includes/figures/CMAP_diagram.svg :alt: CMAP diagram -In addition to the sockets needed to support your application's threads, -each ``MongoClient`` instance opens two additional sockets per server -in your MongoDB topology for monitoring the server's state. -For example, a client connected to a three-node replica set opens six -monitoring sockets. If the application uses the default setting for -``MaxConnectionPoolSize`` and only queries the primary (default) node, then -there can be at most ``106`` total connections in use. If the -application uses a :ref:`read preference ` to query the -secondary nodes, those connection pools grow and there can be -``306`` total connections. - -To support high numbers of concurrent MongoDB threads -within one process, you can increase ``MaxConnectionPoolSize``. - -The driver has a wait queue that limits the number of threads that can -wait for a connection. The size of the wait queue is determined by the -``WaitQueueMultiple`` option, which defaults to ``5``. To calculate the -maximum wait queue size, the driver multiplies ``WaitQueueMultiple`` by -``MaxConnectionPoolSize``. If you use the default value for each option, -the wait queue size will be ``500``. You can also set the wait queue -size by specifying the ``WaitQueueSize`` option, which overrides the -other settings. However, we do not recommend changing the wait queue -size from the default. - -Connection pools are rate-limited. The ``MaxConnecting`` setting -determines the number of connections that the pool can create in -parallel at any time. For example, if the value of ``MaxConnecting`` is -``2``, the third thread that attempts to concurrently check out a -connection succeeds only in one of the following cases: - -- One of the first two threads finishes creating a connection. -- An existing connection is checked back into the pool. -- The driver's ability to reuse existing connections improves due to - rate-limits on connection creation. - -You can set the minimum number of concurrent connections to -each server by using the ``MinConnectionPoolSize`` option, which -defaults to ``0``. The connection pool will be initialized with this -number of sockets. If errors cause any sockets to close and the -total number of sockets (both in-use and idle) drops below the minimum, -the driver opens more sockets until the number reaches the minimum. - -You can set the maximum number of milliseconds that a connection can -remain idle in the pool by using the ``MaxConnectionIdleTime`` option. -Once a connection is idle for ``MaxConnectionIdleTime``, the driver -removes it. This option defaults to 10 minutes. If the pool size falls -below ``MinConnectionPoolSize``, the driver removes *and* replaces the -idle connection. - -``MongoClient`` also has the ``MaxConnectionLifeTime`` option, which -specifies the length of time, 30 minutes by default, that a connection -can be pooled before expiring. - -The following default configuration for a ``MongoClient`` works for most -applications: +Configuring Connection Pools +---------------------------- + +You can specify the following connection pool settings in your ``MongoClient`` object or in +your connection URI: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Setting + - Description + + * - ``ConnectTimeout`` + - | The maximum amount of time that the {+driver-short+} waits when establishing a new + connection before timing out. + | + | **Data Type**: ``TimeSpan`` + | **Default**: 30 seconds + | **Connection URI Example**: ``connectTimeoutMS=0`` + + * - ``MaxConnecting`` + - | The maximum number of connections that each pool can establish concurrently. + If this limit is reached, further requests wait until a connection is established + or another in-use connection is checked back into the pool. + | + | **Data Type**: ``integer`` + | **Default**: ``2`` + | **Connection URI Example**: ``maxConnecting=3`` + + * - ``MaxConnectionIdleTime`` + - | The maximum time that a connection can remain idle in the pool. When a connection + exceeds this limit, the {+driver-short+} closes the connection and removes it from + the pool. + | + | **Data Type**: ``TimeSpan`` + | **Default**: 10 minutes + | **Connection URI Example**: ``maxIdleTimeMS=60000`` + + * - ``MaxConnectionLifeTime`` + - | The maximum time that a connection can be pooled. When a connection exceeds this + limit, the {+driver-short+} closes the connection and removes it from the pool. + | + | **Data Type**: ``TimeSpan`` + | **Default**: 30 minutes + | **Connection URI Example**: ``maxLifeTimeMS=50000`` + + * - ``MaxConnectionPoolSize`` + - | The maximum number of concurrent connections that the pool maintains. + If the maximum pool size is reached, further requests wait until a connection + becomes available. + | + | **Data Type**: ``integer`` + | **Default**: ``100`` + | **Connection URI Example**: ``maxPoolSize=150`` + + * - ``MinConnectionPoolSize`` + - | The minimum number of concurrent connections that the pool maintains. If + the number of open connections falls below this value due to network errors, + the {+driver-short+} attempts to create new connections to maintain this minimum. + | + | **Data Type**: ``integer`` + | **Default**: ``0`` + | **Connection URI Example**: ``minPoolSize=3`` + + * - ``SocketTimeout`` + - | The length of time that the {+driver-short+} waits for a response from the server + before timing out. + | + | **Data Type**: ``TimeSpan`` + | **Default**: OS default + | **Connection URI Example**: ``socketTimeoutMS=100000`` + + * - ``WaitQueueTimeout`` + - | How long a thread waits for a connection to become available in the connection pool + before timing out. + | + | **Data Type**: ``TimeSpan`` + | **Default**: 2 minutes + | **Connection URI Example**: ``waitQueueTimeoutMS=100000`` + +The following code creates a client with a maximum connection pool size of ``50`` by using the +``MaxConnectionPoolSize`` parameter: .. code-block:: csharp - var client = new MongoClient(""); + var settings = MongoClientSettings.FromConnectionString(""); + settings.MaxConnectionPoolSize = 50; + var client = new MongoClient(settings); + +The following code creates a client with the same configuration as the preceding example, +but uses a connection URI: + +.. code-block:: csharp + + var settings = MongoClientSettings.FromConnectionString("?maxPoolSize=50"); + var client = new MongoClient(settings); + +Additional Information +---------------------- + +To learn more about connection pools, see :manual:`Connection Pool Overview ` +in the {+mdb-server+} manual. + +API Documentation +~~~~~~~~~~~~~~~~~ -Create a client once for each process, and reuse it for all -operations. It is a common mistake to create a new client for each -request, which is very inefficient. +To learn more about any of the methods or types discussed in this +guide, see the following API documentation: -There is no supported way to terminate a ``MongoClient`` in the driver. \ No newline at end of file +- `MongoClient <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.MongoClient.html>`__ +- `MongoClientSettings <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.MongoClientSettings.html>`__ From 9ddd74f1faaa08471f3c0ea58f5fcaf2c92a45d7 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Tue, 29 Apr 2025 14:45:35 -0500 Subject: [PATCH 10/35] DOCSP-49230 - Aggregation stages (builders) (#591) --- snooty.toml | 4 +- source/aggregation.txt | 1347 +-------------------------------- source/aggregation/stages.txt | 356 +++++++++ 3 files changed, 377 insertions(+), 1330 deletions(-) create mode 100644 source/aggregation/stages.txt diff --git a/snooty.toml b/snooty.toml index 61696522..00aa0586 100644 --- a/snooty.toml +++ b/snooty.toml @@ -1,7 +1,9 @@ toc_landing_pages = [ "/get-started", "/connect/connection-options", - "/security/authentication" + "/security/authentication", + "/aggregation", + "/aggregation/stages" ] name = "csharp" title = "C#/.NET" diff --git a/source/aggregation.txt b/source/aggregation.txt index 404bf1ea..037ec1a5 100644 --- a/source/aggregation.txt +++ b/source/aggregation.txt @@ -1,15 +1,15 @@ .. _csharp-aggregation: -=========== -Aggregation -=========== +====================== +Aggregation Operations +====================== .. facet:: :name: genre :values: reference - + .. meta:: - :keywords: code example, transform, pipeline + :keywords: dotnet, code example, transform, pipeline .. contents:: On this page :local: @@ -17,6 +17,12 @@ Aggregation :depth: 2 :class: singlecol +.. toctree:: + :titlesonly: + :maxdepth: 1 + + Pipeline Stages + Overview -------- @@ -28,6 +34,9 @@ return computed results. The MongoDB Aggregation framework is modeled on the concept of data processing pipelines. Documents enter a pipeline comprised of one or more stages, and this pipeline transforms the documents into an aggregated result. +To learn more about the aggregation stages supported by the {+driver-short+}, see +:ref:`Aggregation Stages `. + Analogy ~~~~~~~ @@ -87,1337 +96,17 @@ performing aggregation operations: the `AllowDiskUse <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.AggregateOptions.AllowDiskUse.html#MongoDB_Driver_AggregateOptions_AllowDiskUse>`__ property of the ``AggregateOptions`` object that you pass to the ``Aggregate()`` method. -- The :manual:`$graphLookup ` stage has - a strict memory limit of 100 megabytes and ignores the ``AllowDiskUse`` property. - -Aggregation Example -------------------- - -To perform an aggregation, pass a list of aggregation stages to the -``IMongoCollection.Aggregate()`` method. - -.. note:: - - This example uses 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 :ref:`csharp-get-started`. - -The following code example produces a count of the number of bakeries in each borough -of New York City. To do so, it uses an aggregation pipeline that contains the following stages: - -- A :manual:`$match ` stage to filter for documents whose - ``cuisine`` field contains the value ``"Bakery"``. - -- A :manual:`$group ` stage to group the matching - documents by the ``borough`` field, accumulating a count of documents for each distinct value - of that field. - -The following sections implement this example by using LINQ, Builders, and BsonDocument -approaches to create and combine the aggregation stages used in the example pipeline. - -LINQ Approach -~~~~~~~~~~~~~ - -.. io-code-block:: - - .. input:: /includes/fundamentals/code-examples/LinqAggregation.cs - :language: csharp - :dedent: - :start-after: begin-aggregation - :end-before: end-aggregation - - .. output:: - :language: console - :visible: false - - { _id = Bronx, Count = 71 } - { _id = Brooklyn, Count = 173 } - { _id = Staten Island, Count = 20 } - { _id = Missing, Count = 2 } - { _id = Manhattan, Count = 221 } - { _id = Queens, Count = 204 } - -To learn more about using LINQ to construct aggregation pipelines, see the -:ref:`csharp-linq` guide. - -Builders Approach -~~~~~~~~~~~~~~~~~ - -.. io-code-block:: - - .. input:: /includes/fundamentals/code-examples/BuilderAggregation.cs - :language: csharp - :dedent: - :start-after: begin-aggregation - :end-before: end-aggregation - - .. output:: - :language: console - :visible: false - - { _id = Bronx, Count = 71 } - { _id = Brooklyn, Count = 173 } - { _id = Staten Island, Count = 20 } - { _id = Missing, Count = 2 } - { _id = Manhattan, Count = 221 } - { _id = Queens, Count = 204 } - -To learn more about using builders to construct aggregation pipelines, -see the :ref:`csharp-builders-aggregation` section of the Operations with Builders guide. - -BsonDocument Approach -~~~~~~~~~~~~~~~~~~~~~ - -.. io-code-block:: - - .. input:: /includes/fundamentals/code-examples/Aggregation.cs - :language: csharp - :dedent: - :start-after: begin-aggregation - :end-before: end-aggregation - - .. output:: - :language: console - :visible: false +Troubleshooting +--------------- - { "_id" : "Brooklyn", "count" : 173 } - { "_id" : "Manhattan", "count" : 221 } - { "_id" : "Bronx", "count" : 71 } - { "_id" : "Missing", "count" : 2 } - { "_id" : "Staten Island", "count" : 20 } - { "_id" : "Queens", "count" : 204 } +.. include:: /includes/troubleshooting/unsupported-filter-expression.rst Additional Information ---------------------- -MongoDB Server Manual -~~~~~~~~~~~~~~~~~~~~~ - To view a full list of expression operators, see :manual:`Aggregation Operators `. -To learn more about assembling an aggregation pipeline and view examples, see -:manual:`Aggregation Pipeline `. - -To learn more about creating pipeline stages, see -:manual:`Aggregation Stages `. - To learn about explaining MongoDB aggregation operations, see :manual:`Explain Results ` and -:manual:`Query Plans `. - -API Documentation -~~~~~~~~~~~~~~~~~ - -For more information about the aggregation operations discussed in this guide, see the -following API documentation: - -- `Aggregate() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.Aggregate.html>`__ -- `AggregateOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.AggregateOptions.html>`__ -- `Group() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.PipelineStageDefinitionBuilder.Group.html>`__ -- `Match() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.PipelineStageDefinitionBuilder.Match.html>`__ -- `Where() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Linq.MongoQueryable.Where.html>`__ -- `GroupBy() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Linq.MongoQueryable.GroupBy.html>`__ -- `Select() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Linq.MongoQueryable.Select.html>`__ - -.. TODO: integrate into existing page - -Sample Class ------------- - -The code examples in this guide demonstrate how you can use builders to -create types to interact with documents in the sample collection ``plants.flowers``. -Documents in this collection are modeled by the following ``Flower`` class: - -.. literalinclude:: /includes/fundamentals/code-examples/builders.cs - :language: csharp - :dedent: - :start-after: start-model - :end-before: end-model - -Each builder class takes a generic type parameter -``TDocument`` which represents the type of document that you are working -with. In this guide, the ``Flower`` class is the document type used in -each builder class example. - -.. _csharp-builders-aggregation: - -Build an Aggregation Pipeline ------------------------------ - -The ``PipelineDefinitionBuilder`` class provides a type-safe interface for -defining an **aggregation pipeline**. An aggregation pipeline is a series of -stages that are used to transform a document. Suppose you want to create a -pipeline that performs the following operations: - -- Matches all documents with "spring" in the ``Season`` field -- Sorts the results by the ``Category`` field -- Groups the documents by category and shows the average price and total - available for all documents in that category - -Use ``PipelineDefinitionBuilder`` classes to build the pipeline: - -.. code-block:: csharp - - var sortBuilder = Builders.Sort.Ascending(f => f.Category); - var matchFilter = Builders.Filter.AnyEq(f => f.Season, "spring"); - - var pipeline = new EmptyPipelineDefinition() - .Match(matchFilter) - .Sort(sortBuilder) - .Group(f => f.Category, - g => new - { - name = g.Key, - avgPrice = g.Average(f => f.Price), - totalAvailable = g.Sum(f => f.Stock) - } - ); - -The preceding example creates the following pipeline: - -.. code-block:: json - - [{ "$match" : { "season" : "spring" } }, { "$sort" : { "category" : 1 } }, { "$group" : { "_id" : "$category", "avgPrice" : { "$avg" : "$price" }, "totalAvailable" : { "$sum" : "$stock" } } }] - -You can add stages to your pipeline that don't have corresponding type-safe -methods in the ``PipelineDefinitionBuilder`` interface by providing your query -as a ``BsonDocument`` to the `AppendStage() method -<{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.PipelineDefinitionBuilder.AppendStage.html>`__. - -.. code-block:: csharp - - var pipeline = new EmptyPipelineDefinition().AppendStage("{ $set: { field1: '$field2' } }"); - -.. note:: - - When using a ``BsonDocument`` to define your pipeline stage, the driver does - not take into account any ``BsonClassMap``, serialization attributes or - serialization conventions. The field names used in the ``BsonDocument`` must - match those stored on the server. - - For more information on providing a query as a ``BsonDocument``, see our - :ref:`FAQ page `. - -To learn more about the Aggregation Pipeline, see the -:manual:`Aggregation Pipeline ` server manual page. - -.. _csharp-builders-out: - -Write Pipeline Results to a Collection -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You can write the documents returned from an aggregation pipeline to a -collection by creating an ``$out`` stage at the end of your aggregation -pipeline. To create an ``$out`` stage, call the ``Out()`` method on a -``PipelineStageDefinitionBuilder``. The ``Out()`` method requires the name of -the collection you want to write the documents to. - -The following example builds an aggregation pipeline that matches all documents -with a ``season`` field value of ``"Spring"`` and outputs them to -a ``springFlowers`` collection: - -.. code-block:: csharp - - var outputCollection = database.GetCollection("springFlowers"); - var matchFilter = Builders.Filter.AnyEq(f => f.Season, "spring"); - - // Creates an aggregation pipeline and outputs resulting documents to a new collection. - var pipeline = new EmptyPipelineDefinition() - .Match(matchFilter) - .Out(outputCollection); - -You can write the results of an aggregation pipeline to a time series collection -by specifying a ``TimeSeriesOption`` object and passing it as the second -parameter to the ``Out()`` method. - -Imagine that the documents in the ``plants.flowers`` collection contain a ``datePlanted`` field that -holds BSON date values. You can store the documents in this collection in a time -series collection by using the ``datePlanted`` field as the time field. - -The following example creates a ``TimeSeriesOptions`` object and specifies -``datePlanted`` as the ``timeField``. It then builds an aggregation pipeline that matches all documents -with a ``season`` field value of ``"Spring"`` and outputs them to a -time series collection called ``springFlowerTimes``. - -.. code-block:: csharp - - var timeSeriesOptions = new TimeSeriesOptions("datePlanted"); - var collectionName = "springFlowerTimes" - var matchFilter = Builders.Filter.AnyEq(f => f.Season, "spring"); - - // Creates an aggregation pipeline and outputs resulting documents to a time series collection. - var pipeline = new EmptyPipelineDefinition() - .Match(matchFilter) - .Out(collectionName, timeSeriesOptions); - -To learn more about time series collections, see :ref:`csharp-time-series`. - - -- `PipelineDefinitionBuilder <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.PipelineDefinitionBuilder.html>`__ - -.. TODO: integrate into existing page - -.. _csharp-linq: - -==== -LINQ -==== - -.. facet:: - :name: genre - :values: reference - -.. meta:: - :keywords: code example, query, aggregation - - -Overview --------- - -.. include:: /includes/linq-vs-builders.rst - -In this guide you can learn how to use -`LINQ `__ -with the {+driver-long+}. LINQ allows you to construct queries against -strongly typed collections of objects by using language keywords and operators. -The {+driver-short+} automatically translates LINQ queries into -:manual:`aggregation operations `. - -.. important:: - - LINQ3 is the only LINQ provider available in the {+driver-long+}. If you have - manually configured your project to use LINQ2, it will not compile. - -The examples in this guide use the ``restaurants`` collection -in the ``sample_restaurants`` database provided in the :atlas:`Atlas sample datasets `. -To learn how to create a free MongoDB Atlas cluster and load the sample datasets, -see the :ref:``. - -The following ``Restaurant``, ``Address`` and ``GradeEntry`` classes model the -documents in this collection: - -.. literalinclude:: /includes/fundamentals/code-examples/linq.cs - :language: csharp - :dedent: - :start-after: start-restaurant-model - :end-before: end-restaurant-model - -.. literalinclude:: /includes/fundamentals/code-examples/linq.cs - :language: csharp - :dedent: - :start-after: start-address-model - :end-before: end-address-model - -.. literalinclude:: /includes/fundamentals/code-examples/linq.cs - :language: csharp - :dedent: - :start-after: start-grade-model - :end-before: end-grade-model - -.. include:: /includes/convention-pack-note.rst - -.. _csharp-linq-queryable: - -Make A Collection Queryable ---------------------------- - -To use LINQ to query your collection, you must first create an -an `IQueryable -`__ -object that links to the collection. To create the object, use the ``AsQueryable()`` method -as follows: - -.. code-block:: csharp - :emphasize-lines: 3 - - 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**, -which resembles SQL query syntax. - -Select the :guilabel:`Method Syntax` or :guilabel:`Query Syntax` tab to see -how to compose a query using LINQ: - -.. tabs:: - - .. tab:: Method Syntax - :tabid: method-syntax - - .. code-block:: csharp - - var query = queryableCollection - .Where(r => r.Name == "The Movable Feast") - .Select(r => new { r.Name, r.Address }); - - .. tab:: Query Syntax - :tabid: query-syntax - - .. code-block:: csharp - - var query = from r in queryableCollection - where r.Name == "The Movable Feast" - select new { r.Name, r.Address }; - -You can print the results of the preceding example as follows: - -.. io-code-block:: - - .. input:: - :language: csharp - - foreach (var restaurant in query) - { - Console.WriteLine(restaurant.ToJson()); - } - - .. output:: - - { "name" : "The Movable Feast", "address" : { "building" : "284", "coord" : [-73.982923900000003, 40.6580753], "street" : "Prospect Park West", "zipcode" : "11215" } } - -.. tip:: Accessing Query Results - - You can also access the results of your query by using the ``ToList()`` or - ``ToCursor()`` methods: - - .. code-block:: csharp - - var results = query.ToList(); - - .. code-block:: csharp - - var results = query.ToCursor(); - - -Supported Aggregation Stages ----------------------------- - -You can use LINQ to create an :ref:`aggregation pipeline `. -The {+driver-short+} automatically translates each LINQ statement into the corresponding -aggregation pipeline stages. In this section you can learn which -aggregation pipeline stages are supported. - -To learn more about the aggregation pipeline stages, see the -:ref:`aggregation-pipeline-operator-reference` page in the server manual. - -$project -~~~~~~~~ - -The ``$project`` aggregation stage returns a document containing only the specified -fields. - -Select the :guilabel:`Method Syntax` or :guilabel:`Query Syntax` tab to see how -to generate a ``$project`` stage using LINQ: - -.. tabs:: - - .. tab:: Method Syntax - :tabid: method-syntax - - .. code-block:: csharp - :emphasize-lines: 2 - - var query = queryableCollection - .Select(r => new { r.Name, r.Address }); - - .. tab:: Query Syntax - :tabid: query-syntax - - .. code-block:: csharp - :emphasize-lines: 2 - - var query = from r in queryableCollection - select new { r.Name, r.Address }; - -The result of the preceding example contains the following document: - -.. code-block:: json - - { "name" : "The Movable Feast", "address" : { "building" : "284", "coord" : [-73.982923900000003, 40.6580753], "street" : "Prospect Park West", "zipcode" : "11215" } } - -.. note:: Excluding the ``_id`` Field - - If you don't include the ``_id`` field in your LINQ projection, the {+driver-short+} - automatically excludes it from the results. - -$match -~~~~~~ - -The ``$match`` aggregation stage returns the documents that match a specified -criteria. - -Select the :guilabel:`Method Syntax` or :guilabel:`Query Syntax` tab to see how -to generate a ``$match`` stage using LINQ: - -.. tabs:: - - .. tab:: Method Syntax - :tabid: method-syntax - - .. code-block:: csharp - :emphasize-lines: 2 - - var query = queryableCollection - .Where(r => r.Name == "The Movable Feast"); - - .. tab:: Query Syntax - :tabid: query-syntax - - .. code-block:: csharp - :emphasize-lines: 2 - - var query = from r in queryableCollection - where r.Name == "The Movable Feast" - select r; - -The result of the preceding example contains the following document: - -.. code-block:: json - - // Results Truncated - - { "_id" : ObjectId(...), "name" : "The Movable Feast", "restaurant_id" : "40361606", "cuisine" : "American", "address" : {...}, "borough" : "Brooklyn", "grades" : [...] } - -$limit -~~~~~~ - -The ``$limit`` aggregation stage limits the number of documents returned by the -query. The following example shows how to generate a ``$limit`` stage using LINQ: - -.. code-block:: csharp - :emphasize-lines: 4 - - var query = queryableCollection - .Where(r => r.Cuisine == "Italian") - .Select(r => new {r.Name, r.Cuisine}) - .Take(5); - -The result of the preceding example contains the following documents: - -.. code-block:: json - - { "name" : "Philadelhia Grille Express", "cuisine" : "Italian" } - { "name" : "Isle Of Capri Resturant", "cuisine" : "Italian" } - { "name" : "Marchis Restaurant", "cuisine" : "Italian" } - { "name" : "Crystal Room", "cuisine" : "Italian" } - { "name" : "Forlinis Restaurant", "cuisine" : "Italian" } - -$sample -~~~~~~~ - -The ``$sample`` aggregation stage returns a random sample of documents from a -collection. The following example shows how to generate a ``$sample`` stage by using -LINQ: - -.. code-block:: csharp - :emphasize-lines: 4 - - var query = queryableCollection - .Aggregate() - .Sample(4) - .ToList(); - -The result of the preceding example contains the following documents: - -.. code-block:: json - - // Results Truncated - - { "name" : "Von Dolhens", "cuisine" : "Ice Cream, Gelato, Yogurt, Ices" } - { "name" : "New York Mercantile Exchange", "cuisine" : "American" } - { "name" : "Michaelangelo's Restaurant", "cuisine" : "Italian" } - { "name" : "Charlie Palmer Steak", "cuisine" : "American" } - -$skip -~~~~~ - -The ``$skip`` aggregation stage skips over a specified number of documents returned -by a query, then returns the rest of the results. The following example shows how to generate -a ``$skip`` stage using LINQ: - -.. code-block:: csharp - :emphasize-lines: 4 - - var query = queryableCollection - .Where(r => r.Cuisine == "Italian") - .Select(r => new {r.Name, r.Cuisine}) - .Skip(2); - -The preceding example skips the first two restaurants that match the criteria, and -returns the rest. The result contains the following documents: - -.. code-block:: json - - // Results Truncated - - { "name" : "Marchis Restaurant", "cuisine" : "Italian" } - { "name" : "Crystal Room", "cuisine" : "Italian" } - { "name" : "Forlinis Restaurant", "cuisine" : "Italian" } - ... - -$unwind -~~~~~~~ - -The ``$unwind`` aggregation stage deconstructs a specified array field and returns -a document for each element in that array. - -Select the :guilabel:`Method Syntax` or :guilabel:`Query Syntax` tab to see how -to generate an ``$unwind`` stage using LINQ: - -.. tabs:: - - .. tab:: Method Syntax - :tabid: method-syntax - - .. code-block:: csharp - :emphasize-lines: 3 - - var query = queryableCollection - .Where(r => r.Name == "The Movable Feast") - .SelectMany(r => r.Grades); - - .. tab:: Query Syntax - :tabid: query-syntax - - .. code-block:: csharp - :emphasize-lines: 3 - - var query = from r in queryableCollection - where r.Name == "The Movable Feast" - from grade in r.Grades - select grade; - -The query in the preceding example finds the document where the ``Name`` field -has the value "The Movable Feast." Then, for each element in this document's -``Grades`` array, the query returns a new document. The result contains the -following documents: - -.. code-block:: json - - { "date" : ISODate("2014-11-19T00:00:00Z"), "grade" : "A", "score" : 11 } - { "date" : ISODate("2013-11-14T00:00:00Z"), "grade" : "A", "score" : 2 } - { "date" : ISODate("2012-12-05T00:00:00Z"), "grade" : "A", "score" : 13 } - { "date" : ISODate("2012-05-17T00:00:00Z"), "grade" : "A", "score" : 11 } - -Nested Statements -+++++++++++++++++ - -You can chain or nest ``Select`` and ``SelectMany`` statements to unwind nested -arrays. Consider a collection that contains documents with a **new** schema. These -documents contain a ``restaurants`` field, which holds an array of documents -represented by the ``Restaurant`` class. The documents within the array each have -a ``grades`` field that holds an array of documents represented by -the ``Grade`` class. The following code is an example of a single document in -this collection: - -.. code-block:: json - - { - "_id": { "$oid": ... }, - "restaurants": [ - { - "_id": { ... } , - "address": { ... }, - "name": "Tov Kosher Kitchen", - "grades": [ - { - "date" : ISODate("2014-11-24T00:00:00Z"), - "grade" : "Z", - "score" : 20.0 - }, - { - "date" : ISODate("2013-01-17T00:00:00Z"), - "grade" : "A", - "score" : 13.0 - } - ] - ... - }, - { - "_id": { ... } , - "address": { ... }, - "name": "Harriet's Kitchen", - "grades": [ - { - "date" : ISODate("2014-04-19T00:00:00Z"), - "grade" : "B", - "score" : 12.0 - } - ], - ... - }, - ... - ] - } - -You can nest ``SelectMany`` statements within ``SelectMany`` or ``Select`` -statements. The following example nests a ``SelectMany`` statement within a -``Select`` statement to retrieve an array from each document in the collection. -Each array holds all grade objects from all restaurants in each document. - -.. io-code-block:: - :copyable: true - - .. input:: /includes/fundamentals/code-examples/linq.cs - :language: csharp - :start-after: start-nested-SelectMany - :end-before: end-nested-SelectMany - - .. output:: - :visible: false - :language: json - - // output for first document in collection - [ - { "date" : ISODate("2014-11-24T00:00:00Z"), - "grade" : "Z", - "score" : 20.0 - }, - { "date" : ISODate("2013-01-17T00:00:00Z"), - "grade" : "A", - "score" : 13.0 - }, - { - "date" : ISODate("2014-04-19T00:00:00Z"), - "grade" : "B", - "score" : 12.0 - }, - ... - ], - // output for second document in collection - [ - ... - ] - -$group -~~~~~~ - -The ``$group`` aggregation stage separates documents into groups according to -the criteria you specify. - -Select the :guilabel:`Method Syntax` or :guilabel:`Query Syntax` tab to see how -to generate an ``$group`` stage using LINQ: - -.. tabs:: - - .. tab:: Method Syntax - :tabid: method-syntax - - .. code-block:: csharp - :emphasize-lines: 2 - - var query = queryableCollection - .GroupBy(r => r.Cuisine) - .Select(g => new { Cuisine = g.Key, Count = g.Count() }); - - .. tab:: Query Syntax - :tabid: query-syntax - - .. code-block:: csharp - :emphasize-lines: 2 - - var query = from r in queryableCollection - group r by r.Cuisine into g - select new {Cuisine = g.Key, Count = g.Count()}; - -The preceding example groups each document by the value in its ``Cuisine`` field, -then counts how many documents have each ``Cuisine`` value. The result contains -the following documents: - -.. code-block:: json - - // Results Truncated - - { "cuisine" : "Caribbean", "count" : 657 } - { "cuisine" : "Café/Coffee/Tea", "count" : 1214 } - { "cuisine" : "Iranian", "count" : 2 } - { "cuisine" : "Nuts/Confectionary", "count" : 6 } - { "cuisine" : "Middle Eastern", "count" : 168 } - ... - -.. note:: Result Order - - The preceding queries don't always return results in the same order. Running - this example may return the results in a different order than shown above. - -$sort -~~~~~ - -The ``$sort`` aggregation stage returns the results of your query in the order -that you specify. - -Select the :guilabel:`Method Syntax` or :guilabel:`Query Syntax` tab to see how -to generate an ``$sort`` stage using LINQ: - -.. tabs:: - - .. tab:: Method Syntax - :tabid: method-syntax - - .. code-block:: csharp - :emphasize-lines: 2 - - var query = queryableCollection - .OrderBy(r => r.Name) - .ThenByDescending(r => r.RestaurantId); - - .. tab:: Query Syntax - :tabid: query-syntax - - .. code-block:: csharp - :emphasize-lines: 2 - - var query = from r in queryableCollection - orderby r.Name, r.RestaurantId descending - select r; - -The preceding example returns the query results sorted alphabetically by the -``Name`` field, with a secondary descending sort on the ``RestaurantId`` field. -The following is a subset of the documents contained in the returned results: - -.. code-block:: json - - // Results Truncated - - ... - { "_id" : ObjectId(...), "name" : "Aba Turkish Restaurant", "restaurant_id" : "41548686", "cuisine" : "Turkish", "address" : {...}, "borough" : "Manhattan", "grades" : [...] } - { "_id" : ObjectId(...), "name" : "Abace Sushi", "restaurant_id" : "50006214", "cuisine" : "Japanese", "address" : { ... }, "borough" : "Manhattan", "grades" : [...] } - { "_id" : ObjectId(...), "name" : "Abacky Potluck", "restaurant_id" : "50011222", "cuisine" : "Asian", "address" : { ... }, "borough" : "Manhattan", "grades" : [...] } - { "_id" : ObjectId(...), "name" : "Abaleh", "restaurant_id" : "50009096", "cuisine" : "Mediterranean", "address" : { ... }, "borough" : "Manhattan", "grades" : [...] } - ... - -$lookup -~~~~~~~ - -The ``$lookup`` aggregation stage joins documents from one collection to documents -from another collection in the same database. The ``$lookup`` stage adds a new -array field to each input document. The new array field contains the matching -documents from the "joined" collection. - -.. note:: - - To perform a lookup, you must make both collections queryable by using the - ``AsQueryable()`` method. - - To learn how to make a collection queryable, see :ref:`csharp-linq-queryable`. - -Consider a second collection in the ``sample_restaurants`` database called -``reviews`` that has restaurant reviews. You can join documents from that collection -to documents with the same ``name`` value in the ``restaurants`` collection using -the ``$lookup`` stage. - -The following ``Review`` class models the documents in the ``reviews`` collection: - -.. literalinclude:: /includes/fundamentals/code-examples/linq.cs - :language: csharp - :dedent: - :start-after: start-review-model - :end-before: end-review-model - -Select the :guilabel:`Method Syntax` or :guilabel:`Query Syntax` tab to see how -to generate a ``$lookup`` stage by using LINQ: - -.. tabs:: - - .. tab:: Method Syntax - :tabid: method-syntax - - .. code-block:: csharp - - var query = queryableCollection - .GroupJoin(reviewCollection, - restaurant => restaurant.Name, - review => review.RestaurantName, - (restaurant, reviews) => - new { Restaurant = restaurant, Reviews = reviews } - ); - - .. tab:: Query Syntax - :tabid: query-syntax - - .. code-block:: csharp - - var query = from restaurant in queryableCollection - join rv in reviewCollection on restaurant.Name equals rv.RestaurantName into reviews - select new { restaurant, reviews }; - -The preceding example returns all documents from the ``restaurants`` collection. Each -restaurant document has an added field called ``reviews``, which contains all -reviews for that restaurant. A review matches a restaurant if the value of the -``name`` field in the review document matches the ``name`` field of the restaurant -document. - -The following shows a subset of the returned results: - -.. code-block:: json - - // Results Truncated - - { - "restaurant": { - "_id": ObjectId("..."), - "name": "The Movable Feast", - "restaurant_id": "40361606", - "cuisine": "American", - "address": { ... }, - "borough": "Brooklyn", - "grades": [ ... ] - }, - "reviews": [ - { - "_id": ObjectId("..."), - "restaurant_name": "The Movable Feast", - "reviewer": "Lazlo Cravensworth", - "review_text": "Great restaurant! 12/10 stars!" - }, - { - "_id": ObjectId("..."), - "restaurant_name": "The Movable Feast", - "reviewer": "Michael Scarn", - "review_text": "It really was a feast" - } - ] - } - -$vectorSearch -~~~~~~~~~~~~~ - -The ``$vectorSearch`` aggregation stage performs an *approximate nearest neighbor* search -on a vector in the specified field. Your collection *must* have a -defined Atlas Vector Search index before you can perform a vector search on your data. - -.. tip:: - - To obtain the sample dataset used in the following example, see :ref:`csharp-get-started`. - To create the sample Atlas Vector Search index used in the following example, see - :atlas:`Create an Atlas Vector Search Index ` in the - Atlas manual. - -Consider the ``embedded_movies`` collection in the ``sample_mflix`` database. You -can use a ``$vectorSearch`` stage to perform a semantic search on the ``plot_embedding`` -field of the documents in the collection. - -The following ``EmbeddedMovie`` class models the documents in the ``embedded_movies`` -collection: - -.. code-block:: csharp - - [BsonIgnoreExtraElements] - public class EmbeddedMovie - { - [BsonIgnoreIfDefault] - public string Title { get; set; } - - public string Plot { get; set; } - - [BsonElement("plot_embedding")] - public double[] Embedding { get; set; } - } - -The following example shows how to generate a ``$vectorSearch`` stage to search -the ``plot_embedding`` field using vector embeddings for the string ``"time travel"``: - -.. code-block:: csharp - - // Defines vector embeddings for the string "time travel" - var vector = new[] {-0.0016261312,-0.028070757,-0.011342932,-0.012775794,-0.0027440966,0.008683807,-0.02575152,-0.02020668,-0.010283281,-0.0041719596,0.021392956,0.028657231,-0.006634482,0.007490867,0.018593878,0.0038187427,0.029590257,-0.01451522,0.016061379,0.00008528442,-0.008943722,0.01627464,0.024311995,-0.025911469,0.00022596726,-0.008863748,0.008823762,-0.034921836,0.007910728,-0.01515501,0.035801545,-0.0035688248,-0.020299982,-0.03145631,-0.032256044,-0.028763862,-0.0071576433,-0.012769129,0.012322609,-0.006621153,0.010583182,0.024085402,-0.001623632,0.007864078,-0.021406285,0.002554159,0.012229307,-0.011762793,0.0051682983,0.0048484034,0.018087378,0.024325324,-0.037694257,-0.026537929,-0.008803768,-0.017767483,-0.012642504,-0.0062712682,0.0009771782,-0.010409906,0.017754154,-0.004671795,-0.030469967,0.008477209,-0.005218282,-0.0058480743,-0.020153364,-0.0032805866,0.004248601,0.0051449724,0.006791097,0.007650814,0.003458861,-0.0031223053,-0.01932697,-0.033615597,0.00745088,0.006321252,-0.0038154104,0.014555207,0.027697546,-0.02828402,0.0066711367,0.0077107945,0.01794076,0.011349596,-0.0052715978,0.014755142,-0.019753495,-0.011156326,0.011202978,0.022126047,0.00846388,0.030549942,-0.0041386373,0.018847128,-0.00033655585,0.024925126,-0.003555496,-0.019300312,0.010749794,0.0075308536,-0.018287312,-0.016567878,-0.012869096,-0.015528221,0.0078107617,-0.011156326,0.013522214,-0.020646535,-0.01211601,0.055928253,0.011596181,-0.017247654,0.0005939711,-0.026977783,-0.003942035,-0.009583511,-0.0055248477,-0.028737204,0.023179034,0.003995351,0.0219661,-0.008470545,0.023392297,0.010469886,-0.015874773,0.007890735,-0.009690142,-0.00024970944,0.012775794,0.0114762215,0.013422247,0.010429899,-0.03686786,-0.006717788,-0.027484283,0.011556195,-0.036068123,-0.013915418,-0.0016327957,0.0151016945,-0.020473259,0.004671795,-0.012555866,0.0209531,0.01982014,0.024485271,0.0105431955,-0.005178295,0.033162415,-0.013795458,0.007150979,0.010243294,0.005644808,0.017260984,-0.0045618312,0.0024725192,0.004305249,-0.008197301,0.0014203656,0.0018460588,0.005015015,-0.011142998,0.01439526,0.022965772,0.02552493,0.007757446,-0.0019726837,0.009503538,-0.032042783,0.008403899,-0.04609149,0.013808787,0.011749465,0.036388017,0.016314628,0.021939443,-0.0250051,-0.017354285,-0.012962398,0.00006107364,0.019113706,0.03081652,-0.018114036,-0.0084572155,0.009643491,-0.0034721901,0.0072642746,-0.0090636825,0.01642126,0.013428912,0.027724205,0.0071243206,-0.6858542,-0.031029783,-0.014595194,-0.011449563,0.017514233,0.01743426,0.009950057,0.0029706885,-0.015714826,-0.001806072,0.011856096,0.026444625,-0.0010663156,-0.006474535,0.0016161345,-0.020313311,0.0148351155,-0.0018393943,0.0057347785,0.018300641,-0.018647194,0.03345565,-0.008070676,0.0071443142,0.014301958,0.0044818576,0.003838736,-0.007350913,-0.024525259,-0.001142124,-0.018620536,0.017247654,0.007037683,0.010236629,0.06046009,0.0138887605,-0.012122675,0.037694257,0.0055081863,0.042492677,0.00021784494,-0.011656162,0.010276617,0.022325981,0.005984696,-0.009496873,0.013382261,-0.0010563189,0.0026507939,-0.041639622,0.008637156,0.026471283,-0.008403899,0.024858482,-0.00066686375,-0.0016252982,0.027590916,0.0051449724,0.0058647357,-0.008743787,-0.014968405,0.027724205,-0.011596181,0.0047650975,-0.015381602,0.0043718936,0.002159289,0.035908177,-0.008243952,-0.030443309,0.027564257,0.042625964,-0.0033688906,0.01843393,0.019087048,0.024578573,0.03268257,-0.015608194,-0.014128681,-0.0033538956,-0.0028757197,-0.004121976,-0.032389335,0.0034322033,0.058807302,0.010943064,-0.030523283,0.008903735,0.017500903,0.00871713,-0.0029406983,0.013995391,-0.03132302,-0.019660193,-0.00770413,-0.0038853872,0.0015894766,-0.0015294964,-0.006251275,-0.021099718,-0.010256623,-0.008863748,0.028550599,0.02020668,-0.0012962399,-0.003415542,-0.0022509254,0.0119360695,0.027590916,-0.046971202,-0.0015194997,-0.022405956,0.0016677842,-0.00018535563,-0.015421589,-0.031802863,0.03814744,0.0065411795,0.016567878,-0.015621523,0.022899127,-0.011076353,0.02841731,-0.002679118,-0.002342562,0.015341615,0.01804739,-0.020566562,-0.012989056,-0.002990682,0.01643459,0.00042527664,0.008243952,-0.013715484,-0.004835075,-0.009803439,0.03129636,-0.021432944,0.0012087687,-0.015741484,-0.0052016205,0.00080890034,-0.01755422,0.004811749,-0.017967418,-0.026684547,-0.014128681,0.0041386373,-0.013742141,-0.010056688,-0.013268964,-0.0110630235,-0.028337335,0.015981404,-0.00997005,-0.02424535,-0.013968734,-0.028310679,-0.027750863,-0.020699851,0.02235264,0.001057985,0.00081639783,-0.0099367285,0.013522214,-0.012016043,-0.00086471526,0.013568865,0.0019376953,-0.019020405,0.017460918,-0.023045745,0.008503866,0.0064678704,-0.011509543,0.018727167,-0.003372223,-0.0028690554,-0.0027024434,-0.011902748,-0.012182655,-0.015714826,-0.0098634185,0.00593138,0.018753825,0.0010146659,0.013029044,0.0003521757,-0.017620865,0.04102649,0.00552818,0.024485271,-0.009630162,-0.015608194,0.0006718621,-0.0008418062,0.012395918,0.0057980907,0.016221326,0.010616505,0.004838407,-0.012402583,0.019900113,-0.0034521967,0.000247002,-0.03153628,0.0011038032,-0.020819811,0.016234655,-0.00330058,-0.0032289368,0.00078973995,-0.021952773,-0.022459272,0.03118973,0.03673457,-0.021472929,0.0072109587,-0.015075036,0.004855068,-0.0008151483,0.0069643734,0.010023367,-0.010276617,-0.023019087,0.0068244194,-0.0012520878,-0.0015086699,0.022046074,-0.034148756,-0.0022192693,0.002427534,-0.0027124402,0.0060346797,0.015461575,0.0137554705,0.009230294,-0.009583511,0.032629255,0.015994733,-0.019167023,-0.009203636,0.03393549,-0.017274313,-0.012042701,-0.0009930064,0.026777849,-0.013582194,-0.0027590916,-0.017594207,-0.026804507,-0.0014236979,-0.022032745,0.0091236625,-0.0042419364,-0.00858384,-0.0033905501,-0.020739838,0.016821127,0.022539245,0.015381602,0.015141681,0.028817179,-0.019726837,-0.0051283115,-0.011489551,-0.013208984,-0.0047017853,-0.0072309524,0.01767418,0.0025658219,-0.010323267,0.012609182,-0.028097415,0.026871152,-0.010276617,0.021912785,0.0022542577,0.005124979,-0.0019710176,0.004518512,-0.040360045,0.010969722,-0.0031539614,-0.020366628,-0.025778178,-0.0110030435,-0.016221326,0.0036587953,0.016207997,0.003007343,-0.0032555948,0.0044052163,-0.022046074,-0.0008822095,-0.009363583,0.028230704,-0.024538586,0.0029840174,0.0016044717,-0.014181997,0.031349678,-0.014381931,-0.027750863,0.02613806,0.0004136138,-0.005748107,-0.01868718,-0.0010138329,0.0054348772,0.010703143,-0.003682121,0.0030856507,-0.004275259,-0.010403241,0.021113047,-0.022685863,-0.023032416,0.031429652,0.001792743,-0.005644808,-0.011842767,-0.04078657,-0.0026874484,0.06915057,-0.00056939584,-0.013995391,0.010703143,-0.013728813,-0.022939114,-0.015261642,-0.022485929,0.016807798,0.007964044,0.0144219175,0.016821127,0.0076241563,0.005461535,-0.013248971,0.015301628,0.0085171955,-0.004318578,0.011136333,-0.0059047225,-0.010249958,-0.018207338,0.024645219,0.021752838,0.0007614159,-0.013648839,0.01111634,-0.010503208,-0.0038487327,-0.008203966,-0.00397869,0.0029740208,0.008530525,0.005261601,0.01642126,-0.0038753906,-0.013222313,0.026537929,0.024671877,-0.043505676,0.014195326,0.024778508,0.0056914594,-0.025951454,0.017620865,-0.0021359634,0.008643821,0.021299653,0.0041686273,-0.009017031,0.04044002,0.024378639,-0.027777521,-0.014208655,0.0028623908,0.042119466,0.005801423,-0.028124074,-0.03129636,0.022139376,-0.022179363,-0.04067994,0.013688826,0.013328944,0.0046184794,-0.02828402,-0.0063412455,-0.0046184794,-0.011756129,-0.010383247,-0.0018543894,-0.0018593877,-0.00052024535,0.004815081,0.014781799,0.018007403,0.01306903,-0.020433271,0.009043689,0.033189073,-0.006844413,-0.019766824,-0.018767154,0.00533491,-0.0024575242,0.018727167,0.0058080875,-0.013835444,0.0040719924,0.004881726,0.012029372,0.005664801,0.03193615,0.0058047553,0.002695779,0.009290274,0.02361889,0.017834127,0.0049017193,-0.0036388019,0.010776452,-0.019793482,0.0067777685,-0.014208655,-0.024911797,0.002385881,0.0034988478,0.020899786,-0.0025858153,-0.011849431,0.033189073,-0.021312982,0.024965113,-0.014635181,0.014048708,-0.0035921505,-0.003347231,0.030869836,-0.0017161017,-0.0061346465,0.009203636,-0.025165047,0.0068510775,0.021499587,0.013782129,-0.0024475274,-0.0051149824,-0.024445284,0.006167969,0.0068844,-0.00076183246,0.030150073,-0.0055948244,-0.011162991,-0.02057989,-0.009703471,-0.020646535,0.008004031,0.0066378145,-0.019900113,-0.012169327,-0.01439526,0.0044252095,-0.004018677,0.014621852,-0.025085073,-0.013715484,-0.017980747,0.0071043274,0.011456228,-0.01010334,-0.0035321703,-0.03801415,-0.012036037,-0.0028990454,-0.05419549,-0.024058744,-0.024272008,0.015221654,0.027964126,0.03182952,-0.015354944,0.004855068,0.011522872,0.004771762,0.0027874154,0.023405626,0.0004242353,-0.03132302,0.007057676,0.008763781,-0.0027057757,0.023005757,-0.0071176565,-0.005238275,0.029110415,-0.010989714,0.013728813,-0.009630162,-0.029137073,-0.0049317093,-0.0008630492,-0.015248313,0.0043219104,-0.0055681667,-0.013175662,0.029723546,0.025098402,0.012849103,-0.0009996708,0.03118973,-0.0021709518,0.0260181,-0.020526575,0.028097415,-0.016141351,0.010509873,-0.022965772,0.002865723,0.0020493253,0.0020509914,-0.0041419696,-0.00039695262,0.017287642,0.0038987163,0.014795128,-0.014661839,-0.008950386,0.004431874,-0.009383577,0.0012604183,-0.023019087,0.0029273694,-0.033135757,0.009176978,-0.011023037,-0.002102641,0.02663123,-0.03849399,-0.0044152127,0.0004527676,-0.0026924468,0.02828402,0.017727496,0.035135098,0.02728435,-0.005348239,-0.001467017,-0.019766824,0.014715155,0.011982721,0.0045651635,0.023458943,-0.0010046692,-0.0031373003,-0.0006972704,0.0019043729,-0.018967088,-0.024311995,0.0011546199,0.007977373,-0.004755101,-0.010016702,-0.02780418,-0.004688456,0.013022379,-0.005484861,0.0017227661,-0.015394931,-0.028763862,-0.026684547,0.0030589928,-0.018513903,0.028363993,0.0044818576,-0.009270281,0.038920518,-0.016008062,0.0093902415,0.004815081,-0.021059733,0.01451522,-0.0051583014,0.023765508,-0.017874114,-0.016821127,-0.012522544,-0.0028390652,0.0040886537,0.020259995,-0.031216389,-0.014115352,-0.009176978,0.010303274,0.020313311,0.0064112223,-0.02235264,-0.022872468,0.0052449396,0.0005723116,0.0037321046,0.016807798,-0.018527232,-0.009303603,0.0024858483,-0.0012662497,-0.007110992,0.011976057,-0.007790768,-0.042999174,-0.006727785,-0.011829439,0.007024354,0.005278262,-0.017740825,-0.0041519664,0.0085905045,0.027750863,-0.038387362,0.024391968,0.00087721116,0.010509873,-0.00038508154,-0.006857742,0.0183273,-0.0037054466,0.015461575,0.0017394272,-0.0017944091,0.014181997,-0.0052682655,0.009023695,0.00719763,-0.013522214,0.0034422,0.014941746,-0.0016711164,-0.025298337,-0.017634194,0.0058714002,-0.005321581,0.017834127,0.0110630235,-0.03369557,0.029190388,-0.008943722,0.009363583,-0.0034222065,-0.026111402,-0.007037683,-0.006561173,0.02473852,-0.007084334,-0.010110005,-0.008577175,0.0030439978,-0.022712521,0.0054582027,-0.0012620845,-0.0011954397,-0.015741484,0.0129557345,-0.00042111133,0.00846388,0.008930393,0.016487904,0.010469886,-0.007917393,-0.011762793,-0.0214596,0.000917198,0.021672864,0.010269952,-0.007737452,-0.010243294,-0.0067244526,-0.015488233,-0.021552904,0.017127695,0.011109675,0.038067464,0.00871713,-0.0025591573,0.021312982,-0.006237946,0.034628596,-0.0045251767,0.008357248,0.020686522,0.0010696478,0.0076708077,0.03772091,-0.018700508,-0.0020676525,-0.008923728,-0.023298996,0.018233996,-0.010256623,0.0017860786,0.009796774,-0.00897038,-0.01269582,-0.018527232,0.009190307,-0.02372552,-0.042119466,0.008097334,-0.0066778013,-0.021046404,0.0019593548,0.011083017,-0.0016028056,0.012662497,-0.000059095124,0.0071043274,-0.014675168,0.024831824,-0.053582355,0.038387362,0.0005698124,0.015954746,0.021552904,0.031589597,-0.009230294,-0.0006147976,0.002625802,-0.011749465,-0.034362018,-0.0067844326,-0.018793812,0.011442899,-0.008743787,0.017474247,-0.021619547,0.01831397,-0.009037024,-0.0057247817,-0.02728435,0.010363255,0.034415334,-0.024032086,-0.0020126705,-0.0045518344,-0.019353628,-0.018340627,-0.03129636,-0.0034038792,-0.006321252,-0.0016161345,0.033642255,-0.000056075285,-0.005005019,0.004571828,-0.0024075406,-0.00010215386,0.0098634185,0.1980148,-0.003825407,-0.025191706,0.035161756,0.005358236,0.025111731,0.023485601,0.0023342315,-0.011882754,0.018287312,-0.0068910643,0.003912045,0.009243623,-0.001355387,-0.028603915,-0.012802451,-0.030150073,-0.014795128,-0.028630573,-0.0013487226,0.002667455,0.00985009,-0.0033972147,-0.021486258,0.009503538,-0.017847456,0.013062365,-0.014341944,0.005078328,0.025165047,-0.015594865,-0.025924796,-0.0018177348,0.010996379,-0.02993681,0.007324255,0.014475234,-0.028577257,0.005494857,0.00011725306,-0.013315615,0.015941417,0.009376912,0.0025158382,0.008743787,0.023832154,-0.008084005,-0.014195326,-0.008823762,0.0033455652,-0.032362677,-0.021552904,-0.0056081535,0.023298996,-0.025444955,0.0097301295,0.009736794,0.015274971,-0.0012937407,-0.018087378,-0.0039387033,0.008637156,-0.011189649,-0.00023846315,-0.011582852,0.0066411467,-0.018220667,0.0060846633,0.0376676,-0.002709108,0.0072776037,0.0034188742,-0.010249958,-0.0007747449,-0.00795738,-0.022192692,0.03910712,0.032122757,0.023898797,0.0076241563,-0.007397564,-0.003655463,0.011442899,-0.014115352,-0.00505167,-0.031163072,0.030336678,-0.006857742,-0.022259338,0.004048667,0.02072651,0.0030156737,-0.0042119464,0.00041861215,-0.005731446,0.011103011,0.013822115,0.021512916,0.009216965,-0.006537847,-0.027057758,-0.04054665,0.010403241,-0.0056281467,-0.005701456,-0.002709108,-0.00745088,-0.0024841821,0.009356919,-0.022659205,0.004061996,-0.013175662,0.017074378,-0.006141311,-0.014541878,0.02993681,-0.00028448965,-0.025271678,0.011689484,-0.014528549,0.004398552,-0.017274313,0.0045751603,0.012455898,0.004121976,-0.025458284,-0.006744446,0.011822774,-0.015035049,-0.03257594,0.014675168,-0.0039187097,0.019726837,-0.0047251107,0.0022825818,0.011829439,0.005391558,-0.016781142,-0.0058747325,0.010309938,-0.013049036,0.01186276,-0.0011246296,0.0062112883,0.0028190718,-0.021739509,0.009883412,-0.0073175905,-0.012715813,-0.017181009,-0.016607866,-0.042492677,-0.0014478565,-0.01794076,0.012302616,-0.015194997,-0.04433207,-0.020606548,0.009696807,0.010303274,-0.01694109,-0.004018677,0.019353628,-0.001991011,0.000058938927,0.010536531,-0.17274313,0.010143327,0.014235313,-0.024152048,0.025684876,-0.0012504216,0.036601283,-0.003698782,0.0007310093,0.004165295,-0.0029157067,0.017101036,-0.046891227,-0.017460918,0.022965772,0.020233337,-0.024072073,0.017220996,0.009370248,0.0010363255,0.0194336,-0.019606877,0.01818068,-0.020819811,0.007410893,0.0019326969,0.017887443,0.006651143,0.00067394477,-0.011889419,-0.025058415,-0.008543854,0.021579562,0.0047484366,0.014062037,0.0075508473,-0.009510202,-0.009143656,0.0046817916,0.013982063,-0.0027990784,0.011782787,0.014541878,-0.015701497,-0.029350337,0.021979429,0.01332228,-0.026244693,-0.0123492675,-0.003895384,0.0071576433,-0.035454992,-0.00046984528,0.0033522295,0.039347045,0.0005119148,0.00476843,-0.012995721,0.0024042083,-0.006931051,-0.014461905,-0.0127558,0.0034555288,-0.0074842023,-0.030256703,-0.007057676,-0.00807734,0.007804097,-0.006957709,0.017181009,-0.034575284,-0.008603834,-0.005008351,-0.015834786,0.02943031,0.016861115,-0.0050849924,0.014235313,0.0051449724,0.0025924798,-0.0025741523,0.04289254,-0.002104307,0.012969063,-0.008310596,0.00423194,0.0074975314,0.0018810473,-0.014248641,-0.024725191,0.0151016945,-0.017527562,0.0018727167,0.0002830318,0.015168339,0.0144219175,-0.004048667,-0.004358565,0.011836103,-0.010343261,-0.005911387,0.0022825818,0.0073175905,0.00403867,0.013188991,0.03334902,0.006111321,0.008597169,0.030123414,-0.015474904,0.0017877447,-0.024551915,0.013155668,0.023525586,-0.0255116,0.017220996,0.004358565,-0.00934359,0.0099967085,0.011162991,0.03092315,-0.021046404,-0.015514892,0.0011946067,-0.01816735,0.010876419,-0.10124666,-0.03550831,0.0056348112,0.013942076,0.005951374,0.020419942,-0.006857742,-0.020873128,-0.021259667,0.0137554705,0.0057880944,-0.029163731,-0.018767154,-0.021392956,0.030896494,-0.005494857,-0.0027307675,-0.006801094,-0.014821786,0.021392956,-0.0018110704,-0.0018843795,-0.012362596,-0.0072176233,-0.017194338,-0.018713837,-0.024272008,0.03801415,0.00015880188,0.0044951867,-0.028630573,-0.0014070367,-0.00916365,-0.026537929,-0.009576847,-0.013995391,-0.0077107945,0.0050016865,0.00578143,-0.04467862,0.008363913,0.010136662,-0.0006268769,-0.006591163,0.015341615,-0.027377652,-0.00093136,0.029243704,-0.020886457,-0.01041657,-0.02424535,0.005291591,-0.02980352,-0.009190307,0.019460259,-0.0041286405,0.004801752,0.0011787785,-0.001257086,-0.011216307,-0.013395589,0.00088137644,-0.0051616337,0.03876057,-0.0033455652,0.00075850025,-0.006951045,-0.0062112883,0.018140694,-0.006351242,-0.008263946,0.018154023,-0.012189319,0.0075508473,-0.044358727,-0.0040153447,0.0093302615,-0.010636497,0.032789204,-0.005264933,-0.014235313,-0.018393943,0.007297597,-0.016114693,0.015021721,0.020033404,0.0137688,0.0011046362,0.010616505,-0.0039453674,0.012109346,0.021099718,-0.0072842683,-0.019153694,-0.003768759,0.039320387,-0.006747778,-0.0016852784,0.018154023,0.0010963057,-0.015035049,-0.021033075,-0.04345236,0.017287642,0.016341286,-0.008610498,0.00236922,0.009290274,0.028950468,-0.014475234,-0.0035654926,0.015434918,-0.03372223,0.004501851,-0.012929076,-0.008483873,-0.0044685286,-0.0102233,0.01615468,0.0022792495,0.010876419,-0.0059647025,0.01895376,-0.0069976957,-0.0042952523,0.017207667,-0.00036133936,0.0085905045,0.008084005,0.03129636,-0.016994404,-0.014915089,0.020100048,-0.012009379,-0.006684466,0.01306903,0.00015765642,-0.00530492,0.0005277429,0.015421589,0.015528221,0.032202728,-0.003485519,-0.0014286962,0.033908837,0.001367883,0.010509873,0.025271678,-0.020993087,0.019846799,0.006897729,-0.010216636,-0.00725761,0.01818068,-0.028443968,-0.011242964,-0.014435247,-0.013688826,0.006101324,-0.0022509254,0.013848773,-0.0019077052,0.017181009,0.03422873,0.005324913,-0.0035188415,0.014128681,-0.004898387,0.005038341,0.0012320944,-0.005561502,-0.017847456,0.0008538855,-0.0047884234,0.011849431,0.015421589,-0.013942076,0.0029790192,-0.013702155,0.0001199605,-0.024431955,0.019926772,0.022179363,-0.016487904,-0.03964028,0.0050849924,0.017487574,0.022792496,0.0012504216,0.004048667,-0.00997005,0.0076041627,-0.014328616,-0.020259995,0.0005598157,-0.010469886,0.0016852784,0.01716768,-0.008990373,-0.001987679,0.026417969,0.023792166,0.0046917885,-0.0071909656,-0.00032051947,-0.023259008,-0.009170313,0.02071318,-0.03156294,-0.030869836,-0.006324584,0.013795458,-0.00047151142,0.016874444,0.00947688,0.00985009,-0.029883493,0.024205362,-0.013522214,-0.015075036,-0.030603256,0.029270362,0.010503208,0.021539574,0.01743426,-0.023898797,0.022019416,-0.0068777353,0.027857494,-0.021259667,0.0025758184,0.006197959,0.006447877,-0.00025200035,-0.004941706,-0.021246338,-0.005504854,-0.008390571,-0.0097301295,0.027244363,-0.04446536,0.05216949,0.010243294,-0.016008062,0.0122493,-0.0199401,0.009077012,0.019753495,0.006431216,-0.037960835,-0.027377652,0.016381273,-0.0038620618,0.022512587,-0.010996379,-0.0015211658,-0.0102233,0.007071005,0.008230623,-0.009490209,-0.010083347,0.024431955,0.002427534,0.02828402,0.0035721571,-0.022192692,-0.011882754,0.010056688,0.0011904413,-0.01426197,-0.017500903,-0.00010985966,0.005591492,-0.0077707744,-0.012049366,0.011869425,0.00858384,-0.024698535,-0.030283362,0.020140035,0.011949399,-0.013968734,0.042732596,-0.011649498,-0.011982721,-0.016967745,-0.0060913274,-0.007130985,-0.013109017,-0.009710136}; - - // Specifies that the vector search will consider the 150 nearest neighbors - // in the specified index - var options = new VectorSearchOptions() - { - IndexName = "vector_index", - NumberOfCandidates = 150 - }; - - // Builds aggregation pipeline and specifies that the $vectorSearch stage - // returns 10 results - var results = queryableCollection - .VectorSearch(m => m.Embedding, vector, 10, options) - .Select(m => new { m.Title, m.Plot }); - -The results of the preceding example contain the following documents: - -.. code-block:: json - - { "_id" : ObjectId("573a13a0f29313caabd04a4f"), "plot" : "A reporter, learning of time travelers visiting 20th century disasters, tries to change the history they know by averting upcoming disasters.", "title" : "Thrill Seekers" } - { "_id" : ObjectId("573a13d8f29313caabda6557"), "plot" : "At the age of 21, Tim discovers he can travel in time and change what happens and has happened in his own life. His decision to make his world a better place by getting a girlfriend turns out not to be as easy as you might think.", "title" : "About Time" } - { "_id" : ObjectId("573a13a5f29313caabd13b4b"), "plot" : "Hoping to alter the events of the past, a 19th century inventor instead travels 800,000 years into the future, where he finds humankind divided into two warring races.", "title" : "The Time Machine" } - { "_id" : ObjectId("573a13aef29313caabd2e2d7"), "plot" : "After using his mother's newly built time machine, Dolf gets stuck involuntary in the year 1212. He ends up in a children's crusade where he confronts his new friends with modern techniques...", "title" : "Crusade in Jeans" } - { "_id" : ObjectId("573a1399f29313caabceec0e"), "plot" : "An officer for a security agency that regulates time travel, must fend for his life against a shady politician who has a tie to his past.", "title" : "Timecop" } - { "_id" : ObjectId("573a1399f29313caabcee36f"), "plot" : "A time-travel experiment in which a robot probe is sent from the year 2073 to the year 1973 goes terribly wrong thrusting one of the project scientists, a man named Nicholas Sinclair into a...", "title" : "A.P.E.X." } - { "_id" : ObjectId("573a13c6f29313caabd715d3"), "plot" : "Agent J travels in time to M.I.B.'s early days in 1969 to stop an alien from assassinating his friend Agent K and changing history.", "title" : "Men in Black 3" } - { "_id" : ObjectId("573a13d4f29313caabd98c13"), "plot" : "Bound by a shared destiny, a teen bursting with scientific curiosity and a former boy-genius inventor embark on a mission to unearth the secrets of a place somewhere in time and space that exists in their collective memory.", "title" : "Tomorrowland" } - { "_id" : ObjectId("573a13b6f29313caabd477fa"), "plot" : "With the help of his uncle, a man travels to the future to try and bring his girlfriend back to life.", "title" : "Love Story 2050" } - { "_id" : ObjectId("573a13e5f29313caabdc40c9"), "plot" : "A dimension-traveling wizard gets stuck in the 21st century because cell-phone radiation interferes with his magic. With his home world on the brink of war, he seeks help from a jaded ...", "title" : "The Portal" } - -For more information about Atlas Vector Search, Atlas Vector Search indexes, and how -to incorporate them into your application, see :atlas:`Atlas Vector Search Overview ` -in the Atlas manual. For more examples about running Atlas Vector Search queries using the -{+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 ------------------------------- - -The {+driver-long+} implementation of LINQ does not support the following -aggregation stages: - -- ``$redact`` -- ``$geoNear`` -- ``$out`` - -To learn how to create an aggregation pipeline with the ``$out`` stage by using Builders, see -the :ref:`` section. - -Supported Methods ------------------ - -The following are some methods supported by the {+driver-long+} implementation of LINQ: - -.. list-table:: - :header-rows: 1 - :widths: 40 60 - - * - Method Name - - Description - - * - ``Any`` - - Determines if any documents match the specified criteria - - * - ``Average`` - - Calculates the average of the specified fields - - * - ``Count`` - - Returns an ``Int32`` that represents the number of documents that match the specified criteria - - * - ``LongCount`` - - Returns an ``Int64`` that represents the number of documents that match the specified criteria - - * - ``DateFromString`` - - Converts a ``string`` to a ``DateTime`` object - - * - ``Distinct`` - - Returns distinct documents that match the specified criteria - - * - ``DistinctMany`` - - Returns distinct documents from an array that match the specified criteria - - * - ``Exists`` - - Tests whether a field exists - - * - ``First`` - - Returns the first matching document, and throws an exception if none are found - - * - ``FirstOrDefault`` - - Returns the first matching document, or ``null`` if none are found - - * - ``GroupBy`` - - Groups documents based on specified criteria - - * - ``GroupJoin`` - - Performs a left outer join to another collection in the same database - - * - ``IsMissing`` - - Returns ``true`` if a field is missing and false otherwies - - * - ``IsNullOrMissing`` - - Returns ``true`` if a field is null or missing and false otherwise - - * - ``Max`` - - Returns the document with the maximum specified value - - * - ``OfType`` - - Returns documents that match the specified type - - * - ``OrderBy``, ``OrderByDescending`` - - Returns results in a specified sort order - - * - ``ThenBy``, ``ThenByDescending`` - - Allows a secondary sort to be specified - - * - ``Select`` - - Selects documents based on specified criteria - - * - ``SelectMany`` - - Projects each element of a sequence and combines the resulting sequences into one document - - * - ``Single`` - - Returns the only matching document, and throws an exception if there is not exactly one document - - * - ``SingleOrDefault`` - - Returns a single matching document or ``null`` if no documents match - - * - ``Skip`` - - Skips over a specified number of documents and returns the rest of the results - - * - ``Sum`` - - Returns the sum of the values in a specified field - - * - ``Take`` - - Specifies the number of results to return - - * - ``Where`` - - Returns all documents that match your specified criteria - -View Translated Queries ------------------------ - -When you run a LINQ query, the {+driver-short+} automatically translates your -query into an aggregation pipeline written with the {+query-api+}. You can view -the translated query by using the ``ToString()`` method or the -``LoggedStages`` property. - -To see the translated query for **non-scalar operations**, use the ``ToString()`` -method. Non-scalar operations are operations that return a query object, such -as: - -- ``Where`` -- ``Select`` -- ``SelectMany`` -- ``GroupJoin`` - -The following example calls the ``ToString()`` method on a LINQ query and prints -the translated query: - -.. io-code-block:: - - .. input:: - :language: csharp - - var queryableCollection = _restaurantsCollection.AsQueryable(); - var query = queryableCollection - .Where(r => r.Name == "The Movable Feast"); - - var queryTranslated = query.ToString(); - Console.WriteLine(queryTranslated); - - .. output:: - - sample_restaurants.restaurants.Aggregate([{ "$match" : { "name" : "The Movable Feast" } }]) - -To get the translated query for **scalar operations** use the ``LoggedStages`` -property. Scalar operations are operations that return a scalar result rather than a -query object, such as: - -- ``First`` -- ``Sum`` -- ``Count`` -- ``Min`` -- ``Max`` - -To get a translated query with the ``LoggedStages`` property, you must save -the translated query directly after it is executed, and before executing any -other queries with the same queryable object. - -The following example uses the ``LoggedStages`` property on a LINQ query that -uses a scalar operation, then prints the translated query: - -.. io-code-block:: - - .. input:: - :language: csharp - :emphasize-lines: 6 - - - var queryableCollection = _restaurantsCollection.AsQueryable(); - var query = queryableCollection - .Where(r => r.Name == "The Movable Feast"); - - var result = query.FirstOrDefault(); - var queryTranslated = query.LoggedStages; - - Console.WriteLine(queryTranslated.ToJson()); - - .. output:: - - [{ "$match" : { "name" : "The Movable Feast" } }, { "$limit" : NumberLong(1) }] - -.. important:: - - ``LoggedStages`` is not thread-safe. Executing a query and accessing the - associated ``LoggedStages`` property from multiple threads might have - non-deterministic results. - -Troubleshooting ---------------- - -.. include:: /includes/troubleshooting/unsupported-filter-expression.rst \ No newline at end of file +:manual:`Query Plans `. \ No newline at end of file diff --git a/source/aggregation/stages.txt b/source/aggregation/stages.txt new file mode 100644 index 00000000..94d54fd4 --- /dev/null +++ b/source/aggregation/stages.txt @@ -0,0 +1,356 @@ +.. _csharp-aggregation-stages: + +=========================== +Aggregation Pipeline Stages +=========================== + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: dotnet, code example, transform, pipeline + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +Overview +-------- + +On this page, you can learn how to create an aggregation pipeline and pipeline stages +by using methods in the {+driver-short+}. + +Build an Aggregation Pipeline +----------------------------- + +You can use the {+driver-short+} to build an aggregation pipeline by using builder +methods or BSON documents. See the following sections to learn more about each of these +approaches. + +.. _csharp-aggregation-stages-builder: + +Builder Methods +~~~~~~~~~~~~~~~ + +You can build a type-safe aggregation pipeline in the following ways: + +- Construct an ``EmptyPipelineDefinition`` object. Chain calls from this object + to the relevant aggregation methods. Then, pass the pipeline object to the + ``IMongoCollection.Aggregate()`` method. + +- Call the ``IMongoCollection.Aggregate()`` method. Chain calls from this + method call to the relevant aggregation methods. + +Select the :guilabel:`EmptyPipelineDefinition` +or :guilabel:`Aggregate` tab to see the corresponding code for each approach: + +.. tabs:: + + .. tab:: EmptyPipelineDefinition + :tabid: empty-pipeline-definition + + .. code-block:: csharp + + // Defines the aggregation pipeline + var pipeline = new EmptyPipelineDefinition() + .Match(...) + .Group(...) + .Merge(...); + + // Executes the aggregation pipeline + var results = collection.Aggregate(pipeline); + + .. tab:: Aggregate + :tabid: aggregate + + .. code-block:: csharp + + // Defines and executes the aggregation pipeline + var results = collection.Aggregate() + .Match(...) + .Group(...) + .Merge(...); + +.. _csharp-aggregation-stages-bsondocument: + +BsonDocument +~~~~~~~~~~~~ + +Some aggregation stages don't have corresponding methods in the {+driver-short+}. +To add these stages to your pipeline, use ``BsonDocument`` objects or string literals +to construct a stage in the Query API syntax. Then, pass the BSON document to the +``PipelineDefinitionBuilder.AppendStage()`` method. This syntax supports all stages +in the aggregation pipeline, but doesn't provide type hints or type safety. + +The following code example shows how to add the ``$unset`` stage to an empty aggregation +pipeline: + +.. code-block:: csharp + + var pipeline = new EmptyPipelineDefinition() + .AppendStage("{ $unset: 'field1' }"); + +.. important:: + + If you use a ``BsonDocument`` to define a pipeline stage, the driver doesn't + recognize any ``BsonClassMap`` attributes, serialization attributes, or + serialization conventions. The field names that you use in the ``BsonDocument`` must + match the field names stored in {+mdb-server+}. + +Aggregation Stage Methods +------------------------- + +The following table lists the builder methods in the {+driver-short+} that correspond +to stages in the aggregation pipeline. To learn more about an aggregation stage, +follow the link from the method name to its reference page in the {+mdb-server+} manual. +To learn more about a builder method, follow the link from the method name to its +dedicated page. + +If an aggregation stage isn't in the table, the driver doesn't provide a builder method for +it. In this case, you must use the +:ref:`BsonDocument ` syntax to add the stage +to your pipeline. + +.. list-table:: + :header-rows: 1 + :widths: 28 44 28 + + * - Aggregation Stage + - Description + - Builder Method + + * - :manual:`$bucket ` + - Categorizes incoming documents into groups, called buckets, + based on a specified expression and bucket boundaries. + - :ref:`Bucket() ` + + * - :manual:`$bucketAuto ` + - Categorizes incoming documents into a specific number of + groups, called buckets, based on a specified expression. + Bucket boundaries are automatically determined in an attempt + to evenly distribute the documents into the specified number + of buckets. + - :ref:`BucketAuto() ` + + * - :manual:`$changeStream ` + - Returns a change stream cursor for the + collection. This stage can occur only once in an aggregation + pipeline and it must occur as the first stage. + - :ref:`ChangeStream() ` + + * - :manual:`$changeStreamSplitLargeEvent ` + - Splits large change stream events that exceed 16 MB into smaller fragments returned + in a change stream cursor. + + You can use ``$changeStreamSplitLargeEvent`` only in a ``$changeStream`` pipeline, and + it must be the final stage in the pipeline. + - :ref:`ChangeStreamSplitLargeEvent() ` + + * - :manual:`$count ` + - Returns a count of the number of documents at this stage of + the aggregation pipeline. + - :ref:`Count() ` + + * - :manual:`$densify ` + - Creates new documents in a sequence of documents where certain values in a field are missing. + - :ref:`Densify() ` + + * - :manual:`$documents ` + - Returns literal documents from input expressions. + - :ref:`Documents() ` + + * - :manual:`$facet ` + - Processes multiple aggregation pipelines + within a single stage on the same set + of input documents. Enables the creation of multi-faceted + aggregations capable of characterizing data across multiple + dimensions, or facets, in a single stage. + - :ref:`Facet() ` + + * - :manual:`$graphLookup ` + - Performs a recursive search on a collection. This method adds + a new array field to each output document that contains the traversal + results of the recursive search for that document. + - :ref:`GraphLookup() ` + + * - :manual:`$group ` + - Groups input documents by a specified identifier expression + and applies the accumulator expressions, if specified, to + each group. Consumes all input documents and outputs one + document per each distinct group. The output documents + contain only the identifier field and, if specified, accumulated + fields. + - :ref:`Group() ` + + * - :manual:`$limit ` + - Passes the first *n* documents unmodified to the pipeline, + where *n* is the specified limit. For each input document, + outputs either one document (for the first *n* documents) or + zero documents (after the first *n* documents). + - :ref:`Limit() ` + + * - :manual:`$lookup ` + - Performs a left outer join to another collection in the + *same* database to filter in documents from the "joined" + collection for processing. + - :ref:`Lookup() ` + + * - :manual:`$match ` + - Filters the document stream to allow only matching documents + to pass unmodified into the next pipeline stage. + For each input document, outputs either one document (a match) or zero + documents (no match). + - :ref:`Match() ` + + * - :manual:`$merge ` + - Writes the resulting documents of the aggregation pipeline to + a collection. The stage can incorporate (insert new + documents, merge documents, replace documents, keep existing + documents, fail the operation, process documents with a + custom update pipeline) the results into an output + collection. To use this stage, it must be + the last stage in the pipeline. + - :ref:`Merge() ` + + * - :manual:`$out ` + - Writes the resulting documents of the aggregation pipeline to + a collection. To use this stage, it must be + the last stage in the pipeline. + - :ref:`Out() ` + + * - :manual:`$project ` + - Reshapes each document in the stream, such as by adding new + fields or removing existing fields. For each input document, + outputs one document. + - :ref:`Project() ` + + * - :manual:`$rankFusion ` + - Uses a rank fusion algorithm to combine results from a Vector Search + query and an Atlas Search query. + - :ref:`RankFusion() ` + + * - :manual:`$replaceRoot ` + - Replaces a document with the specified embedded document. The + operation replaces all existing fields in the input document, + including the ``_id`` field. Specify a document embedded in + the input document to promote the embedded document to the + top level. + + The ``$replaceWith`` stage is an alias for the ``$replaceRoot`` stage. + - :ref:`ReplaceRoot() ` + + * - :manual:`$replaceWith ` + - Replaces a document with the specified embedded document. + The operation replaces all existing fields in the input document, including + the ``_id`` field. Specify a document embedded in the input document to promote + the embedded document to the top level. + + The ``$replaceWith`` stage is an alias for the ``$replaceRoot`` stage. + - :ref:`ReplaceWith() ` + + * - :manual:`$sample ` + - Randomly selects the specified number of documents from its + input. + - :ref:`Sample() ` + + * - :manual:`$search ` + - Performs a full-text search of the field or fields in an + :atlas:`Atlas ` + collection. + + This stage is available only for MongoDB Atlas clusters, and is not + available for self-managed deployments. To learn more, see + :atlas:`Atlas Search Aggregation Pipeline Stages + ` in the Atlas documentation. + - :ref:`Search() ` + + * - :manual:`$searchMeta ` + - Returns different types of metadata result documents for the + :atlas:`Atlas Search ` query against an + :atlas:`Atlas ` + collection. + + This stage is available only for MongoDB Atlas clusters, + and is not available for self-managed deployments. To learn + more, see :atlas:`Atlas Search Aggregation Pipeline Stages + ` in the Atlas documentation. + - :ref:`SearchMeta() ` + + * - :manual:`$set ` + - Adds new fields to documents. Like the ``Project()`` method, + this method reshapes each + document in the stream by adding new fields to + output documents that contain both the existing fields + from the input documents and the newly added fields. + - :ref:`Set() ` + + * - :manual:`$setWindowFields ` + - Groups documents into windows and applies one or more + operators to the documents in each window. + - :ref:`SetWindowFields() ` + + * - :manual:`$skip ` + - Skips the first *n* documents, where *n* is the specified skip + number, and passes the remaining documents unmodified to the + pipeline. For each input document, outputs either zero + documents (for the first *n* documents) or one document (if + after the first *n* documents). + - :ref:`Skip() ` + + * - :manual:`$sort ` + - Reorders the document stream by a specified sort key. The documents remain unmodified. + For each input document, outputs one document. + - :ref:`Sort() ` + + * - :manual:`$sortByCount ` + - Groups incoming documents based on the value of a specified + expression, then computes the count of documents in each + distinct group. + - :ref:`SortByCount() ` + + * - :manual:`$unionWith ` + - Combines pipeline results from two collections into a single + result set. + - :ref:`UnionWith() ` + + * - :manual:`$unwind ` + - Deconstructs an array field from the input documents to + output a document for *each* element. Each output document + replaces the array with an element value. For each input + document, outputs *n* Documents, where *n* is the number of + array elements. *n* can be zero for an empty array. + - :ref:`Unwind() ` + + * - :manual:`$vectorSearch ` + - Performs an :abbr:`ANN (Approximate Nearest Neighbor)` or + :abbr:`ENN (Exact Nearest Neighbor)` search on a + vector in the specified field of an + :atlas:`Atlas ` collection. + + This stage is available only for MongoDB Atlas clusters, and is not + available for self-managed deployments. To learn more, see + :ref:`Atlas Vector Search `. + - :ref:`VectorSearch() ` + +API Documentation +----------------- + +To learn more about assembling an aggregation pipeline, see +:manual:`Aggregation Pipeline ` in the {+mdb-server+} +manual. + +To learn more about creating pipeline stages, see +:manual:`Aggregation Stages ` in the +{+mdb-server+} manual. + +For more information about the methods and classes used on this page, see the +following API documentation: + +- `Aggregate() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.Aggregate.html>`__ +- `AggregateOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.AggregateOptions.html>`__ +- `EmptyPipelineDefinition <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.EmptyPipelineDefinition-1.-ctor.html>`__ +- `BsonDocument <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonDocument.html>`__ +- `PipelineDefinitionBuilder.AppendStage() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.PipelineDefinitionBuilder.AppendStage.html>`__ \ No newline at end of file From 785a11cd2547b20057f975e98df8765a543b0761 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Wed, 30 Apr 2025 09:25:57 -0500 Subject: [PATCH 11/35] DOCSP-49635 - Aggregation stages fix (#624) --- source/aggregation/stages.txt | 69 ++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/source/aggregation/stages.txt b/source/aggregation/stages.txt index 94d54fd4..673d84b4 100644 --- a/source/aggregation/stages.txt +++ b/source/aggregation/stages.txt @@ -1,4 +1,6 @@ .. _csharp-aggregation-stages: +.. _csharp-builders-aggregation: +.. _csharp-linq: =========================== Aggregation Pipeline Stages @@ -104,10 +106,9 @@ Aggregation Stage Methods ------------------------- The following table lists the builder methods in the {+driver-short+} that correspond -to stages in the aggregation pipeline. To learn more about an aggregation stage, -follow the link from the method name to its reference page in the {+mdb-server+} manual. -To learn more about a builder method, follow the link from the method name to its -dedicated page. +to stages in the aggregation pipeline. To learn more about an aggregation stage and +see a code example for the equivalent C# method, follow the link from the stage name +to its reference page in the {+mdb-server+} manual. If an aggregation stage isn't in the table, the driver doesn't provide a builder method for it. In this case, you must use the @@ -125,7 +126,7 @@ to your pipeline. * - :manual:`$bucket ` - Categorizes incoming documents into groups, called buckets, based on a specified expression and bucket boundaries. - - :ref:`Bucket() ` + - ``Bucket()`` * - :manual:`$bucketAuto ` - Categorizes incoming documents into a specific number of @@ -133,13 +134,13 @@ to your pipeline. Bucket boundaries are automatically determined in an attempt to evenly distribute the documents into the specified number of buckets. - - :ref:`BucketAuto() ` + - ``BucketAuto()`` * - :manual:`$changeStream ` - Returns a change stream cursor for the collection. This stage can occur only once in an aggregation pipeline and it must occur as the first stage. - - :ref:`ChangeStream() ` + - ``ChangeStream()`` * - :manual:`$changeStreamSplitLargeEvent ` - Splits large change stream events that exceed 16 MB into smaller fragments returned @@ -147,20 +148,20 @@ to your pipeline. You can use ``$changeStreamSplitLargeEvent`` only in a ``$changeStream`` pipeline, and it must be the final stage in the pipeline. - - :ref:`ChangeStreamSplitLargeEvent() ` + - ``ChangeStreamSplitLargeEvent()`` * - :manual:`$count ` - Returns a count of the number of documents at this stage of the aggregation pipeline. - - :ref:`Count() ` + - ``Count()`` * - :manual:`$densify ` - Creates new documents in a sequence of documents where certain values in a field are missing. - - :ref:`Densify() ` + - ``Densify()`` * - :manual:`$documents ` - Returns literal documents from input expressions. - - :ref:`Documents() ` + - ``Documents()`` * - :manual:`$facet ` - Processes multiple aggregation pipelines @@ -168,13 +169,13 @@ to your pipeline. of input documents. Enables the creation of multi-faceted aggregations capable of characterizing data across multiple dimensions, or facets, in a single stage. - - :ref:`Facet() ` + - ``Facet()`` * - :manual:`$graphLookup ` - Performs a recursive search on a collection. This method adds a new array field to each output document that contains the traversal results of the recursive search for that document. - - :ref:`GraphLookup() ` + - ``GraphLookup()`` * - :manual:`$group ` - Groups input documents by a specified identifier expression @@ -183,27 +184,27 @@ to your pipeline. document per each distinct group. The output documents contain only the identifier field and, if specified, accumulated fields. - - :ref:`Group() ` + - ``Group()`` * - :manual:`$limit ` - Passes the first *n* documents unmodified to the pipeline, where *n* is the specified limit. For each input document, outputs either one document (for the first *n* documents) or zero documents (after the first *n* documents). - - :ref:`Limit() ` + - ``Limit()`` * - :manual:`$lookup ` - Performs a left outer join to another collection in the *same* database to filter in documents from the "joined" collection for processing. - - :ref:`Lookup() ` + - ``Lookup()`` * - :manual:`$match ` - Filters the document stream to allow only matching documents to pass unmodified into the next pipeline stage. For each input document, outputs either one document (a match) or zero documents (no match). - - :ref:`Match() ` + - ``Match()`` * - :manual:`$merge ` - Writes the resulting documents of the aggregation pipeline to @@ -213,24 +214,24 @@ to your pipeline. custom update pipeline) the results into an output collection. To use this stage, it must be the last stage in the pipeline. - - :ref:`Merge() ` + - ``Merge()`` * - :manual:`$out ` - Writes the resulting documents of the aggregation pipeline to a collection. To use this stage, it must be the last stage in the pipeline. - - :ref:`Out() ` + - ``Out()`` * - :manual:`$project ` - Reshapes each document in the stream, such as by adding new fields or removing existing fields. For each input document, outputs one document. - - :ref:`Project() ` + - ``Project()`` * - :manual:`$rankFusion ` - Uses a rank fusion algorithm to combine results from a Vector Search query and an Atlas Search query. - - :ref:`RankFusion() ` + - ``RankFusion()`` * - :manual:`$replaceRoot ` - Replaces a document with the specified embedded document. The @@ -240,7 +241,7 @@ to your pipeline. top level. The ``$replaceWith`` stage is an alias for the ``$replaceRoot`` stage. - - :ref:`ReplaceRoot() ` + - ``ReplaceRoot()`` * - :manual:`$replaceWith ` - Replaces a document with the specified embedded document. @@ -249,12 +250,12 @@ to your pipeline. the embedded document to the top level. The ``$replaceWith`` stage is an alias for the ``$replaceRoot`` stage. - - :ref:`ReplaceWith() ` + - ``ReplaceWith()`` * - :manual:`$sample ` - Randomly selects the specified number of documents from its input. - - :ref:`Sample() ` + - ``Sample()`` * - :manual:`$search ` - Performs a full-text search of the field or fields in an @@ -265,7 +266,7 @@ to your pipeline. available for self-managed deployments. To learn more, see :atlas:`Atlas Search Aggregation Pipeline Stages ` in the Atlas documentation. - - :ref:`Search() ` + - ``Search()`` * - :manual:`$searchMeta ` - Returns different types of metadata result documents for the @@ -277,7 +278,7 @@ to your pipeline. and is not available for self-managed deployments. To learn more, see :atlas:`Atlas Search Aggregation Pipeline Stages ` in the Atlas documentation. - - :ref:`SearchMeta() ` + - ``SearchMeta()`` * - :manual:`$set ` - Adds new fields to documents. Like the ``Project()`` method, @@ -285,12 +286,12 @@ to your pipeline. document in the stream by adding new fields to output documents that contain both the existing fields from the input documents and the newly added fields. - - :ref:`Set() ` + - ``Set()`` * - :manual:`$setWindowFields ` - Groups documents into windows and applies one or more operators to the documents in each window. - - :ref:`SetWindowFields() ` + - ``SetWindowFields()`` * - :manual:`$skip ` - Skips the first *n* documents, where *n* is the specified skip @@ -298,23 +299,23 @@ to your pipeline. pipeline. For each input document, outputs either zero documents (for the first *n* documents) or one document (if after the first *n* documents). - - :ref:`Skip() ` + - ``Skip()`` * - :manual:`$sort ` - Reorders the document stream by a specified sort key. The documents remain unmodified. For each input document, outputs one document. - - :ref:`Sort() ` + - ``Sort()`` * - :manual:`$sortByCount ` - Groups incoming documents based on the value of a specified expression, then computes the count of documents in each distinct group. - - :ref:`SortByCount() ` + - ``SortByCount()`` * - :manual:`$unionWith ` - Combines pipeline results from two collections into a single result set. - - :ref:`UnionWith() ` + - ``UnionWith()`` * - :manual:`$unwind ` - Deconstructs an array field from the input documents to @@ -322,7 +323,7 @@ to your pipeline. replaces the array with an element value. For each input document, outputs *n* Documents, where *n* is the number of array elements. *n* can be zero for an empty array. - - :ref:`Unwind() ` + - ``Unwind()`` * - :manual:`$vectorSearch ` - Performs an :abbr:`ANN (Approximate Nearest Neighbor)` or @@ -333,7 +334,7 @@ to your pipeline. This stage is available only for MongoDB Atlas clusters, and is not available for self-managed deployments. To learn more, see :ref:`Atlas Vector Search `. - - :ref:`VectorSearch() ` + - ``VectorSearch()`` API Documentation ----------------- From 473761baa6aad9a187c59951c98ad61697d7c3ac Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Wed, 30 Apr 2025 11:33:51 -0400 Subject: [PATCH 12/35] DOCSP-49054: Connection targets (#589) --- .../connection-options/server-selection.txt | 2 +- source/connect/connection-targets.txt | 174 ++++++++++++++++++ source/connect/mongoclient.txt | 57 ------ .../connection/ConnectionTargets.cs | 0 .../connection/ReplicaSetConnection.cs | 32 +++- 5 files changed, 204 insertions(+), 61 deletions(-) create mode 100644 source/includes/fundamentals/code-examples/connection/ConnectionTargets.cs diff --git a/source/connect/connection-options/server-selection.txt b/source/connect/connection-options/server-selection.txt index 2e32a90e..fc750f3d 100644 --- a/source/connect/connection-options/server-selection.txt +++ b/source/connect/connection-options/server-selection.txt @@ -192,4 +192,4 @@ documentation: - `ClusterConfigurator <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.MongoClientSettings.ClusterConfigurator.html>`__ - `ServerSelectors <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Core.Clusters.ServerSelectors.html>`__ - `IServerSelector <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Core.Clusters.ServerSelectors.IServerSelector.html>`__ -- `SelectServer() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Core.Clusters.ServerSelectors.IServerSelector.SelectServers.html>`__ \ No newline at end of file +- `SelectServer() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Core.Clusters.ServerSelectors.IServerSelector.SelectServers.html>`__ diff --git a/source/connect/connection-targets.txt b/source/connect/connection-targets.txt index e69de29b..4014c6b7 100644 --- a/source/connect/connection-targets.txt +++ b/source/connect/connection-targets.txt @@ -0,0 +1,174 @@ +.. _csharp-connection-targets: + +========================== +Choose a Connection Target +========================== + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: connection string, URI, server, settings, client, load balancing, srv, dns + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +Overview +-------- + +In this guide, you can learn how to use a connection string and ``MongoClient`` object +to connect to different types of MongoDB deployments. + +Atlas +----- + +To connect to a MongoDB deployment on Atlas, include the following elements +in your connection string: + +- URL of your Atlas cluster +- MongoDB username +- MongoDB password + +Then, pass your connection string to the ``MongoClient`` constructor. + +.. tip:: + + Follow the :atlas:`Atlas driver connection guide ` + to retrieve your connection string. + +When you connect to Atlas, we recommend using the {+stable-api+} client option to avoid +breaking changes when Atlas upgrades to a new version of {+mdb-server+}. +To learn more about the {+stable-api+} feature, see the :ref:`` guide. + +The following code shows how to use {+driver-short+} to connect to an Atlas cluster. The +code also uses the ``server_api`` option to specify a {+stable-api+} version. + +.. literalinclude:: /includes/fundamentals/code-examples/connection/AtlasConnection.cs + :language: csharp + :start-after: // start atlas connection + :end-before: // end atlas connection + +Local Deployments +----------------- + +To connect to a local MongoDB deployment, use ``localhost`` as the hostname. By +default, the ``mongod`` process runs on port 27017, though you can customize this for +your deployment. + +The following code shows how to use {+driver-short+} to connect to a local MongoDB +deployment: + +.. literalinclude:: /includes/fundamentals/code-examples/connection/LocalConnection.cs + :language: csharp + :start-after: // start local connection + :end-before: // end local connection + +Replica Sets +------------ + +To connect to a replica set, specify the hostnames (or IP addresses) and +port numbers of the replica set members in your connection string. + +The following code shows how to use {+driver-short+} to connect to a replica set +that contains three hosts: + +.. literalinclude:: /includes/fundamentals/code-examples/connection/ReplicaSetConnection.cs + :language: csharp + :start-after: // start-replica-set-connection-list + :end-before: // end-replica-set-connection-list + +If you aren't able to provide a full list of hosts in the replica set, you can +specify one or more of the hosts in the replica set and instruct {+driver-short+} to +perform automatic discovery to find the others. To instruct the driver to perform +automatic discovery, perform one of the following actions: + +- Specify the name of the replica set as the value of the ``replicaSet`` parameter. +- Specify ``false`` as the value of the ``directConnection`` parameter. You can also omit + this parameter, as it defaults to ``false``. +- Specify more than one host in the replica set. + +In the following example, the driver uses a sample connection URI to connect to the +MongoDB replica set ``sampleRS``, which is running on port ``27017`` of three different +hosts, including ``host1``: + +.. literalinclude:: /includes/fundamentals/code-examples/connection/ReplicaSetConnection.cs + :language: csharp + :start-after: // start-replica-set-connection-rs-name + :end-before: // end-replica-set-connection-rs-name + +.. note:: Specifying the Replica Set Name + + Although the driver can automatically discover replica set members without specifying + the hostnames of all members or the replica set name, we recommend specifying the + replica set name to avoid corner cases where the replica set will not initialize + correctly. + +The {+driver-short+} evenly load balances operations across deployments that are reachable +within the client's ``localThresholdMS`` value. To learn more about how the {+driver-short+} load +balances operations across multiple MongoDB deployments, see the +:ref:`csharp-server-selection` guide. + +.. note:: + + The ``MongoClient`` constructor is *non-blocking*. + When you connect to a replica set, the constructor returns immediately while the + client uses background threads to connect to the replica set. + + If you construct a ``MongoClient`` and immediately print the string representation + of its ``nodes`` attribute, the list might be empty while the client connects to + the replica set members. + +Connect to a Single Server +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To connect to a single server in a replica set rather than the entire replica set, specify +``false`` as the value of the ``directConnection`` connection option. You can do this in two ways: by passing +an argument to the ``MongoClient`` constructor or through a parameter in your connection string. Select the +:guilabel:`MongoClientSettings` or :guilabel:`Connection String` tab to see the corresponding code. + +.. tabs:: + + .. tab:: MongoClientSettings + :tabid: settings + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ReplicaSetConnection.cs + :language: csharp + :start-after: // start-replica-set-direct-connection-settings + :end-before: // end-replica-set-direct-connection-settings + + .. tab:: Connection String + :tabid: connection-string + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ReplicaSetConnection.cs + :language: csharp + :start-after: // start-replica-set-direct-connection-string + :end-before: // end-replica-set-direct-connection-string + +DNS Service Discovery +--------------------- + +To use DNS service discovery to look up the DNS SRV record of the service you're connecting to, +specify the SRV connection format in your connection string. Additionally, if you enable +the SRV connection format, the {+driver-short+} automatically re-scans for new hosts without +having to change the client configuration. + +The following code shows a connection string that uses the SRV connection format: + +.. code-block:: csharp + + var uri = "mongodb+srv://" + +To learn more about the SRV connection format, see the :manual:`SRV Connection Format ` +entry in the {+mdb-server+} manual. + +API Documentation +----------------- + +To learn more about the types discussed in this guide, see the following API documentation: + +- `MongoClient <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.MongoClient.html>`__ +- `MongoClientSettings <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.MongoClientSettings.html>`__ diff --git a/source/connect/mongoclient.txt b/source/connect/mongoclient.txt index 99dbfde5..f97f42d6 100644 --- a/source/connect/mongoclient.txt +++ b/source/connect/mongoclient.txt @@ -98,60 +98,3 @@ MongoDB instance on port ``27017`` of ``localhost``: :dedent: :start-after: // start mongo client settings :end-before: // end mongo client settings - -Other Connection Targets ------------------------- - -Connect to Atlas -~~~~~~~~~~~~~~~~ - -To connect to a MongoDB deployment on Atlas, create a client. You can -create a client that uses your connection string and other -client options by passing a ``MongoClientSettings`` object to the ``MongoClient`` -constructor. - -To specify your connection URI, pass it to the ``FromConnectionString()`` -method, which returns a new ``MongoClientSettings`` instance. To specify any other -client options, set the relevant fields of the ``MongoClientSettings`` object. - -You can set the {+stable-api+} version as a client option to avoid -breaking changes when you upgrade to a new server version. To -learn more about the {+stable-api+} feature, see the :ref:`{+stable-api+} page -`. - -The following code shows how you can specify the connection string and -the {+stable-api+} client option when connecting to a MongoDB -deployment and verify that the connection is successful: - -.. literalinclude:: /includes/fundamentals/code-examples/connection/AtlasConnection.cs - :language: csharp - :start-after: // start atlas connection - :end-before: // end atlas connection - -.. tip:: - - Follow the :atlas:`Atlas driver connection guide ` - to retrieve your connection string. - -Connect to a Replica Set -~~~~~~~~~~~~~~~~~~~~~~~~ - -To connect to a replica set deployment, specify the hostnames (or IP addresses) and -port numbers of the members of the replica set. - -If you aren't able to provide a full list of hosts in the replica set, you can -specify one or more of the hosts in the replica set and instruct the driver to -perform automatic discovery in one of the following ways: - -- Specify the name of the replica set as the value of the ``replicaSet`` parameter. -- Specify ``false`` as the value of the ``directConnection`` parameter. -- Specify more than one host in the replica set. - -In the following example, the driver uses a sample connection URI to connect to the -MongoDB replica set ``sampleRS``, which is running on port ``27017`` of three different -hosts, including ``sample.host1``: - -.. literalinclude:: /includes/fundamentals/code-examples/connection/ReplicaSetConnection.cs - :language: csharp - :start-after: // start replica set connection - :end-before: // end replica set connection diff --git a/source/includes/fundamentals/code-examples/connection/ConnectionTargets.cs b/source/includes/fundamentals/code-examples/connection/ConnectionTargets.cs new file mode 100644 index 00000000..e69de29b diff --git a/source/includes/fundamentals/code-examples/connection/ReplicaSetConnection.cs b/source/includes/fundamentals/code-examples/connection/ReplicaSetConnection.cs index 46c53384..8f253a49 100644 --- a/source/includes/fundamentals/code-examples/connection/ReplicaSetConnection.cs +++ b/source/includes/fundamentals/code-examples/connection/ReplicaSetConnection.cs @@ -1,11 +1,37 @@ // Connects to a specific replica set by using a URI -// start replica set connection +// start-replica-set-connection-rs-name using MongoDB.Driver; // Sets the connection URI than includes the replica set name -const string connectionUri = "mongodb://sample.host1:27017/?replicaSet=sampleRS"; +const string connectionUri = "mongodb://host1:27017/?replicaSet=sampleRS"; // Creates a new client and connects to the server var client = new MongoClient(connectionUri); -// end replica set connection \ No newline at end of file +// end-replica-set-connection-rs-name + +// start-replica-set-connection-list +using MongoDB.Driver; + +// Sets the connection URI than includes the list of hosts in the replica set +const string connectionUri = "mongodb://host1:27017,host2:27017,host3:27017"; + +// Creates a new client and connects to the server +var client = new MongoClient(connectionUri); +// end-replica-set-connection-list + +// start-replica-set-direct-connection-string +using MongoDB.Driver; + +const string connectionUri = "mongodb://host1:27017/?directConnection=true"; +var client = new MongoClient(connectionUri); +// end-replica-set-direct-connection-string + +// start-replica-set-direct-connection-settings +using MongoDB.Driver; + +var settings = MongoClientSettings.FromConnectionString("mongodb://host1:27017"); +settings.DirectConnection = true; +var client = new MongoClient(settings); +// end-replica-set-direct-connection-settings + From c233f4fdf521d8cd0e08b0acaf88fc8f30996a84 Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Wed, 30 Apr 2025 15:50:29 -0400 Subject: [PATCH 13/35] DOCSP-49078: Extended JSON (#619) --- source/data-formats/extended-json.txt | 82 ++++++++++++++++++- .../code-examples/ExtendedJson.cs | 42 ++++++++++ 2 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 source/includes/fundamentals/code-examples/ExtendedJson.cs diff --git a/source/data-formats/extended-json.txt b/source/data-formats/extended-json.txt index c2a69aa8..3d62ec4e 100644 --- a/source/data-formats/extended-json.txt +++ b/source/data-formats/extended-json.txt @@ -8,4 +8,84 @@ Extended JSON :local: :backlinks: none :depth: 2 - :class: singlecol \ No newline at end of file + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: code examples, bson, relaxed, canonical, legacy + +.. sharedinclude:: dbx/extended-json.rst + + .. replacement:: driver-specific-text-relaxed + + The {+driver-short+} uses Relaxed mode by default. + + +Read Extended JSON +------------------ + +You can read an Extended JSON documents into a {+language+} object by using the +``BsonSerializer.Deserialize()`` method. The following example reads an +Extended JSON document into a ``BsonDocument`` object: + +.. io-code-block:: + + .. input:: /includes/fundamentals/code-examples/ExtendedJson.cs + :language: csharp + :start-after: start-read-ejson + :end-before: end-read-ejson + :dedent: + + .. output:: + :visible: false + + { "_id" : { "$oid" : "573a1391f29313caabcd9637" }, "createdAt" : { "$date" : "1970-01-19T12:51:39.609Z" }, "numViews" : 36520312 } + +Write Extended JSON +------------------- + +You can write an Extended JSON string by calling the ``ToJson()`` method on a +``BsonDocument`` object or custom class. You must specify a ``JsonWriterSettings`` object +with the ``OutputMode`` property set to the desired Extended JSON format as a parameter. + +Consider the following custom class: + +.. literalinclude:: /includes/fundamentals/code-examples/ExtendedJson.cs + :language: csharp + :start-after: start-custom-class + :end-before: end-custom-class + +The following example outputs an instance of ``MyDocument`` in +Extended JSON format by specifying the ``CanonicalExtendedJson`` value as an ``OutputMode`` +property: + +.. io-code-block:: + + .. input:: /includes/fundamentals/code-examples/ExtendedJson.cs + :language: csharp + :start-after: start-write-ejson + :end-before: end-write-ejson + :dedent: + + .. output:: + :visible: false + + { "_id" : { "$oid" : "68094769744af81f368ff1c1" }, "CreatedAt" : { "$date" : { "$numberLong" : "1745438569994" } }, "NumViews" : { "$numberLong" : "1234567890" } } + +API Documentation +----------------- + +To learn more about the methods and classes used on this page, see the following API +documentation: + +- `BsonDocument <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonDocument.html>`__ +- `BsonSerializer <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.Serialization.BsonSerializer.html>`__ +- `ToJson() <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonExtensionMethods.ToJson.html>`__ +- `JsonWriter <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.IO.JsonWriter.html>`__ +- `JsonReader <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.IO.JsonReader.html>`__ +- `JsonWriterSettings <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.IO.JsonWriterSettings.html>`__ +- `JsonReaderSettings <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.IO.JsonReaderSettings.html>`__ +- `JsonOutputMode <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.IO.JsonOutputMode.html>`__ \ No newline at end of file diff --git a/source/includes/fundamentals/code-examples/ExtendedJson.cs b/source/includes/fundamentals/code-examples/ExtendedJson.cs new file mode 100644 index 00000000..1f0f1a8e --- /dev/null +++ b/source/includes/fundamentals/code-examples/ExtendedJson.cs @@ -0,0 +1,42 @@ +using MongoDB.Bson; +using MongoDB.Bson.IO; +using MongoDB.Bson.Serialization; + +public class ExtendedJson +{ + public static void Main(string[] args) + { + { + // start-read-ejson + var ejson = "{\n\"_id\": { \"$oid\": \"573a1391f29313caabcd9637\" },\n \"createdAt\": { \"$date\": { \"$numberLong\": \"1601499609\" }},\n\"numViews\": { \"$numberLong\": \"36520312\" }\n}\n\n"; + + var document = BsonSerializer.Deserialize(ejson); + Console.WriteLine(document.ToJson()); + // end-read-ejson + } + + { + // start-write-ejson + var document = new MyDocument(); + document.Id = ObjectId.GenerateNewId(); + document.CreatedAt = DateTime.UtcNow; + document.NumViews = 1234567890; + + var json = document.ToJson(new JsonWriterSettings + { + OutputMode = JsonOutputMode.CanonicalExtendedJson + }); + Console.WriteLine(json); + // end-write-ejson + } + } +} + +// start-custom-class +public class MyDocument +{ + public ObjectId Id { get; set; } + public DateTime CreatedAt { get; set; } + public long NumViews { get; set; } +} +// end-custom-class \ No newline at end of file From 1fe89e91b0028c173c6148eda1b237b7555bd83e Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Thu, 1 May 2025 09:04:03 -0400 Subject: [PATCH 14/35] DOCSP-49053: Standardize MongoClient page (#621) --- source/connect/mongoclient.txt | 93 +++++++++++++++++++++------------- 1 file changed, 58 insertions(+), 35 deletions(-) diff --git a/source/connect/mongoclient.txt b/source/connect/mongoclient.txt index f97f42d6..b2bdff0f 100644 --- a/source/connect/mongoclient.txt +++ b/source/connect/mongoclient.txt @@ -11,6 +11,7 @@ Create a MongoClient .. meta:: :keywords: connection string, URI, server, Atlas, settings + :description: Learn how to create a MongoClient to connect to a MongoDB deployment URI and customize connection behavior. .. contents:: On this page :local: @@ -21,20 +22,32 @@ Create a MongoClient This guide shows you how to connect to a MongoDB instance or replica set deployment by using the {+driver-short+}. -.. _csharp_connection_uri: +Overview +-------- + +Connecting to a MongoDB deployment requires the following components: + +- **Connection URI**, also known as a *connection string*, which tells the {+driver-short+} + which MongoDB deployment to connect to. +- **MongoClient** object, which creates and sustains the connection to the MongoDB deployment + and lets you perform data operations. + +You can also specify connection settings in either of these components to customize the way +the {+driver-short+} behaves while connected to MongoDB. + +This guide shows you how to create a connection URI and use a ``MongoClient`` object +to connect to MongoDB. Connection URI -------------- -A **connection URI**, also known as a *connection string*, tells the driver how to connect to a MongoDB deployment and how to behave while connected. - -A standard connection string includes the following pieces: +A standard connection URI includes the following components: .. list-table:: :widths: 20 80 :header-rows: 1 - * - Piece + * - Component - Description * - ``mongodb://`` @@ -42,20 +55,24 @@ A standard connection string includes the following pieces: - Required. A prefix that identifies this as a string in the standard connection format. - * - ``username:password@`` + * - ``username:password`` - - Optional. Authentication credentials. If you include these, the client will authenticate the user against the database specified in ``authSource``. + - Optional. Authentication credentials. If you include these, the client + authenticates the user against the database specified in ``authSource``. + For more information about authentication settings, see + :ref:`csharp-authentication-mechanisms`. * - ``host[:port]`` - - Required. The host and optional port number where MongoDB is running. If you don't include the port number, the driver will use the default port, ``27017``. + - Required. The host and optional port number where MongoDB is running. If you don't + include the port number, the driver uses the default port ``27017``. * - ``/defaultauthdb`` - Optional. The authentication database to use if the connection string includes ``username:password@`` authentication credentials but not the ``authSource`` option. If you don't include - this piece, the client will authenticate the user against the ``admin`` database. + this component, the client authenticates the user against the ``admin`` database. * - ``?`` @@ -64,37 +81,43 @@ A standard connection string includes the following pieces: :ref:`csharp-connection-options` for a full description of these options. -To use a connection URI, pass it as a string to the ``MongoClient`` constructor. In the -following example, the driver uses a sample connection URI to connect to a MongoDB -instance on port ``27017`` of ``localhost``: +For more information about creating a connection string, see +:manual:`Connection Strings ` in the +MongoDB Server documentation. + +MongoClient +----------- + +To create a connection to MongoDB, pass a connection URI to the +``MongoClient`` constructor. In the following example, the driver uses a sample +connection URI to connect to a MongoDB deployment running on port ``27017`` of ``localhost``: + +.. code-block:: csharp + + const string uri = "mongodb://localhost:27017/"; + var client = new MongoClient(uri); -.. literalinclude:: /includes/fundamentals/code-examples/connection/LocalConnection.cs - :language: csharp - :start-after: // start local connection - :end-before: // end local connection +Configure the MongoClient +------------------------- -.. tip:: Reuse Your Client +You can configure settings for the ``MongoClient`` object by passing a +``MongoClientSettings`` object to the constructor. The following example creates a +``MongoClient`` object and sets the ``UseTls`` property to ``true``: - Because each ``MongoClient`` represents a pool of connections to the - database, most applications require only a single instance of - ``MongoClient``, even across multiple requests. To learn more about - how connection pools work in the driver, see the :ref:`FAQ page - `. +.. code-block:: csharp -See :manual:`the MongoDB Manual ` for more information about creating a connection string. + var connectionString = "mongodb://localhost:27017/" + var settings = MongoClientSettings.FromConnectionString(connectionString); + settings.UseTls = true; -MongoClientSettings -------------------- +To view a full list of the settings you can configure, see the +:ref:`csharp-connection-options` guide. -You can use a ``MongoClientSettings`` object to configure the connection in code -rather than in a connection URI. To use a ``MongoClientSettings`` object, create an -instance of the class and pass it as an argument to the ``MongoClient`` constructor. +API Documentation +----------------- -In the following example, the driver uses a ``MongoClientSettings`` object to connect to a -MongoDB instance on port ``27017`` of ``localhost``: +To learn more about creating a ``MongoClient`` object with the {+driver-short+}, +see the following API documentation: -.. literalinclude:: /includes/fundamentals/code-examples/connection/MongoClientSettings.cs - :language: csharp - :dedent: - :start-after: // start mongo client settings - :end-before: // end mongo client settings +- `MongoClient <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.MongoClient.html>`__ +- `MongoClientSettings <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.MongoClientSettings.html>`__ From 92ff41255a63ed85a953cd9e36efb676f589f458 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Thu, 1 May 2025 10:25:57 -0500 Subject: [PATCH 15/35] DOCSP-49089 - Authentication (Comprehensive Coverage) (#625) --- source/security/authentication/aws-iam.txt | 6 +++--- source/security/authentication/kerberos.txt | 6 +++--- source/security/authentication/ldap.txt | 6 +++--- source/security/authentication/oidc.txt | 6 +++--- source/security/authentication/scram.txt | 6 +++--- source/security/authentication/x509.txt | 6 +++--- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/source/security/authentication/aws-iam.txt b/source/security/authentication/aws-iam.txt index 1376ce81..cc6def81 100644 --- a/source/security/authentication/aws-iam.txt +++ b/source/security/authentication/aws-iam.txt @@ -1,9 +1,9 @@ .. _csharp-mongodb-aws: .. _csharp-authentication-aws: -================================== -AWS Identity and Access Management -================================== +====================== +AWS IAM Authentication +====================== .. contents:: On this page :local: diff --git a/source/security/authentication/kerberos.txt b/source/security/authentication/kerberos.txt index 1c289266..e45af57a 100644 --- a/source/security/authentication/kerberos.txt +++ b/source/security/authentication/kerberos.txt @@ -1,9 +1,9 @@ .. _csharp-kerberos: .. _csharp-authentication-kerberos: -================= -Kerberos (GSSAPI) -================= +================================ +Kerberos (GSSAPI) Authentication +================================ .. contents:: On this page :local: diff --git a/source/security/authentication/ldap.txt b/source/security/authentication/ldap.txt index 0303356f..88d8cba8 100644 --- a/source/security/authentication/ldap.txt +++ b/source/security/authentication/ldap.txt @@ -1,9 +1,9 @@ .. _csharp-authentication-LDAP: .. _csharp-authentication-ldap: -==== -LDAP -==== +=========================== +LDAP (PLAIN) Authentication +=========================== .. contents:: On this page :local: diff --git a/source/security/authentication/oidc.txt b/source/security/authentication/oidc.txt index 66ebb19d..5f00689b 100644 --- a/source/security/authentication/oidc.txt +++ b/source/security/authentication/oidc.txt @@ -1,9 +1,9 @@ .. _csharp-mongodb-oidc: .. _csharp-authentication-oidc: -=================================== -OIDC (Workload Identity Federation) -=================================== +================================================== +OIDC (Workload Identity Federation) Authentication +================================================== .. contents:: On this page :local: diff --git a/source/security/authentication/scram.txt b/source/security/authentication/scram.txt index 64d047ad..39a48ec8 100644 --- a/source/security/authentication/scram.txt +++ b/source/security/authentication/scram.txt @@ -1,8 +1,8 @@ .. _csharp-authentication-scram: -===== -SCRAM -===== +============================================ +SCRAM-SHA-1 and SCRAM-SHA-256 Authentication +============================================ .. contents:: On this page :local: diff --git a/source/security/authentication/x509.txt b/source/security/authentication/x509.txt index 4d61fb4e..4022f3f0 100644 --- a/source/security/authentication/x509.txt +++ b/source/security/authentication/x509.txt @@ -1,8 +1,8 @@ .. _csharp-authentication-x509: -===== -X.509 -===== +============================= +X.509 Authentication with TLS +============================= .. contents:: On this page :local: From 4a6a5bc3449d471fa1f29ef022983c44dee870fa Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Thu, 1 May 2025 13:41:30 -0400 Subject: [PATCH 16/35] DOCSP-49096: Causal Consistency note (#579) --- source/crud/transactions.txt | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/source/crud/transactions.txt b/source/crud/transactions.txt index 92b22d8e..9e8102a6 100644 --- a/source/crud/transactions.txt +++ b/source/crud/transactions.txt @@ -49,6 +49,35 @@ instantiating a new client each time. ``IClientSession`` with a different ``MongoClient`` results in operation errors. +Causal Consistency +~~~~~~~~~~~~~~~~~~ + +.. sharedinclude:: dbx/causal-consistency.rst + + .. replacement:: insert-one-method + + ``InsertOne()`` + + .. replacement:: update-one-method + + ``UpdateOne()`` + + .. replacement:: find-one-method + + ``Find()`` + + .. replacement:: delete-one-method + + ``DeleteOne()`` + + .. replacement:: majority-rc + + ``ReadConcern.Majority`` + + .. replacement:: majority-wc + + ``WriteConcern.WMajority`` + Methods ------- @@ -231,3 +260,4 @@ guide, see the following API Documentation: - `CommitTransaction() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IClientSession.CommitTransaction.html>`__ / `CommitTransactionAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IClientSession.CommitTransactionAsync.html>`__ - `WithTransaction() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IClientSession.WithTransaction.html>`__ / `WithTransactionAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IClientSession.WithTransactionAsync.html>`__ - `TransactionOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.TransactionOptions.html>`__ +- `CausalConsistency <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ClientSessionOptions.CausalConsistency.html>`__ \ No newline at end of file From 137151ef3d9a37f480e0d97f246aca5e2854e5ef Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Thu, 1 May 2025 14:04:58 -0500 Subject: [PATCH 17/35] DOCSP-49082 - Indexes (Comprehensive Coverage) (#623) --- source/indexes.txt | 118 ++++++++------------------- source/reference/quick-reference.txt | 2 +- 2 files changed, 36 insertions(+), 84 deletions(-) diff --git a/source/indexes.txt b/source/indexes.txt index 62c52fe1..dbc2f98c 100644 --- a/source/indexes.txt +++ b/source/indexes.txt @@ -1,8 +1,8 @@ .. _csharp-indexes: -======= -Indexes -======= +========================= +Create and Manage Indexes +========================= .. facet:: :name: genre @@ -70,7 +70,18 @@ Index Types ----------- MongoDB provides several different index types to support querying -your data. The following sections describe the most common index types +your data. The following steps describe the process for creating an index: + +1. Use the ``IndexKeysDefinitionBuilder`` class, which you can access through the + ``Builders.IndexKeys`` property, to create one or more + ``IndexKeysDefinition`` objects. These key definitions describe the type + of index to create and the index's other properties. +#. Create a new ``CreateIndexModel`` object. Pass the key definitions from the + previous step to the constructor. +#. Call the ``CreateOne()`` method on your collection's ``Indexes`` property. Pass + the ``CreateIndexModel`` object from the previous step. + +The following sections describe the most common index types and provide sample code for creating each index type. .. note:: @@ -313,9 +324,15 @@ and :manual:`Text Indexes ` in the Server manual. Geospatial Indexes ~~~~~~~~~~~~~~~~~~ -MongoDB supports queries of geospatial coordinate data using **2dsphere -indexes**. With a 2dsphere index, you can query the geospatial data for -inclusion, intersection, and proximity. +You can query geospatial coordinate data in MongoDB by using **2d** or +**2dsphere indexes**. + +2dsphere Indexes +++++++++++++++++ + +2dsphere indexes support geospatial queries on an earth-like sphere. By using a 2dsphere +index, you can query the geospatial data For inclusion, intersection, and proximity. +The indexed field must be either GeoJSON objects or legacy coordinate pairs. To create a 2dsphere index, you must specify a field that contains only **GeoJSON objects**. For more details about this type, see :manual:`GeoJSON objects ` @@ -367,7 +384,11 @@ The following is an example of a geospatial query using the "location.geo" index :end-before: end-geospatial-query :dedent: -MongoDB also supports ``2d`` indexes for calculating distances on a Euclidean plane and +2d Indexes +++++++++++ + +The {+driver-short+} also includes a ``Geo2D`` method for creating 2d indexes. +You can use these indexes to calculate distances on a Euclidean plane and for working with the "legacy coordinate pairs" syntax used in MongoDB 2.2 and earlier. To learn more, see :manual:`Geospatial Queries ` in the Server manual. @@ -433,81 +454,12 @@ all indexes in a collection: :end-before: end-list-indexes :dedent: -.. TODO: integrate into existing page - -Sample Class ------------- - -The code examples in this guide demonstrate how you can use builders to -create types to interact with documents in the sample collection ``plants.flowers``. -Documents in this collection are modeled by the following ``Flower`` class: - -.. literalinclude:: /includes/fundamentals/code-examples/builders.cs - :language: csharp - :dedent: - :start-after: start-model - :end-before: end-model - -Each builder class takes a generic type parameter -``TDocument`` which represents the type of document that you are working -with. In this guide, the ``Flower`` class is the document type used in -each builder class example. - -.. _csharp-builders-indexes: - -Define Index Keys ------------------ - -The ``IndexKeysDefinitionBuilder`` class provides a type-safe interface for -defining index keys. Suppose you want to select ``Category`` as an -ascending index key. - -Use builders to select the index key with the typed variant: - -.. code-block:: csharp - :copyable: true - - var builder = Builders.IndexKeys; - var keys = builder.Ascending(f => f.Category); - -Alternatively, you can use string-based field names to select the index key: - -.. code-block:: csharp - :copyable: true - - var builder = Builders.IndexKeys; - var keys = builder.Ascending("Category"); - -The ``IndexKeysDefinitionBuilder`` class also provides methods to build -a wildcard index. You can create a wildcard index using ``All field paths`` or ``A -single field path``, in this case using ``Category``: - -.. tabs:: - - .. tab:: ``All field paths`` - :tabid: all-wildcard-index - - .. code-block:: csharp - :copyable: true - - var builder = Builders.IndexKeys; - var keys = builder.Wildcard(); - - .. tab:: ``A single field path`` - :tabid: single-wildcard-index - - .. code-block:: csharp - :copyable: true - - var builder = Builders.IndexKeys; - - // Using the typed variant - var keys = builder.Wildcard(f => f.Category); - - // Using string-based field names - var keys = builder.Wildcard("Category"); +Additional Information +---------------------- -For more information about how to use wildcard indexes, see -:manual:`Wildcard Indexes `. +For more information about the classes and methods used on this page, see the following +API documentation: +- `CreateOne() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoIndexManager-1.CreateOne.html>`__ +- `CreateIndexModel <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.CreateIndexModel-1.html>`__ - `IndexKeysDefinitionBuilder <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IndexKeysDefinitionBuilder-1.html>`__ \ No newline at end of file diff --git a/source/reference/quick-reference.txt b/source/reference/quick-reference.txt index 8b03bd9e..3e81573a 100644 --- a/source/reference/quick-reference.txt +++ b/source/reference/quick-reference.txt @@ -561,7 +561,7 @@ their related reference and API documentation. * - | **Create an Index** | | `API Documentation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoIndexManager-1.CreateOne.html>`__ - | :ref:`Fundamentals ` + | :ref:`Fundamentals ` - .. code-block:: csharp :copyable: true From 60e0cca061b6764fe5a6f102103df1014f497506 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Thu, 8 May 2025 08:36:45 -0500 Subject: [PATCH 18/35] DOCSP-49811 - ClientSessionOptions (#627) --- source/crud/transactions.txt | 87 +++++++++++++++++++++++++++++++----- 1 file changed, 77 insertions(+), 10 deletions(-) diff --git a/source/crud/transactions.txt b/source/crud/transactions.txt index 9e8102a6..f9049a47 100644 --- a/source/crud/transactions.txt +++ b/source/crud/transactions.txt @@ -1,15 +1,15 @@ .. _csharp-transactions: -============ -Transactions -============ +================================ +Batch Operations in Transactions +================================ .. facet:: :name: genre :values: reference .. meta:: - :keywords: code example, multi-document + :keywords: code example, multi-document, atomic, acid .. contents:: On this page :local: @@ -27,21 +27,33 @@ transaction is committed. If any operation in the transaction returns an error, the driver cancels the transaction and discards all data changes before they ever become visible. +MongoDB guarantees that the data involved in your transaction operations remains +consistent, even if the operations encounter unexpected errors. + +Sessions +-------- + In MongoDB, transactions run within logical **sessions**. A :manual:`session ` is a grouping of related read or write operations that you intend to run sequentially. Sessions -enable :manual:`causal consistency -` for a +enable causal consistency for a group of operations or allow you to execute operations in an -:website:`ACID transaction `. MongoDB -guarantees that the data involved in your transaction operations remains -consistent, even if the operations encounter unexpected errors. +:website:`ACID transaction `. When using the {+driver-short+}, you can create a new session from a ``MongoClient`` instance as an ``IClientSession`` type. We recommend that you reuse your client for multiple sessions and transactions instead of instantiating a new client each time. +The following example shows how to create a session by calling the ``StartSession()`` +method: + +.. code-block:: csharp + :copyable: true + + var client = new MongoClient("mongodb://localhost:27017"); + var session = client.StartSession(); + .. warning:: Use an ``IClientSession`` only with the ``MongoClient`` (or associated @@ -49,6 +61,61 @@ instantiating a new client each time. ``IClientSession`` with a different ``MongoClient`` results in operation errors. +ClientSessionOptions +~~~~~~~~~~~~~~~~~~~~ + +You can customize the behavior of your session by passing an instance of the +``ClientSessionOptions`` class to the ``StartSession()`` method. The following table +describes the properties that you can set on a ``ClientSessionOptions`` object: + +.. list-table:: + :widths: 35 65 + :header-rows: 1 + + * - Property + - Description + + * - ``CausalConsistency`` + - | Specifies whether the session is causally consistent. In a causally consistent session, + the driver executes operations in the order they were issued. To learn more, see + :ref:``. + | + | **Data Type**: {+bool-data-type+} + | **Default**: ``true`` + + * - ``DefaultTransactionOptions`` + - | Specifies the default transaction options for the session. This includes the maximum commit + time, read concern, read preference, and write concern. + | + | **Data Type**: `TransactionOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.TransactionOptions.html>`__ + | **Default**: ``null`` + + * - ``Snapshot`` + - | Specifies whether the driver performs snapshot reads. To learn more about snapshot + reads, see :manual:`Read Concern "snapshot" ` + in the {+mdb-server+} manual. + | + | **Data Type**: {+bool-data-type+} + | **Default**: ``false`` + +The following code example shows how to create a session with custom options: + +.. code-block:: csharp + :copyable: true + + var client = new MongoClient("mongodb://localhost:27017"); + var sessionOptions = new ClientSessionOptions + { + CausalConsistency = true, + DefaultTransactionOptions = new TransactionOptions( + readConcern: ReadConcern.Available, + writeConcern: WriteConcern.Acknowledged) + }; + + var session = client.StartSession(sessionOptions); + +.. _csharp-causal-consistency: + Causal Consistency ~~~~~~~~~~~~~~~~~~ @@ -94,7 +161,7 @@ tabs to learn about the methods to manage your transaction: :tabid: synchronous-methods .. list-table:: - :widths: 40 60 + :widths: 30 70 :header-rows: 1 * - Method From 502746c15e8749c983f558f0fe8200315a168022 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Thu, 8 May 2025 08:37:27 -0500 Subject: [PATCH 19/35] DOCSP-49061 - Query filters (Comprehensive Coverage) (#620) --- config/redirects | 3 +- source/crud/query.txt | 2 +- source/crud/query/query-filter.txt | 633 ++++++++++++++++++ source/crud/query/specify-query.txt | 436 ------------ .../specify-query/FindAndBuilder.cs | 2 +- .../specify-query/FindAndPOCO.cs | 2 +- .../specify-query/FindEqBuilder.cs | 2 +- .../code-examples/specify-query/FindEqPOCO.cs | 2 +- .../specify-query/FindExistsBuilder.cs | 2 +- .../specify-query/FindGtBuilder.cs | 2 +- .../code-examples/specify-query/FindGtPOCO.cs | 4 +- .../specify-query/FindRegexBuilder.cs | 2 +- .../specify-query/FindSizeBuilder.cs | 2 +- source/reference/compatibility.txt | 4 +- 14 files changed, 648 insertions(+), 450 deletions(-) create mode 100644 source/crud/query/query-filter.txt delete mode 100644 source/crud/query/specify-query.txt diff --git a/config/redirects b/config/redirects index b593fff5..0f70d847 100644 --- a/config/redirects +++ b/config/redirects @@ -93,4 +93,5 @@ raw: ${prefix}/master -> ${base}/upcoming/ [*-master]: ${prefix}/${version}/fundamentals/authentication/ldap/ -> ${base}/${version}/security/authentication/ldap/ [*-master]: ${prefix}/${version}/fundamentals/authentication/oidc/ -> ${base}/${version}/security/authentication/oidc/ [*-master]: ${prefix}/${version}/fundamentals/authentication/scram/ -> ${base}/${version}/security/authentication/scram/ -[*-master]: ${prefix}/${version}/fundamentals/authentication/x509/ -> ${base}/${version}/security/authentication/x509/ \ No newline at end of file +[*-master]: ${prefix}/${version}/fundamentals/authentication/x509/ -> ${base}/${version}/security/authentication/x509/ +[*-master]: ${prefix}/${version}/crud/query/specify-query/ -> ${base}/${version}/crud/query/query-filter/ \ No newline at end of file diff --git a/source/crud/query.txt b/source/crud/query.txt index 93468c74..e5f07bf7 100644 --- a/source/crud/query.txt +++ b/source/crud/query.txt @@ -12,7 +12,7 @@ Read Operations :titlesonly: :maxdepth: 1 - Specify a Query + Specify a Query Find Documents Specify Documents to Return Specify Fields to Return diff --git a/source/crud/query/query-filter.txt b/source/crud/query/query-filter.txt new file mode 100644 index 00000000..d409d099 --- /dev/null +++ b/source/crud/query/query-filter.txt @@ -0,0 +1,633 @@ +.. _csharp-specify-query: +.. _csharp-create-query-filter: + +===================== +Create a Query Filter +===================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 1 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: search, read, update, delete + +Overview +-------- + +In this guide, you can learn how to use the {+driver-long+} to create a **query filter**. +A query filter is an expression that specifies the documents to read, update, or delete +in a CRUD operation. You can use builder methods, available from the +``Builders.Filter`` static property, to create query filters and add +operations to them. + +.. include:: /includes/method-overloads.rst + +Sample Data +~~~~~~~~~~~ + +The examples in this guide use the following documents in a collection called +``guitars``: + +.. code-block:: json + + { "_id": 1, "make": "Fender", "models": ["Stratocaster", "Telecaster"], "establishedYear": 1946, "rating": 9 } + { "_id": 2, "make": "Gibson", "models": ["Les Paul", "SG", "Explorer"], "establishedYear": 1902, "rating": 8 } + { "_id": 3, "make": "PRS", "models": ["Silver Sky", "SE", "Custom"], "establishedYear": 1985, "rating": 9 } + { "_id": 4, "make": "Kiesel", "models": ["Ares", "Vader", "Solo"], "establishedYear": 2015 } + { "_id": 5, "make": "Ibanez", "models": ["RG", "AZ"], "establishedYear": 1957, "rating": 7 } + { "_id": 6, "make": "Strandberg", "models": ["Boden", "Salen"], "establishedYear": 1982 } + +The following ``Guitar`` class models the documents in this collection: + +.. literalinclude:: /includes/fundamentals/code-examples/specify-query/Guitar.cs + :language: csharp + :copyable: + :dedent: + +To run the code examples on this page, you must obtain a reference to the ``guitars`` +collection, as shown in the following example: + +.. code-block:: csharp + + var client = new MongoClient("localhost://27017"); + var guitarCollection = client.GetDatabase("example").GetCollection("guitars"); + +.. note:: + + The documents in the ``guitars`` collection use the camel-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 ``Guitar`` class. + + To learn more creating and serializing custom classes, see the following pages: + + - :ref:`csharp-poco` + - :ref:`csharp-class-mapping` + - :ref:`csharp-serialization` + - :ref:`csharp-polymorphism` + +Find All Documents +------------------ + +An empty query filter matches all documents in a collection. The following example shows +how to create an empty query filter: + +.. code-block:: csharp + + var filter = Builders.Filter.Empty; + +Comparison Operators +-------------------- + +Comparison operators compare the query value to the value in a specified field. Some of +these methods have alternative syntax that you can use in place of the method, as shown +in the following example: + +.. code-block:: csharp + + var filter = Builders.Filter.Eq(g => g.Make, "Fender"); + var results = guitarCollection.Find(filter).ToList(); + + // Alternative syntax + var results = guitarCollection.Find(g => g.Make == "Fender").ToList();; + +The following table lists the {+driver-short+} methods for comparison operations +and the equivalent {+mdb-server+} operators: + +.. list-table:: + :widths: 20 20 40 20 + :header-rows: 1 + + * - {+driver-short+} Method + - Alternative Syntax + - Description + - {+mdb-server+} Operator + + * - ``Eq()`` + - ``==`` + - Matches documents where the value of the specified field is equal to the query value. + - :manual:`$eq ` + + * - ``Gt()`` + - ``>`` + - Matches documents where the value of the specified field is greater than the query value. + - :manual:`$gt ` + + * - ``Gte()`` + - ``>=`` + - Matches documents where any element in the specified array field is greater than or + equal to the query value. + - :manual:`$gte ` + + * - ``In()`` + - N/A + - Matches documents where any element in the specified array field matches any value in + the query array. + - :manual:`$in ` + + * - ``Lt()`` + - ``<`` + - Matches documents where any element in the specified array field is less than the + query value. + - :manual:`$lt ` + + * - ``Lte()`` + - ``<=`` + - Matches documents where any element in the specified array field is less than or equal + to the query value. + - :manual:`$lte ` + + * - ``Ne()`` + - ``!=`` + - Matches documents where any element in the specified array field is not equal to + the query value. + - :manual:`$ne ` + + * - ``Nin()`` + - N/A + - Matches documents where one of the following is true: + + - None of the elements in the specified array field matches any of the values in the + query array. + - The specified field doesn't exist. + - :manual:`$nin ` + + * - ``StringIn()`` + - N/A + - Matches documents where the string value of the specified field matches any string + value in the query array. + - :manual:`$in ` + + * - ``StringNin()`` + - N/A + - Matches documents where the string value of the specified field doesn't match any + of the string values in the query array. + - :manual:`$in ` + +The following example calls the ``Find()`` method and passes a lambda filter, which +the driver translates to a query filter. The query matches all documents where the +``establishedYear`` field is greater than ``1985``. + +.. io-code-block:: + :copyable: + + .. input:: /includes/fundamentals/code-examples/specify-query/FindGtPOCO.cs + :language: csharp + + .. output:: + :language: json + :visible: false + + { "_id" : 4, "make" : "Kiesel", "models" : ["Ares", "Vader", "Solo"], "establishedYear" : 2015, "rating" : null } + +The following example uses builders to create a query filter that matches the +same documents as the preceding example: + +.. io-code-block:: + :copyable: + + .. input:: /includes/fundamentals/code-examples/specify-query/FindGtBuilder.cs + :language: csharp + + .. output:: + :language: json + :visible: false + + { "_id" : 4, "make" : "Kiesel", "models" : ["Ares", "Vader", "Solo"], "establishedYear" : 2015, "rating" : null } + +The following example calls the ``Find()`` method and passes a lambda expression, which +the driver translates to a query filter. The query matches all documents where the +``make`` field equals "Fender". + +.. io-code-block:: + :copyable: + + .. input:: /includes/fundamentals/code-examples/specify-query/FindEqPOCO.cs + :language: csharp + + .. output:: + :language: json + :visible: false + + { "_id" : 1, "make" : "Fender", "models" : ["Stratocaster", "Telecaster"], "establishedYear" : 1946, "rating" : 9 } + +The following example uses builders to create a query filter that matches the +same documents as the preceding example: + +.. io-code-block:: + :copyable: + + .. input:: /includes/fundamentals/code-examples/specify-query/FindEqBuilder.cs + :language: csharp + + .. output:: + :language: json + :visible: false + + { "_id" : 1, "make" : "Fender", "models" : ["Stratocaster", "Telecaster"], "establishedYear" : 1946, "rating" : 9 } + +Logical Operators +----------------- + +Logical operators combine two or more expressions and return results based on the results +of those expressions. These methods have alternative syntax that you can use in place of +the method, as shown in the following example: + +.. code-block:: csharp + + var builder = Builders.Filter; + var filter = builder.And( + builder.Gte(g => g.EstablishedYear, 1985), + builder.Ne(r => r.Make, "Kiesel")); + + var results = guitarCollection.Find(filter).ToList(); + + // Alternative syntax + var results = guitarCollection.Find( + g => g.EstablishedYear >= 1985 + && g.Make != "Kiesel") + .ToList(); + +The following table lists the {+driver-short+} methods for logical operations +and the equivalent {+mdb-server+} operators: + +.. list-table:: + :widths: 20 20 40 20 + :header-rows: 1 + + * - {+driver-short+} Method + - Alternative Syntax + - Description + - {+mdb-server+} Operator + + * - ``And()`` + - ``&&`` + - Matches documents where all expressions evaluate to true. + - :manual:`$and ` + + * - ``Or()`` + - ``||`` + - Matches documents where one or more expressions evaluates to true. + - :manual:`$or ` + +The following example calls the ``Find()`` method and passes a lambda expression, +which the driver translates to a query filter. The query matches all documents where the +``establishedYear`` field is greater than or equal to ``1985``, and the ``make`` +field is not equal to "Kiesel". + +.. io-code-block:: + :copyable: + + .. input:: /includes/fundamentals/code-examples/specify-query/FindAndPOCO.cs + :language: csharp + + .. output:: + :language: json + :visible: false + + { "_id" : 3, "make" : "PRS", "models" : ["Silver Sky", "SE", "Custom"], "establishedYear" : 1985, "rating" : 9 } + +The following example uses builders to create a query filter that matches the +same documents as the preceding example: + +.. io-code-block:: + :copyable: + + .. input:: /includes/fundamentals/code-examples/specify-query/FindAndBuilder.cs + :language: csharp + + .. output:: + :language: json + :visible: false + + { "_id" : 3, "make" : "PRS", "models" : ["Silver Sky", "SE", "Custom"], "establishedYear" : 1985, "rating" : 9 } + +Array Operators +--------------- + +Array operators match documents based on the value or quantity of elements in an array +field. The following table lists the {+driver-short+} methods for array operations +and the equivalent {+mdb-server+} operators: + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - {+driver-short+} Method + - Description + - {+mdb-server+} Operator + + * - ``All()`` + - Matches documents where the values in the specified array field match all query + values. + - :manual:`$all ` + + * - ``AnyEq()`` + - Matches documents where any element in the specified array field matches the + query value. + - :manual:`$elemMatch ` + + * - ``AnyGt()`` + - Matches documents where any element in the specified array field is greater than the + query value. + - :manual:`$elemMatch ` + + * - ``AnyGte()`` + - Matches documents where any element in the specified array field is greater than or + equal to the query value. + - :manual:`$elemMatch ` + + * - ``AnyIn()`` + - Matches documents where any element in the specified array field matches any value in + the query array. + - :manual:`$elemMatch ` + + * - ``AnyLt()`` + - Matches documents where any element in the specified array field is less than the + query value. + - :manual:`$elemMatch ` + + * - ``AnyLte()`` + - Matches documents where any element in the specified array field is less than or + equal to the query value. + - :manual:`$elemMatch ` + + * - ``AnyNe()`` + - Matches documents where any element in the specified array field is not equal to + the query value. + - :manual:`$elemMatch ` + + * - ``AnyNin()`` + - Matches documents where one of the following is true: + + - Any element in the specified array field isn't in the query array. + - The specified field doesn't exist. + - :manual:`$elemMatch ` + + * - ``AnyStringIn()`` + - Matches documents where any string element in the specified array field matches any + string value in the query array. + - :manual:`$elemMatch ` + + * - ``AnyStringNin()`` + - Matches documents where one of the following is true: + + - Any string element in the specified array field isn't in the query array. + - The specified field doesn't exist. + - :manual:`$elemMatch ` + + * - ``ElemMatch()`` + - Matches documents where any element in the specified array field matches the + query criteria. + - :manual:`$elemMatch ` + + * - ``Size()`` + - Matches documents where the specified array field is the specified size. + - :manual:`$size ` + + * - ``SizeGt()`` + - Matches documents where the specified array field is larger than the specified size. + - :manual:`$size ` + + * - ``SizeGte()`` + - Matches documents where the specified array field is larger than or equal to the + specified size. + - :manual:`$size ` + + * - ``SizeLt()`` + - Matches documents where the specified array field is smaller than the specified size. + - :manual:`$size ` + + * - ``SizeLte()`` + - Matches documents where the specified array field is smaller than or equal to the + specified size. + - :manual:`$size ` + +The following example uses builders to create a query filter that matches all +documents that have exactly three elements in the ``models`` field: + +.. io-code-block:: + :copyable: + + .. input:: /includes/fundamentals/code-examples/specify-query/FindSizeBuilder.cs + :language: csharp + + .. output:: + :language: json + :visible: false + + { "_id" : 2, "make" : "Gibson", "models" : ["Les Paul", "SG", "Explorer"], "establishedYear" : 1902, "rating" : 8 } + { "_id" : 3, "make" : "PRS", "models" : ["Silver Sky", "SE", "Custom"], "establishedYear" : 1985, "rating" : 9 } + { "_id" : 4, "make" : "Kiesel", "models" : ["Ares", "Vader", "Solo"], "establishedYear" : 2015, "rating" : null } + +Element Operators +----------------- + +Element operators match document query data based on the presence or type of a field. +The following table lists the {+driver-short+} methods for element operations +and the equivalent {+mdb-server+} operators: + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - {+driver-short+} Method + - Description + - {+mdb-server+} Operator + + * - ``Exists()`` + - Matches documents that contain or don't contain a specified field, including + documents where the field value is ``null``. + - :manual:`$exists ` + + * - ``Type()`` + - Matches documents where the value of the specified field is an instance of the + specified BSON types. + - :manual:`$type ` + +The following example uses builders to create a query filter that matches all +documents that have a ``rating`` field: + +.. io-code-block:: + :copyable: + + .. input:: /includes/fundamentals/code-examples/specify-query/FindExistsBuilder.cs + :language: csharp + + .. output:: + :language: json + :visible: false + + { "_id" : 1, "make" : "Fender", "models" : ["Stratocaster", "Telecaster"], "establishedYear" : 1946, "rating" : 9 } + { "_id" : 2, "make" : "Gibson", "models" : ["Les Paul", "SG", "Explorer"], "establishedYear" : 1902, "rating" : 8 } + { "_id" : 3, "make" : "PRS", "models" : ["Silver Sky", "SE", "Custom"], "establishedYear" : 1985, "rating" : 9 } + { "_id" : 5, "make" : "Ibanez", "models" : ["RG", "AZ"], "establishedYear" : 1957, "rating" : 7 } + +Evaluation Operators +-------------------- + +Evaluation operators analyze data in individual fields or all documents in the collection. +The following table lists the {+driver-short+} methods for +evaluation operations and the equivalent {+mdb-server+} operators: + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - {+driver-short+} Method + - Description + - {+mdb-server+} Operator + + * - ``JsonSchema()`` + - Matches documents that satisfy the specified JSON schema. + - :manual:`$jsonSchema ` + + * - ``Mod()`` + - Matches documents where the value of the specified field divided by a divisor has the + specified remainder (modulo). + - :manual:`$mod ` + + * - ``RegEx()`` + - Matches documents where the value of the specified field matches a specified regular + expression. + - :manual:`$regex ` + + * - ``Where()`` + - Use to pass either a string containing a JavaScript expression or a full JavaScript + function to the query system. + - :manual:`$where ` + +The following example uses builders to create a query filter that matches all +documents that have a value in the ``make`` field that starts with the letter +"G": + +.. io-code-block:: + :copyable: + + .. input:: /includes/fundamentals/code-examples/specify-query/FindRegexBuilder.cs + :language: csharp + + .. output:: + :language: json + :visible: false + + { "_id" : 2, "make" : "Gibson", "models" : ["Les Paul", "SG", "Explorer"], "establishedYear" : 1902, "rating" : 8 } + +Geospatial Operators +-------------------- + +Geospatial operators return data based on geospatial expression conditions. +The following table lists the {+driver-short+} methods for +geospatial operations and the equivalent {+mdb-server+} operators: + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - {+driver-short+} Method + - Description + - {+mdb-server+} Operator + + * - ``GeoIntersects()`` + - Matches documents whose geospatial data intersects with a specified + `GeoJsonObject <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.GeoJsonObjectModel.GeoJsonObject-1.html>`__. + - :manual:`$geoIntersects ` + + * - ``GeoWithin()`` + - Matches documents whose geospatial data is entirely within the specified shape. + - :manual:`$geoWithin ` + + * - ``GeoWithinBox()`` + - Matches documents whose geospatial data is entirely within the specified box. + - :manual:`$geoWithin `, :manual:`$box ` + + * - ``GeoWithinCenter()`` + - Matches documents whose geospatial data is entirely within the specified circle. + - :manual:`$geoWithin `, :manual:`$center ` + + * - ``GeoWithinCenterSphere()`` + - Matches documents whose geospatial data is entirely within the specified sphere. + - :manual:`$geoWithin `, :manual:`$centerSphere ` + + * - ``GeoWithinPolygon()`` + - Matches documents whose geospatial data is entirely within the specified polygon. + - :manual:`$geoWithin `, :manual:`$polygon ` + + * - ``Near()`` + - Specifies a point for which a geospatial query returns the documents from nearest to + farthest. + - :manual:`$near ` + + * - ``NearSphere()`` + - Specifies a point for which a geospatial query returns the documents from nearest to + farthest in spherical geometry. + - :manual:`$nearSphere ` + +Bitwise Operators +----------------- + +Bitwise operators matches documents based on bit-position conditions. +The following table lists the {+driver-short+} methods for +bitwise operations and the equivalent {+mdb-server+} operators: + +.. list-table:: + :widths: 20 60 20 + :header-rows: 1 + + * - {+driver-short+} Method + - Description + - {+mdb-server+} Operator + + * - ``BitsAllClear()`` + - Matches documents where all of the specified bit positions are clear (``0``) in + the specified field. + - :manual:`$bitsAllClear ` + + * - ``BitsAllSet()`` + - Matches documents where all of the specified bit positions are set (``1``) in + the specified field. + - :manual:`$bitsAllSet ` + + * - ``BitsAnyClear()`` + - Matches documents where any of the specified bit positions are clear (``0``) in + the specified field. + - :manual:`$bitsAnyClear ` + + * - ``BitsAnySet()`` + - Matches documents where any of the specified bit positions are set (``1``) in + the specified field. + - :manual:`$bitsAnySet ` + +Other Operators +--------------- + +The {+driver-short+} also provides the following methods that create filter definitions: + +.. list-table:: + :widths: 40 60 + :header-rows: 1 + + * - {+driver-short+} Method + - Description + + * - ``OfType()`` + - Matches documents of a type derived from the specified type. You can use overloads + of this method to specify additional query criteria. + + * - ``Text()`` + - Matches documents with a field that contains the specified string. + +Additional Information +---------------------- + +For more information about any of the driver methods on this page, see the +API documentation for the +`FilterDefinitionBuilder <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.FilterDefinitionBuilder-1.html>`__ +class. \ No newline at end of file diff --git a/source/crud/query/specify-query.txt b/source/crud/query/specify-query.txt deleted file mode 100644 index bf508679..00000000 --- a/source/crud/query/specify-query.txt +++ /dev/null @@ -1,436 +0,0 @@ -.. _csharp-specify-query: - -=============== -Specify a Query -=============== - -.. contents:: On this page - :local: - :backlinks: none - :depth: 1 - :class: singlecol - -Overview --------- - -In this guide, you can learn how to specify a query using the {+driver-long+}. - -You can narrow the set of matched documents returned by your query by creating a -**query filter**. A query filter is an expression that specifies the documents you -want to match in a read, update, or delete operation. - -.. note:: Using LINQ - - This guide shows how to specify queries using query filters. You can also - specify queries using LINQ. To learn more about using LINQ, see - :ref:`csharp-linq`. - -The examples in this guide use the following documents in a collection called -``guitars``: - -.. code-block:: json - - { "_id": 1, "make": "Fender", "models": ["Stratocaster", "Telecaster"], "establishedYear": 1946, "rating": 9 } - { "_id": 2, "make": "Gibson", "models": ["Les Paul", "SG", "Explorer"], "establishedYear": 1902, "rating": 8 } - { "_id": 3, "make": "PRS", "models": ["Silver Sky", "SE", "Custom"], "establishedYear": 1985, "rating": 9 } - { "_id": 4, "make": "Kiesel", "models": ["Ares", "Vader", "Solo"], "establishedYear": 2015 } - { "_id": 5, "make": "Ibanez", "models": ["RG", "AZ"], "establishedYear": 1957, "rating": 7 } - { "_id": 6, "make": "Strandberg", "models": ["Boden", "Salen"], "establishedYear": 1982 } - -The following ``Guitar`` class models the documents in this collection. - -.. literalinclude:: /includes/fundamentals/code-examples/specify-query/Guitar.cs - :language: csharp - :copyable: - :dedent: - -.. note:: - - The documents in the ``guitars`` collection use the camel-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 ``Guitar`` class. - - To learn more about custom serialization, see :ref:`csharp-custom-serialization`. - -To learn more about class mapping, see :ref:`csharp-class-mapping`. - -The following code instantiates the ``_guitarsCollection`` object using the -``Guitar`` class as a type parameter. This type parameter causes the driver to -automatically serialize and deserialize the documents it sends to and receives -from MongoDB to instances of the ``Guitar`` class: - -.. code-block:: csharp - - private static IMongoCollection _guitarsCollection; - -Literal Values --------------- - -Literal value queries return documents with an exact match to your query filter. - -The following example specifies a query filter as a parameter to the ``Find()`` -method. The query matches all documents where the -``make`` field equals "Fender". - -.. io-code-block:: - :copyable: - - .. input:: /includes/fundamentals/code-examples/specify-query/FindEqPOCO.cs - :language: csharp - - .. output:: - :language: json - :visible: - - { "_id" : 1, "make" : "Fender", "models" : ["Stratocaster", "Telecaster"], "establishedYear" : 1946, "rating" : 9 } - -The following example uses builders to create a query filter that matches the -same documents as the preceding example: - -.. io-code-block:: - :copyable: - - .. input:: /includes/fundamentals/code-examples/specify-query/FindEqBuilder.cs - :language: csharp - - .. output:: - :language: json - :visible: - - { "_id" : 1, "make" : "Fender", "models" : ["Stratocaster", "Telecaster"], "establishedYear" : 1946, "rating" : 9 } - -.. tip:: Find All Documents - - Use an empty query filter to match all documents in the collection. Create - an empty query filter with builders as follows: - - .. code-block:: csharp - - var result = _guitarsCollection.Find(Builders.Filter.Empty).ToList(); - -Comparison Operators --------------------- - -Comparison operators analyze the value in a document against the specified value -in your query filter. Common comparison operators include: - -.. list-table:: - :widths: 30 30 40 - :header-rows: 1 - - * - Operator - - Builder - - Description - - * - ``>`` - - ``Gt()`` - - Greater than - - * - ``<=`` - - ``Lte()`` - - Less than or equal to - - * - ``!=`` - - ``Ne()`` - - Not equal to - -For a full list of comparison operators, see the :manual:`Comparison -Query Operators ` page. - -The following example specifies a query filter as a parameter to the ``Find()`` -method. The query matches all documents where the ``establishedYear`` field is -greater than ``1985``. - -.. io-code-block:: - :copyable: - - .. input:: /includes/fundamentals/code-examples/specify-query/FindGtPOCO.cs - :language: csharp - - .. output:: - :language: json - :visible: - - { "_id" : 4, "make" : "Kiesel", "models" : ["Ares", "Vader", "Solo"], "establishedYear" : 2015, "rating" : null } - -The following example uses builders to create a query filter that matches the -same documents as the preceding example: - -.. io-code-block:: - :copyable: - - .. input:: /includes/fundamentals/code-examples/specify-query/FindGtBuilder.cs - :language: csharp - - .. output:: - :language: json - :visible: - - { "_id" : 4, "make" : "Kiesel", "models" : ["Ares", "Vader", "Solo"], "establishedYear" : 2015, "rating" : null } - -Logical Operators ------------------ - -Logical operators match documents using logic applied to the results of two or more -sets of expressions. The following is a list of some logical operators: - -.. list-table:: - :widths: 30 30 40 - :header-rows: 1 - - * - Operator - - Builder - - Description - - * - ``&&`` - - ``And()`` - - All expressions must evaluate to true. - - * - ``||`` - - ``Or()`` - - At least one expression must evaluate to true. - -For a full list of logical operators, see the :manual:`Logical -Query Operators ` page. - -The following example specifies a query filter as a parameter to the ``Find()`` -method. The query matches all documents where the -``establishedYear`` field is greater than or equal to ``1985``, and the ``make`` -field is not equal to "Kiesel". - -.. io-code-block:: - :copyable: - - .. input:: /includes/fundamentals/code-examples/specify-query/FindAndPOCO.cs - :language: csharp - - .. output:: - :language: json - :visible: - - { "_id" : 3, "make" : "PRS", "models" : ["Silver Sky", "SE", "Custom"], "establishedYear" : 1985, "rating" : 9 } - - -The following example uses builders to create a query filter that matches the -same documents as the preceding example: - -.. io-code-block:: - :copyable: - - .. input:: /includes/fundamentals/code-examples/specify-query/FindAndBuilder.cs - :language: csharp - - .. output:: - :language: json - :visible: - - { "_id" : 3, "make" : "PRS", "models" : ["Silver Sky", "SE", "Custom"], "establishedYear" : 1985, "rating" : 9 } - -Array Operators ---------------- - -Array operators match documents based on the value or quantity of elements in an array -field. The following is a list of builder methods that use array operators: - -.. list-table:: - :widths: 40 60 - :header-rows: 1 - - * - Operator - - Description - - * - ``All()`` - - Matches documents if the array field contains all elements specified in - the query. - - * - ``Any()`` - - Matches documents if any element in the array field matches the specified - query filter. - - * - ``Size()`` - - Matches documents if the array field is a specified size. - -.. note:: - - The ``Any()`` builder uses the ``$elemMatch`` query operator. - - To learn more about the ``$elemMatch`` query selector, see - :manual:`$elemMatch `. - -For more information on the array operators, see the :manual:`Array -Query Operators ` page. - -The following example uses builders to create a query filter that matches all -documents that have 3 elements in the ``models`` field: - -.. io-code-block:: - :copyable: - - .. input:: /includes/fundamentals/code-examples/specify-query/FindSizeBuilder.cs - :language: csharp - - .. output:: - :language: json - :visible: - - { "_id" : 2, "make" : "Gibson", "models" : ["Les Paul", "SG", "Explorer"], "establishedYear" : 1902, "rating" : 8 } - { "_id" : 3, "make" : "PRS", "models" : ["Silver Sky", "SE", "Custom"], "establishedYear" : 1985, "rating" : 9 } - { "_id" : 4, "make" : "Kiesel", "models" : ["Ares", "Vader", "Solo"], "establishedYear" : 2015, "rating" : null } - -Element Operators ------------------ - -Element operators query data based on the presence or type of a field. - -For a full list of element operators, see the :manual:`Element -Query Operators ` page. - -The following example uses builders to create a query filter that matches all -documents that have a ``rating`` field: - -.. io-code-block:: - :copyable: - - .. input:: /includes/fundamentals/code-examples/specify-query/FindExistsBuilder.cs - :language: csharp - - .. output:: - :language: json - :visible: - - { "_id" : 1, "make" : "Fender", "models" : ["Stratocaster", "Telecaster"], "establishedYear" : 1946, "rating" : 9 } - { "_id" : 2, "make" : "Gibson", "models" : ["Les Paul", "SG", "Explorer"], "establishedYear" : 1902, "rating" : 8 } - { "_id" : 3, "make" : "PRS", "models" : ["Silver Sky", "SE", "Custom"], "establishedYear" : 1985, "rating" : 9 } - { "_id" : 5, "make" : "Ibanez", "models" : ["RG", "AZ"], "establishedYear" : 1957, "rating" : 7 } - -Evaluation Operators --------------------- - -Evaluation operators analyze data on individual fields, or on the entire collection's -documents. Some builder methods that use evaluation operators include ``Regex()`` -and ``Text()``. - -For a full list of evaluation operators, see the :manual:`Evaluation -Query Operators ` page. - -The following example uses builders to create a query filter that matches all -documents that have a value in the ``make`` field that starts with the letter -"G": - -.. io-code-block:: - :copyable: - - .. input:: /includes/fundamentals/code-examples/specify-query/FindRegexBuilder.cs - :language: csharp - - .. output:: - :language: json - :visible: - - { "_id" : 2, "make" : "Gibson", "models" : ["Les Paul", "SG", "Explorer"], "establishedYear" : 1902, "rating" : 8 } - -Additional Information ----------------------- - -For more information about the operators mentioned in this guide, see the -following Server Manual Entries: - -- :manual:`Comparison Query Operators ` -- :manual:`Logical Query Operators ` -- :manual:`Array Query Operators ` -- :manual:`Element Query Operators ` -- :manual:`Evaluation Query Operators ` - -To learn how to specify queries using LINQ, see :ref:`csharp-linq`. - -.. TODO: integrate into existing page - -Sample Class ------------- - -The code examples in this guide demonstrate how you can use builders to -create types to interact with documents in the sample collection ``plants.flowers``. -Documents in this collection are modeled by the following ``Flower`` class: - -.. literalinclude:: /includes/fundamentals/code-examples/builders.cs - :language: csharp - :dedent: - :start-after: start-model - :end-before: end-model - -Each builder class takes a generic type parameter -``TDocument`` which represents the type of document that you are working -with. In this guide, the ``Flower`` class is the document type used in -each builder class example. - -Construct a Filter ------------------- - -The ``FilterDefinitionBuilder`` class provides a type-safe interface for -building up queries. Suppose you want to query your collection for -documents matching the following criteria: - -- ``Price`` field value less than 20 -- ``Category`` field value is "Perennial" - -Use builders to create the filter definition with the typed variant: - -.. code-block:: csharp - :copyable: true - - var builder = Builders.Filter; - var filter = builder.Lt(f => f.Price, 20) & builder.Eq(f => f.Category, "Perennial"); - -Using the typed variant form provides compile-time safety. Additionally, -your IDE can provide refactoring support. - -Alternatively, you can use string-based field names to contruct the filter: - -.. code-block:: csharp - :copyable: true - - var builder = Builders.Filter; - var filter = builder.Lt("Price", 20) & builder.Eq("Category", "Perennial"); - -If you are using LINQ, you can also use the ``Inject()`` method to apply the filter -to a LINQ query: - -.. code-block:: csharp - :copyable: true - - var builder = Builders.Filter; - var filter = builder.Lt("Price", 20) & builder.Eq("Category", "Perennial"); - var query = collection.AsQueryable().Where(f => filter.Inject()); - -Array Operators -~~~~~~~~~~~~~~~ - -If your document has properties or fields that serialize to arrays, -you can use the methods beginning with ``Any``, such as ``AnyEq()`` or -``AnyLt()``, to compare the entire array against a single item. - -Use builders to check which documents in the collection have a -``Season`` array that includes "winter": - -.. code-block:: csharp - :copyable: true - - var builder = Builders.Filter; - var filter = builder.AnyEq(f => f.Season, "winter"); - -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. - -- `FilterDefinitionBuilder <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.FilterDefinitionBuilder-1.html>`__ \ No newline at end of file diff --git a/source/includes/fundamentals/code-examples/specify-query/FindAndBuilder.cs b/source/includes/fundamentals/code-examples/specify-query/FindAndBuilder.cs index 01bb7a9d..55c26c5c 100644 --- a/source/includes/fundamentals/code-examples/specify-query/FindAndBuilder.cs +++ b/source/includes/fundamentals/code-examples/specify-query/FindAndBuilder.cs @@ -4,7 +4,7 @@ var filter = builder.And(builder.Gte(g => g.EstablishedYear, 1985), builder.Ne(r => r.Make, "Kiesel")); // Finds all documents that match the filter -var result = _guitarsCollection.Find(filter).ToList(); +var result = guitarCollection.Find(filter).ToList(); foreach (var doc in result) { diff --git a/source/includes/fundamentals/code-examples/specify-query/FindAndPOCO.cs b/source/includes/fundamentals/code-examples/specify-query/FindAndPOCO.cs index 946a1a7e..17e2937d 100644 --- a/source/includes/fundamentals/code-examples/specify-query/FindAndPOCO.cs +++ b/source/includes/fundamentals/code-examples/specify-query/FindAndPOCO.cs @@ -1,6 +1,6 @@ // Finds all documents with an "establishedYear" value greater than 1985 // and a "make" value that is not equal to "Kiesel" -var results = _guitarsCollection.Find(g => g.EstablishedYear >= 1985 && r.Make != "Kiesel").ToList(); +var results = guitarCollection.Find(g => g.EstablishedYear >= 1985 && r.Make != "Kiesel").ToList(); foreach (var doc in results) { diff --git a/source/includes/fundamentals/code-examples/specify-query/FindEqBuilder.cs b/source/includes/fundamentals/code-examples/specify-query/FindEqBuilder.cs index 4b346502..7d23f57a 100644 --- a/source/includes/fundamentals/code-examples/specify-query/FindEqBuilder.cs +++ b/source/includes/fundamentals/code-examples/specify-query/FindEqBuilder.cs @@ -2,7 +2,7 @@ var filter = Builders.Filter.Eq(g => g.Make, "Fender"); // Finds all documents that match the filter -var result = _guitarsCollection.Find(filter).ToList(); +var result = guitarCollection.Find(filter).ToList(); foreach (var doc in result) { diff --git a/source/includes/fundamentals/code-examples/specify-query/FindEqPOCO.cs b/source/includes/fundamentals/code-examples/specify-query/FindEqPOCO.cs index ea031b67..a4c92c17 100644 --- a/source/includes/fundamentals/code-examples/specify-query/FindEqPOCO.cs +++ b/source/includes/fundamentals/code-examples/specify-query/FindEqPOCO.cs @@ -1,5 +1,5 @@ // Finds all documents with a "make" value of "Fender" -var results = _guitarsCollection.Find(g => g.Make == "Fender").ToList(); +var results = guitarCollection.Find(g => g.Make == "Fender").ToList(); foreach (var doc in results) { diff --git a/source/includes/fundamentals/code-examples/specify-query/FindExistsBuilder.cs b/source/includes/fundamentals/code-examples/specify-query/FindExistsBuilder.cs index 2860354f..438e33bb 100644 --- a/source/includes/fundamentals/code-examples/specify-query/FindExistsBuilder.cs +++ b/source/includes/fundamentals/code-examples/specify-query/FindExistsBuilder.cs @@ -2,7 +2,7 @@ var filter = Builders.Filter.Exists(g => g.Rating); // Finds all documents that match the filter -var result = _guitarsCollection.Find(filter).ToList(); +var result = guitarCollection.Find(filter).ToList(); foreach (var doc in result) { diff --git a/source/includes/fundamentals/code-examples/specify-query/FindGtBuilder.cs b/source/includes/fundamentals/code-examples/specify-query/FindGtBuilder.cs index 466b56fb..afee42b9 100644 --- a/source/includes/fundamentals/code-examples/specify-query/FindGtBuilder.cs +++ b/source/includes/fundamentals/code-examples/specify-query/FindGtBuilder.cs @@ -3,7 +3,7 @@ var filter = Builders.Filter.Gt(g => g.EstablishedYear, 1985); // Finds all documents that match the filter -var result = _guitarsCollection.Find(filter).ToList(); +var result = guitarCollection.Find(filter).ToList(); foreach (var doc in result) { diff --git a/source/includes/fundamentals/code-examples/specify-query/FindGtPOCO.cs b/source/includes/fundamentals/code-examples/specify-query/FindGtPOCO.cs index d3308414..7f92dcb1 100644 --- a/source/includes/fundamentals/code-examples/specify-query/FindGtPOCO.cs +++ b/source/includes/fundamentals/code-examples/specify-query/FindGtPOCO.cs @@ -1,5 +1,5 @@ -// Finds all documents with am "establishedYear" value greater than 1985 -var results = _guitarsCollection.Find(g => g.EstablishedYear > 1985).ToList(); +// Finds all documents with an "establishedYear" value greater than 1985 +var results = guitarCollection.Find(g => g.EstablishedYear > 1985).ToList(); foreach (var doc in results) { diff --git a/source/includes/fundamentals/code-examples/specify-query/FindRegexBuilder.cs b/source/includes/fundamentals/code-examples/specify-query/FindRegexBuilder.cs index efcc8c59..29e36a79 100644 --- a/source/includes/fundamentals/code-examples/specify-query/FindRegexBuilder.cs +++ b/source/includes/fundamentals/code-examples/specify-query/FindRegexBuilder.cs @@ -2,7 +2,7 @@ var filter = Builders.Filter.Regex(g => g.Make, "^G"); // Finds all documents that match the filter -var result = _guitarsCollection.Find(filter).ToList(); +var result = guitarCollection.Find(filter).ToList(); foreach (var doc in result) { diff --git a/source/includes/fundamentals/code-examples/specify-query/FindSizeBuilder.cs b/source/includes/fundamentals/code-examples/specify-query/FindSizeBuilder.cs index 02764816..7a1272b7 100644 --- a/source/includes/fundamentals/code-examples/specify-query/FindSizeBuilder.cs +++ b/source/includes/fundamentals/code-examples/specify-query/FindSizeBuilder.cs @@ -2,7 +2,7 @@ var filter = Builders.Filter.Size(g => g.Models, 3); // Finds all documents that match the filter -var result = _guitarsCollection.Find(filter).ToList(); +var result = guitarCollection.Find(filter).ToList(); foreach (var doc in result) { diff --git a/source/reference/compatibility.txt b/source/reference/compatibility.txt index ce124f4b..cee8ba3b 100644 --- a/source/reference/compatibility.txt +++ b/source/reference/compatibility.txt @@ -41,5 +41,5 @@ The first column lists the driver version. .. 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. ` +For more information about how to read the compatibility tables, see +`MongoDB Compatibility Tables `__. From e45e0335c684ef8ed3e163d0fceba682b9ee133c Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Thu, 22 May 2025 09:00:39 -0500 Subject: [PATCH 20/35] DOCSP-49849 - Collation (#628) --- source/crud/bulk-write.txt | 20 +-- source/crud/delete.txt | 12 +- source/crud/query/count.txt | 10 +- source/crud/query/distinct.txt | 11 +- source/crud/query/find.txt | 10 +- source/crud/replace.txt | 11 +- source/includes/collation.rst | 117 ++++++++++++++++++ .../includes/page-templates/update/update.rst | 11 +- .../logging-and-monitoring/change-streams.txt | 10 +- 9 files changed, 193 insertions(+), 19 deletions(-) create mode 100644 source/includes/collation.rst diff --git a/source/crud/bulk-write.txt b/source/crud/bulk-write.txt index fb7a0963..b8e746dc 100644 --- a/source/crud/bulk-write.txt +++ b/source/crud/bulk-write.txt @@ -133,8 +133,7 @@ parameters: * - ``collation`` - | *Optional.* The language collation to use when sorting results. See the - :manual:`{+mdb+server+} manual` - for more information. + :ref:`` section of this page for more information. | | **Data Type:** `Collation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Collation.html>`__ | **Default:** ``null`` @@ -228,9 +227,8 @@ constructor accepts the following parameters: | **Data Type:** ``TDocument`` * - ``collation`` - - | *Optional.* The language collation to use when sorting results. See - the :manual:`{+mdb-server+} manual` - for more information. + - | *Optional.* The language collation to use when sorting results. See the + :ref:`` section of this page for more information. | | **Data Type:** `Collation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Collation.html>`__ | **Default:** ``null`` @@ -298,9 +296,8 @@ parameters: | **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. + - | *Optional.* The language collation to use when sorting results. See the + :ref:`` section of this page for more information. | | **Data Type:** `Collation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Collation.html>`__ | **Default:** ``null`` @@ -470,6 +467,13 @@ a delete operation: :copyable: :dedent: 8 +.. _csharp-bulk-write-collation: + +Collation +~~~~~~~~~ + +.. include:: /includes/collation.rst + Return Value ------------ diff --git a/source/crud/delete.txt b/source/crud/delete.txt index 8b91da80..83840696 100644 --- a/source/crud/delete.txt +++ b/source/crud/delete.txt @@ -139,9 +139,8 @@ following properties: * - ``Collation`` - | Gets or sets the type of language collation to use when sorting - results. See :manual:`the delete - statements` - for more information. + results. See the :ref:`` section of this page for more + information. * - ``Comment`` - | Gets or sets the comment for the operation. See :manual:`the delete command @@ -158,6 +157,13 @@ following properties: fields` for more information. +.. _csharp-delete-collation: + +Collation +~~~~~~~~~ + +.. include:: /includes/collation.rst + Example ~~~~~~~ diff --git a/source/crud/query/count.txt b/source/crud/query/count.txt index cc2e4aa1..1b4c8bdf 100644 --- a/source/crud/query/count.txt +++ b/source/crud/query/count.txt @@ -98,7 +98,8 @@ You can set the following properties in a ``CountOptions`` object: - Description * - ``Collation`` - - | The type of language collation to use when sorting results. + - | The type of language collation to use when sorting results. See the + :ref:`` section of this page for more information. | Default: ``null`` * - ``Hint`` @@ -132,6 +133,13 @@ You can set the following properties in a ``CountOptions`` object: CountOptions opts = new CountOptions(){Hint = "_id_"}; var count = collection.CountDocuments(filter, opts); +.. _csharp-count-collation: + +Collation +~~~~~~~~~ + +.. include:: /includes/collation.rst + .. _csharp-estimated-count: Estimated Count diff --git a/source/crud/query/distinct.txt b/source/crud/query/distinct.txt index a3af7165..9aff824f 100644 --- a/source/crud/query/distinct.txt +++ b/source/crud/query/distinct.txt @@ -180,7 +180,9 @@ describes the properties you can set on a ``DistinctOptions`` instance: - Description * - ``Collation`` - - | Sets the collation to use for the operation. + - | Sets the collation to use for the operation. See the + :ref:`` section of this page for more information. + | Default: ``null`` | **Data type**: `Collation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.DistinctOptions.Collation.html>`__ * - ``MaxTime`` @@ -249,6 +251,13 @@ corresponding code. Angie'S Cafe Pizza ... +.. _csharp-distinct-collation: + +Collation +~~~~~~~~~ + +.. include:: /includes/collation.rst + API Documentation ----------------- diff --git a/source/crud/query/find.txt b/source/crud/query/find.txt index f5f2526e..64ffcb47 100644 --- a/source/crud/query/find.txt +++ b/source/crud/query/find.txt @@ -208,7 +208,8 @@ You can configure the commonly used options with the following methods: - | Gets or sets the number of documents to hold in a cursor at a given time. * - ``Collation`` - - | Sets the collation options. + - | Sets the collation options. See the + :ref:`` section of this page for more information. * - ``Comment`` - | Sets the comment to the query. To learn more about query comments, @@ -223,6 +224,13 @@ You can configure the commonly used options with the following methods: To see a full list of available options, see `FindOptions Properties <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.FindOptions.html>`__. +.. _csharp-find-collation: + +Collation +~~~~~~~~~ + +.. include:: /includes/collation.rst + Example ~~~~~~~ diff --git a/source/crud/replace.txt b/source/crud/replace.txt index c094116b..b430ae32 100644 --- a/source/crud/replace.txt +++ b/source/crud/replace.txt @@ -138,8 +138,8 @@ The ``ReplaceOptions`` class contains the following properties: * - ``Collation`` - Specifies the kind of language collation to use when sorting - results. See :manual:`the {+mdb-server+} manual ` - for more information on collation. + results. See the :ref:`` section of this page for more + information. **Data Type:** `Collation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Collation.html>`__ @@ -199,6 +199,13 @@ code. :start-after: // start-replace-one-async-with-options :end-before: // end-replace-one-async-with-options +.. _csharp-replace-collation: + +Collation +~~~~~~~~~ + +.. include:: /includes/collation.rst + Return Value ~~~~~~~~~~~~ diff --git a/source/includes/collation.rst b/source/includes/collation.rst new file mode 100644 index 00000000..e944268c --- /dev/null +++ b/source/includes/collation.rst @@ -0,0 +1,117 @@ +To configure collation for your operation, create an instance of the +`Collation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Collation.html>`__ class. + +The following table describes the parameters that the ``Collation`` constructor accepts. +It also lists the corresponding class property that you can use to read each +setting's value. + +.. list-table:: + :header-rows: 1 + :widths: 20 60 20 + + * - Parameter + - Description + - Class Property + + * - ``locale`` + - | Specifies the International Components for Unicode (ICU) locale. For a list of + supported locales, + see :manual:`Collation Locales and Default Parameters ` + in the {+mdb-server+} Manual. + | + | If you want to use simple binary comparison, use the ``Collation.Simple`` static + property to return a ``Collation`` object with the ``locale`` set to ``"simple"``. + | **Data Type**: {+string-data-type+} + - ``Locale`` + + * - ``caseLevel`` + - | *(Optional)* Specifies whether to include case comparison. + | + | When this argument is ``true``, the driver's behavior depends on the value of + the ``strength`` argument: + | + | - If ``strength`` is ``CollationStrength.Primary``, the driver compares base + characters and case. + | - If ``strength`` is ``CollationStrength.Secondary``, the driver compares base + characters, diacritics, other secondary differences, and case. + | - If ``strength`` is any other value, this argument is ignored. + | + | When this argument is ``false``, the driver doesn't include case comparison at + strength level ``Primary`` or ``Secondary``. + | + | **Data Type**: {+bool-data-type+} + | **Default**: ``false`` + - ``CaseLevel`` + + * - ``caseFirst`` + - | *(Optional)* Specifies the sort order of case differences during tertiary level comparisons. + | + | **Data Type**: `CollationCaseFirst <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.CollationCaseFirst.html>`__ + | **Default**: ``CollationCaseFirst.Off`` + - ``CaseFirst`` + + * - ``strength`` + - | *(Optional)* Specifies the level of comparison to perform, as defined in the + `ICU documentation `__. + | + | **Data Type**: `CollationStrength <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.CollationStrength.html>`__ + | **Default**: ``CollationStrength.Tertiary`` + - ``Strength`` + + * - ``numericOrdering`` + - | *(Optional)* Specifies whether the driver compares numeric strings as numbers. + | + | If this argument is ``true``, the driver compares numeric strings as numbers. + For example, when comparing the strings "10" and "2", the driver treats the values + as 10 and 2, and finds 10 to be greater. + | + | If this argument is ``false`` or excluded, the driver compares numeric strings + as strings. For example, when comparing the strings "10" and "2", the driver + compares one character at a time. Because "1" is less than "2", the driver finds + "10" to be less than "2". + | + | For more information, see :manual:`Collation Restrictions ` + in the {+mdb-server+} manual. + | + | **Data Type**: {+bool-data-type+} + | **Default**: ``false`` + - ``NumericOrdering`` + + * - ``alternate`` + - | *(Optional)* Specifies whether the driver considers whitespace and punctuation as base + characters for purposes of comparison. + | + | **Data Type**: `CollationAlternate <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.CollationAlternate.html>`__ + | **Default**: ``CollationAlternate.NonIgnorable`` (spaces and punctuation are + considered base characters) + - ``Alternate`` + + * - ``maxVariable`` + - | *(Optional)* Specifies which characters the driver considers ignorable when + the ``alternate`` argument is ``CollationAlternate.Shifted``. + | + | **Data Type**: `CollationMaxVariable <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.CollationMaxVariable.html>`__ + | **Default**: ``CollationMaxVariable.Punctuation`` (the driver ignores punctuation + and spaces) + - ``MaxVariable`` + + * - ``normalization`` + - | *(Optional)* Specifies whether the driver normalizes text as needed. + | + | Most text doesn't require normalization. For more information about + normalization, see the `ICU documentation `__. + | + | **Data Type**: {+bool-data-type+} + | **Default**: ``false`` + - ``Normalization`` + + * - ``backwards`` + - | *(Optional)* Specifies whether strings containing diacritics sort from the back of the string + to the front. + | + | **Data Type**: {+bool-data-type+} + | **Default**: ``false`` + - ``Backwards`` + +For more information about collation, see the :manual:`Collation ` +page in the {+mdb-server+} manual. \ No newline at end of file diff --git a/source/includes/page-templates/update/update.rst b/source/includes/page-templates/update/update.rst index c6087ced..e21002c7 100644 --- a/source/includes/page-templates/update/update.rst +++ b/source/includes/page-templates/update/update.rst @@ -165,8 +165,8 @@ The ``UpdateOptions`` class contains the following properties: * - ``Collation`` - Specifies the kind of language collation to use when sorting - results. See :manual:`the {+mdb-server+} manual` - for more information on collation. + results. See the + :ref:`` section of this page for more information. **Data Type:** `Collation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Collation.html>`__ @@ -199,6 +199,13 @@ The ``UpdateOptions`` class contains the following properties: **Data Type:** `BsonDocument <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonDocument.html>`__ +.. _csharp-update-collation: + +Collation +~~~~~~~~~ + +.. include:: /includes/collation.rst + Return Value ------------ diff --git a/source/logging-and-monitoring/change-streams.txt b/source/logging-and-monitoring/change-streams.txt index e2fcc359..95efdbd7 100644 --- a/source/logging-and-monitoring/change-streams.txt +++ b/source/logging-and-monitoring/change-streams.txt @@ -289,11 +289,19 @@ of ``Watch()`` and ``WatchAsync()``: response from the MongoDB cluster. * - ``Collation`` - - | Specifies the collation to use for the change stream cursor. + - | Specifies the collation to use for the change stream cursor. See the + :ref:`` section of this page for more information. * - ``Comment`` - | Attaches a comment to the operation. +.. _csharp-change-stream-collation: + +Collation +~~~~~~~~~ + +.. include:: /includes/collation.rst + .. _csharp-change-stream-pre-post-image: Include Pre-Images and Post-Images From 74784726f8b8375062cd29264ca23f167c0fd0fe Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Fri, 23 May 2025 09:14:32 -0400 Subject: [PATCH 21/35] DOCSP-49867: Add JsonReader example (#636) --- source/data-formats/extended-json.txt | 5 ++--- source/includes/fundamentals/code-examples/ExtendedJson.cs | 6 ++---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/source/data-formats/extended-json.txt b/source/data-formats/extended-json.txt index 3d62ec4e..010910ff 100644 --- a/source/data-formats/extended-json.txt +++ b/source/data-formats/extended-json.txt @@ -28,7 +28,7 @@ Read Extended JSON ------------------ You can read an Extended JSON documents into a {+language+} object by using the -``BsonSerializer.Deserialize()`` method. The following example reads an +``BsonDocument.Parse()`` method. The following example reads an Extended JSON document into a ``BsonDocument`` object: .. io-code-block:: @@ -78,7 +78,7 @@ property: API Documentation ----------------- -To learn more about the methods and classes used on this page, see the following API +To learn more about the methods and classes you can use to work with JSON documents, see the following API documentation: - `BsonDocument <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonDocument.html>`__ @@ -87,5 +87,4 @@ documentation: - `JsonWriter <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.IO.JsonWriter.html>`__ - `JsonReader <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.IO.JsonReader.html>`__ - `JsonWriterSettings <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.IO.JsonWriterSettings.html>`__ -- `JsonReaderSettings <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.IO.JsonReaderSettings.html>`__ - `JsonOutputMode <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.IO.JsonOutputMode.html>`__ \ No newline at end of file diff --git a/source/includes/fundamentals/code-examples/ExtendedJson.cs b/source/includes/fundamentals/code-examples/ExtendedJson.cs index 1f0f1a8e..7a24d794 100644 --- a/source/includes/fundamentals/code-examples/ExtendedJson.cs +++ b/source/includes/fundamentals/code-examples/ExtendedJson.cs @@ -1,6 +1,4 @@ using MongoDB.Bson; -using MongoDB.Bson.IO; -using MongoDB.Bson.Serialization; public class ExtendedJson { @@ -10,11 +8,11 @@ public static void Main(string[] args) // start-read-ejson var ejson = "{\n\"_id\": { \"$oid\": \"573a1391f29313caabcd9637\" },\n \"createdAt\": { \"$date\": { \"$numberLong\": \"1601499609\" }},\n\"numViews\": { \"$numberLong\": \"36520312\" }\n}\n\n"; - var document = BsonSerializer.Deserialize(ejson); + var document = BsonDocument.Parse(ejson); Console.WriteLine(document.ToJson()); // end-read-ejson } - + { // start-write-ejson var document = new MyDocument(); From e95a4e667190f0874cdd61490a0b98479a57359e Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Thu, 29 May 2025 17:19:53 -0500 Subject: [PATCH 22/35] add linq page --- source/aggregation/linq.txt | 1218 +++++++++++++++++++++++++++++++++++ 1 file changed, 1218 insertions(+) create mode 100644 source/aggregation/linq.txt diff --git a/source/aggregation/linq.txt b/source/aggregation/linq.txt new file mode 100644 index 00000000..73fc6053 --- /dev/null +++ b/source/aggregation/linq.txt @@ -0,0 +1,1218 @@ +.. _csharp-linq: + +====================================== +LINQ Syntax for Aggregation Operations +====================================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 3 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: code example, query, aggregation + :description: Learn how to use LINQ with the MongoDB .NET/C# Driver to construct queries and perform aggregation operations on collections. + +Overview +-------- + +In this guide you can learn how to use +`LINQ `__ +with the {+driver-long+}. LINQ allows you to construct queries against +strongly typed collections of objects by using language keywords and operators. +The {+driver-short+} automatically translates LINQ queries into +:manual:`aggregation operations `. + +.. important:: + + LINQ3 is the only LINQ provider available in the {+driver-long+}. If you have + manually configured your project to use LINQ2, it will not compile. + +The examples in this guide use the ``restaurants`` collection +in the ``sample_restaurants`` database provided in the :atlas:`Atlas sample datasets `. +To learn how to create a free MongoDB Atlas cluster and load the sample datasets, +see the :ref:``. + +The following ``Restaurant``, ``Address`` and ``GradeEntry`` classes model the +documents in this collection: + +.. literalinclude:: /includes/fundamentals/code-examples/linq.cs + :language: csharp + :dedent: + :start-after: start-restaurant-model + :end-before: end-restaurant-model + +.. literalinclude:: /includes/fundamentals/code-examples/linq.cs + :language: csharp + :dedent: + :start-after: start-address-model + :end-before: end-address-model + +.. literalinclude:: /includes/fundamentals/code-examples/linq.cs + :language: csharp + :dedent: + :start-after: start-grade-model + :end-before: end-grade-model + +.. include:: /includes/convention-pack-note.rst + +.. _csharp-linq-queryable: + +Make A Collection Queryable +--------------------------- + +To use LINQ to query your collection, you must first create an +an `IQueryable +`__ +object that links to the collection. To create the object, use the ``AsQueryable()`` method +as follows: + +.. code-block:: csharp + :emphasize-lines: 3 + + 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**, +which resembles SQL query syntax. + +Select the :guilabel:`Method Syntax` or :guilabel:`Query Syntax` tab to see +how to compose a query using LINQ: + +.. tabs:: + + .. tab:: Method Syntax + :tabid: method-syntax + + .. code-block:: csharp + + var query = queryableCollection + .Where(r => r.Name == "The Movable Feast") + .Select(r => new { r.Name, r.Address }); + + .. tab:: Query Syntax + :tabid: query-syntax + + .. code-block:: csharp + + var query = from r in queryableCollection + where r.Name == "The Movable Feast" + select new { r.Name, r.Address }; + +You can print the results of the preceding example as follows: + +.. io-code-block:: + + .. input:: + :language: csharp + + foreach (var restaurant in query) + { + Console.WriteLine(restaurant.ToJson()); + } + + .. output:: + + { "name" : "The Movable Feast", "address" : { "building" : "284", "coord" : [-73.982923900000003, 40.6580753], "street" : "Prospect Park West", "zipcode" : "11215" } } + +.. tip:: Accessing Query Results + + You can also access the results of your query by using the ``ToList()`` or + ``ToCursor()`` methods: + + .. code-block:: csharp + + var results = query.ToList(); + + .. code-block:: csharp + + var results = query.ToCursor(); + +Supported Aggregation Stages +---------------------------- + +You can use LINQ to create an :manual:`aggregation pipeline `. +The {+driver-short+} automatically translates each LINQ statement into the corresponding +aggregation pipeline stages. In this section you can learn which +aggregation pipeline stages are supported. + +To learn more about the aggregation pipeline stages, see +:manual:`Aggregation Stages ` +in the {+mdb-server+} manual. + +$project +~~~~~~~~ + +The ``$project`` aggregation stage returns a document containing only the specified +fields. + +Select the :guilabel:`Method Syntax` or :guilabel:`Query Syntax` tab to see how +to generate a ``$project`` stage using LINQ: + +.. tabs:: + + .. tab:: Method Syntax + :tabid: method-syntax + + .. code-block:: csharp + :emphasize-lines: 2 + + var query = queryableCollection + .Select(r => new { r.Name, r.Address }); + + .. tab:: Query Syntax + :tabid: query-syntax + + .. code-block:: csharp + :emphasize-lines: 2 + + var query = from r in queryableCollection + select new { r.Name, r.Address }; + +The result of the preceding example contains the following document: + +.. code-block:: json + + { "name" : "The Movable Feast", "address" : { "building" : "284", "coord" : [-73.982923900000003, 40.6580753], "street" : "Prospect Park West", "zipcode" : "11215" } } + +.. note:: Excluding the ``_id`` Field + + If you don't include the ``_id`` field in your LINQ projection, the {+driver-short+} + automatically excludes it from the results. + +$match +~~~~~~ + +The ``$match`` aggregation stage returns the documents that match a specified +criteria. + +Select the :guilabel:`Method Syntax` or :guilabel:`Query Syntax` tab to see how +to generate a ``$match`` stage using LINQ: + +.. tabs:: + + .. tab:: Method Syntax + :tabid: method-syntax + + .. code-block:: csharp + :emphasize-lines: 2 + + var query = queryableCollection + .Where(r => r.Name == "The Movable Feast"); + + .. tab:: Query Syntax + :tabid: query-syntax + + .. code-block:: csharp + :emphasize-lines: 2 + + var query = from r in queryableCollection + where r.Name == "The Movable Feast" + select r; + +The result of the preceding example contains the following document: + +.. code-block:: json + + // Results Truncated + + { "_id" : ObjectId(...), "name" : "The Movable Feast", "restaurant_id" : "40361606", "cuisine" : "American", "address" : {...}, "borough" : "Brooklyn", "grades" : [...] } + +$limit +~~~~~~ + +The ``$limit`` aggregation stage limits the number of documents returned by the +query. The following example shows how to generate a ``$limit`` stage using LINQ: + +.. code-block:: csharp + :emphasize-lines: 4 + + var query = queryableCollection + .Where(r => r.Cuisine == "Italian") + .Select(r => new {r.Name, r.Cuisine}) + .Take(5); + +The result of the preceding example contains the following documents: + +.. code-block:: json + + { "name" : "Philadelhia Grille Express", "cuisine" : "Italian" } + { "name" : "Isle Of Capri Resturant", "cuisine" : "Italian" } + { "name" : "Marchis Restaurant", "cuisine" : "Italian" } + { "name" : "Crystal Room", "cuisine" : "Italian" } + { "name" : "Forlinis Restaurant", "cuisine" : "Italian" } + +.. _csharp-linq-takewhile: + +Limit on a Condition +```````````````````` + +You can use the ``TakeWhile()`` LINQ method in a ``Select()`` projection +to return array field elements while a specified condition is true, then +skip the remaining elements. + +This example uses the following ``Student`` class to model documents +that contain an array field ``Grades``: + +.. code-block:: csharp + + public class Student + { + public ObjectId Id { get; set; } + public string Name { get; set; } + public int[] Grades { get; set; } + } + +The following code shows how to use the ``TakeWhile()`` method to return +any ``Grades`` array elements that are greater than ``90`` and skip the +rest of the array: + +.. code-block:: csharp + + var query = queryableCollection + .Select(s => s.Grades.TakeWhile(g => g > 90).ToArray()); + +The results might resemble the following arrays: + +.. code-block:: json + :copyable: false + + [92, 97] + [100, 95, 91] + +$sample +~~~~~~~ + +The ``$sample`` aggregation stage returns a random sample of documents from a +collection. The following example shows how to generate a ``$sample`` stage by using +LINQ: + +.. code-block:: csharp + :emphasize-lines: 4 + + var query = queryableCollection + .Aggregate() + .Sample(4) + .ToList(); + +The result of the preceding example contains the following documents: + +.. code-block:: json + + // Results Truncated + + { "name" : "Von Dolhens", "cuisine" : "Ice Cream, Gelato, Yogurt, Ices" } + { "name" : "New York Mercantile Exchange", "cuisine" : "American" } + { "name" : "Michaelangelo's Restaurant", "cuisine" : "Italian" } + { "name" : "Charlie Palmer Steak", "cuisine" : "American" } + +$skip +~~~~~ + +The ``$skip`` aggregation stage skips over a specified number of documents returned +by a query, then returns the rest of the results. The following example shows how to generate +a ``$skip`` stage using LINQ: + +.. code-block:: csharp + :emphasize-lines: 4 + + var query = queryableCollection + .Where(r => r.Cuisine == "Italian") + .Select(r => new {r.Name, r.Cuisine}) + .Skip(2); + +The preceding example skips the first two restaurants that match the criteria, and +returns the rest. The result contains the following documents: + +.. code-block:: json + + // Results Truncated + + { "name" : "Marchis Restaurant", "cuisine" : "Italian" } + { "name" : "Crystal Room", "cuisine" : "Italian" } + { "name" : "Forlinis Restaurant", "cuisine" : "Italian" } + ... + +.. _csharp-linq-skipwhile: + +Skip on a Condition +``````````````````` + +You can use the ``SkipWhile()`` LINQ method in a ``Select()`` projection +to skip array field elements while a specified condition is true, then +return the remaining elements. + +This example uses the following ``Student`` class to model documents +that contain an array field ``Grades``: + +.. code-block:: csharp + + public class Student + { + public ObjectId Id { get; set; } + public string Name { get; set; } + public int[] Grades { get; set; } + } + +The following code shows how to use the ``SkipWhile()`` method to skip +any ``Grades`` array elements that are less than ``75`` and return the +rest of the array: + +.. code-block:: csharp + + var query = queryableCollection + .Select(s => s.Grades.SkipWhile(g => g < 75).ToArray()); + +The results might resemble the following arrays: + +.. code-block:: json + :copyable: false + + [80, 90, 70, 83] + [79, 100, 85, 73] + +$unwind +~~~~~~~ + +The ``$unwind`` aggregation stage deconstructs a specified array field and returns +a document for each element in that array. + +Select the :guilabel:`Method Syntax` or :guilabel:`Query Syntax` tab to see how +to generate an ``$unwind`` stage using LINQ: + +.. tabs:: + + .. tab:: Method Syntax + :tabid: method-syntax + + .. code-block:: csharp + :emphasize-lines: 3 + + var query = queryableCollection + .Where(r => r.Name == "The Movable Feast") + .SelectMany(r => r.Grades); + + .. tab:: Query Syntax + :tabid: query-syntax + + .. code-block:: csharp + :emphasize-lines: 3 + + var query = from r in queryableCollection + where r.Name == "The Movable Feast" + from grade in r.Grades + select grade; + +The query in the preceding example finds the document where the ``Name`` field +has the value "The Movable Feast." Then, for each element in this document's +``Grades`` array, the query returns a new document. The result contains the +following documents: + +.. code-block:: json + + { "date" : ISODate("2014-11-19T00:00:00Z"), "grade" : "A", "score" : 11 } + { "date" : ISODate("2013-11-14T00:00:00Z"), "grade" : "A", "score" : 2 } + { "date" : ISODate("2012-12-05T00:00:00Z"), "grade" : "A", "score" : 13 } + { "date" : ISODate("2012-05-17T00:00:00Z"), "grade" : "A", "score" : 11 } + +Nested Statements +````````````````` + +You can chain or nest ``Select`` and ``SelectMany`` statements to unwind nested +arrays. Consider a collection that contains documents with a **new** schema. These +documents contain a ``restaurants`` field, which holds an array of documents +represented by the ``Restaurant`` class. The documents within the array each have +a ``grades`` field that holds an array of documents represented by +the ``Grade`` class. The following code is an example of a single document in +this collection: + +.. code-block:: json + + { + "_id": { "$oid": ... }, + "restaurants": [ + { + "_id": { ... } , + "address": { ... }, + "name": "Tov Kosher Kitchen", + "grades": [ + { + "date" : ISODate("2014-11-24T00:00:00Z"), + "grade" : "Z", + "score" : 20.0 + }, + { + "date" : ISODate("2013-01-17T00:00:00Z"), + "grade" : "A", + "score" : 13.0 + } + ] + ... + }, + { + "_id": { ... } , + "address": { ... }, + "name": "Harriet's Kitchen", + "grades": [ + { + "date" : ISODate("2014-04-19T00:00:00Z"), + "grade" : "B", + "score" : 12.0 + } + ], + ... + }, + ... + ] + } + +You can nest ``SelectMany`` statements within ``SelectMany`` or ``Select`` +statements. The following example nests a ``SelectMany`` statement within a +``Select`` statement to retrieve an array from each document in the collection. +Each array holds all grade objects from all restaurants in each document. + +.. io-code-block:: + :copyable: true + + .. input:: /includes/fundamentals/code-examples/linq.cs + :language: csharp + :start-after: start-nested-SelectMany + :end-before: end-nested-SelectMany + + .. output:: + :visible: false + :language: json + + // output for first document in collection + [ + { "date" : ISODate("2014-11-24T00:00:00Z"), + "grade" : "Z", + "score" : 20.0 + }, + { "date" : ISODate("2013-01-17T00:00:00Z"), + "grade" : "A", + "score" : 13.0 + }, + { + "date" : ISODate("2014-04-19T00:00:00Z"), + "grade" : "B", + "score" : 12.0 + }, + ... + ], + // output for second document in collection + [ + ... + ] + +$group +~~~~~~ + +The ``$group`` aggregation stage separates documents into groups according to +the criteria you specify. + +Select the :guilabel:`Method Syntax` or :guilabel:`Query Syntax` tab to see how +to generate a ``$group`` stage using LINQ: + +.. tabs:: + + .. tab:: Method Syntax + :tabid: method-syntax + + .. code-block:: csharp + :emphasize-lines: 2 + + var query = queryableCollection + .GroupBy(r => r.Cuisine) + .Select(g => new { Cuisine = g.Key, Count = g.Count() }); + + .. tab:: Query Syntax + :tabid: query-syntax + + .. code-block:: csharp + :emphasize-lines: 2 + + var query = from r in queryableCollection + group r by r.Cuisine into g + select new {Cuisine = g.Key, Count = g.Count()}; + +The preceding example groups each document by the value in its ``Cuisine`` field, +then counts how many documents have each ``Cuisine`` value. The result contains +the following documents: + +.. code-block:: json + + // Results Truncated + + { "cuisine" : "Caribbean", "count" : 657 } + { "cuisine" : "Café/Coffee/Tea", "count" : 1214 } + { "cuisine" : "Iranian", "count" : 2 } + { "cuisine" : "Nuts/Confectionary", "count" : 6 } + { "cuisine" : "Middle Eastern", "count" : 168 } + ... + +.. note:: Result Order + + The preceding queries don't always return results in the same order. Running + this example may return the results in a different order than shown above. + +$sort +~~~~~ + +The ``$sort`` aggregation stage returns the results of your query in the order +that you specify. + +Select the :guilabel:`Method Syntax` or :guilabel:`Query Syntax` tab to see how +to generate a ``$sort`` stage using LINQ: + +.. tabs:: + + .. tab:: Method Syntax + :tabid: method-syntax + + .. code-block:: csharp + :emphasize-lines: 2 + + var query = queryableCollection + .OrderBy(r => r.Name) + .ThenByDescending(r => r.RestaurantId); + + .. tab:: Query Syntax + :tabid: query-syntax + + .. code-block:: csharp + :emphasize-lines: 2 + + var query = from r in queryableCollection + orderby r.Name, r.RestaurantId descending + select r; + +The preceding example returns the query results sorted alphabetically by the +``Name`` field, with a secondary descending sort on the ``RestaurantId`` field. +The following is a subset of the documents contained in the returned results: + +.. code-block:: json + + // Results Truncated + + ... + { "_id" : ObjectId(...), "name" : "Aba Turkish Restaurant", "restaurant_id" : "41548686", "cuisine" : "Turkish", "address" : {...}, "borough" : "Manhattan", "grades" : [...] } + { "_id" : ObjectId(...), "name" : "Abace Sushi", "restaurant_id" : "50006214", "cuisine" : "Japanese", "address" : { ... }, "borough" : "Manhattan", "grades" : [...] } + { "_id" : ObjectId(...), "name" : "Abacky Potluck", "restaurant_id" : "50011222", "cuisine" : "Asian", "address" : { ... }, "borough" : "Manhattan", "grades" : [...] } + { "_id" : ObjectId(...), "name" : "Abaleh", "restaurant_id" : "50009096", "cuisine" : "Mediterranean", "address" : { ... }, "borough" : "Manhattan", "grades" : [...] } + ... + +$lookup +~~~~~~~ + +The ``$lookup`` aggregation stage joins documents from one collection to documents +from another collection in the same database. The ``$lookup`` stage adds a new +array field to each input document. The new array field contains the matching +documents from the "joined" collection. + +Consider a second collection in the ``sample_restaurants`` database called +``reviews`` that has restaurant reviews. You can join documents from that collection +to documents with the same ``name`` value in the ``restaurants`` collection using +the ``$lookup`` stage. + +The following ``Review`` class models the documents in the ``reviews`` collection: + +.. literalinclude:: /includes/fundamentals/code-examples/linq.cs + :language: csharp + :dedent: + :start-after: start-review-model + :end-before: end-review-model + +You can specify a ``$lookup`` stage by calling the ``Lookup()`` method +or the ``GroupJoin()`` method. The following sections show how to perform a +``$lookup`` by using each method. + +Lookup() +```````` + +The following code specifies a ``$lookup`` stage by using the ``Lookup()`` +method. This example joins documents from the ``reviews`` collection to +documents from the ``restaurants`` collection where the ``RestaurantName`` field in the +``reviews`` collection matches the ``Name`` field in the ``restaurants`` collection: + +.. code-block:: csharp + + var lookupResult = restaurantsCollection.AsQueryable() + .Lookup(reviewCollection, + restaurant => restaurant.Name, + review => review.RestaurantName); + +The preceding example returns a list of ``LookupResult`` objects that +each contain a joined document. To learn more about the ``LookupResult`` class, +see the `LookupResult API documentation +<{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Linq.LookupResult-2.html>`__. + +You can also use a ``Lookup()`` method overload to specify additional criteria +for the join. The following example joins documents from the ``restaurants`` +collection to documents from the ``reviews`` collection where the +``RestaurantName`` field in the ``reviews`` collection matches the ``Name`` +field in the ``restaurants`` collection and the ``ReviewText`` field in the +``reviews`` collection contains the name of the restaurant: + +.. code-block:: csharp + + var lookupResult = restaurantsCollection.AsQueryable() + .Lookup(reviewCollection, + (restaurant, reviews) => reviews + .Where(review => review.ReviewText.Contains(restaurant.Name))); + +To view a full list of overloads for the ``Lookup()`` method, see the `Lookup +API documentation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Linq.MongoQueryable.Lookup.html>`__. + +GroupJoin() ++++++++++++ + +You can specify a ``$lookup`` stage by using the LINQ ``GroupJoin()`` method. To +perform a ``GroupJoin()`` lookup, you must make both collections queryable by +using the ``AsQueryable()`` method. To learn how to make a collection queryable, +see :ref:`csharp-linq-queryable`. + +Select the :guilabel:`Method Syntax` or :guilabel:`Query Syntax` tab to see how +to generate a ``$lookup`` stage by using LINQ: + +.. tabs:: + + .. tab:: Method Syntax + :tabid: method-syntax + + .. code-block:: csharp + + var query = queryableCollection + .GroupJoin(reviewCollection, + restaurant => restaurant.Name, + review => review.RestaurantName, + (restaurant, reviews) => + new { Restaurant = restaurant, Reviews = reviews } + ); + + .. tab:: Query Syntax + :tabid: query-syntax + + .. code-block:: csharp + + var query = from restaurant in queryableCollection + join rv in reviewCollection on restaurant.Name equals rv.RestaurantName into reviews + select new { restaurant, reviews }; + +The preceding example returns all documents from the ``restaurants`` collection. Each +restaurant document has an added field called ``reviews``, which contains all +reviews for that restaurant. A review matches a restaurant if the value of the +``name`` field in the review document matches the ``name`` field of the restaurant +document. + +The following shows a subset of the returned results: + +.. code-block:: json + + // Results Truncated + + { + "restaurant": { + "_id": ObjectId("..."), + "name": "The Movable Feast", + "restaurant_id": "40361606", + "cuisine": "American", + "address": { ... }, + "borough": "Brooklyn", + "grades": [ ... ] + }, + "reviews": [ + { + "_id": ObjectId("..."), + "restaurant_name": "The Movable Feast", + "reviewer": "Lazlo Cravensworth", + "review_text": "Great restaurant! 12/10 stars!" + }, + { + "_id": ObjectId("..."), + "restaurant_name": "The Movable Feast", + "reviewer": "Michael Scarn", + "review_text": "It really was a feast" + } + ] + } + +$vectorSearch +~~~~~~~~~~~~~ + +.. include:: /includes/vector-search-intro.rst + + .. replacement:: mechanism + + LINQ + +.. code-block:: csharp + + // Defines vector embeddings for the string "time travel" + var vector = new[] {-0.0016261312,-0.028070757,-0.011342932,-0.012775794,-0.0027440966,0.008683807,-0.02575152,-0.02020668,-0.010283281,-0.0041719596,0.021392956,0.028657231,-0.006634482,0.007490867,0.018593878,0.0038187427,0.029590257,-0.01451522,0.016061379,0.00008528442,-0.008943722,0.01627464,0.024311995,-0.025911469,0.00022596726,-0.008863748,0.008823762,-0.034921836,0.007910728,-0.01515501,0.035801545,-0.0035688248,-0.020299982,-0.03145631,-0.032256044,-0.028763862,-0.0071576433,-0.012769129,0.012322609,-0.006621153,0.010583182,0.024085402,-0.001623632,0.007864078,-0.021406285,0.002554159,0.012229307,-0.011762793,0.0051682983,0.0048484034,0.018087378,0.024325324,-0.037694257,-0.026537929,-0.008803768,-0.017767483,-0.012642504,-0.0062712682,0.0009771782,-0.010409906,0.017754154,-0.004671795,-0.030469967,0.008477209,-0.005218282,-0.0058480743,-0.020153364,-0.0032805866,0.004248601,0.0051449724,0.006791097,0.007650814,0.003458861,-0.0031223053,-0.01932697,-0.033615597,0.00745088,0.006321252,-0.0038154104,0.014555207,0.027697546,-0.02828402,0.0066711367,0.0077107945,0.01794076,0.011349596,-0.0052715978,0.014755142,-0.019753495,-0.011156326,0.011202978,0.022126047,0.00846388,0.030549942,-0.0041386373,0.018847128,-0.00033655585,0.024925126,-0.003555496,-0.019300312,0.010749794,0.0075308536,-0.018287312,-0.016567878,-0.012869096,-0.015528221,0.0078107617,-0.011156326,0.013522214,-0.020646535,-0.01211601,0.055928253,0.011596181,-0.017247654,0.0005939711,-0.026977783,-0.003942035,-0.009583511,-0.0055248477,-0.028737204,0.023179034,0.003995351,0.0219661,-0.008470545,0.023392297,0.010469886,-0.015874773,0.007890735,-0.009690142,-0.00024970944,0.012775794,0.0114762215,0.013422247,0.010429899,-0.03686786,-0.006717788,-0.027484283,0.011556195,-0.036068123,-0.013915418,-0.0016327957,0.0151016945,-0.020473259,0.004671795,-0.012555866,0.0209531,0.01982014,0.024485271,0.0105431955,-0.005178295,0.033162415,-0.013795458,0.007150979,0.010243294,0.005644808,0.017260984,-0.0045618312,0.0024725192,0.004305249,-0.008197301,0.0014203656,0.0018460588,0.005015015,-0.011142998,0.01439526,0.022965772,0.02552493,0.007757446,-0.0019726837,0.009503538,-0.032042783,0.008403899,-0.04609149,0.013808787,0.011749465,0.036388017,0.016314628,0.021939443,-0.0250051,-0.017354285,-0.012962398,0.00006107364,0.019113706,0.03081652,-0.018114036,-0.0084572155,0.009643491,-0.0034721901,0.0072642746,-0.0090636825,0.01642126,0.013428912,0.027724205,0.0071243206,-0.6858542,-0.031029783,-0.014595194,-0.011449563,0.017514233,0.01743426,0.009950057,0.0029706885,-0.015714826,-0.001806072,0.011856096,0.026444625,-0.0010663156,-0.006474535,0.0016161345,-0.020313311,0.0148351155,-0.0018393943,0.0057347785,0.018300641,-0.018647194,0.03345565,-0.008070676,0.0071443142,0.014301958,0.0044818576,0.003838736,-0.007350913,-0.024525259,-0.001142124,-0.018620536,0.017247654,0.007037683,0.010236629,0.06046009,0.0138887605,-0.012122675,0.037694257,0.0055081863,0.042492677,0.00021784494,-0.011656162,0.010276617,0.022325981,0.005984696,-0.009496873,0.013382261,-0.0010563189,0.0026507939,-0.041639622,0.008637156,0.026471283,-0.008403899,0.024858482,-0.00066686375,-0.0016252982,0.027590916,0.0051449724,0.0058647357,-0.008743787,-0.014968405,0.027724205,-0.011596181,0.0047650975,-0.015381602,0.0043718936,0.002159289,0.035908177,-0.008243952,-0.030443309,0.027564257,0.042625964,-0.0033688906,0.01843393,0.019087048,0.024578573,0.03268257,-0.015608194,-0.014128681,-0.0033538956,-0.0028757197,-0.004121976,-0.032389335,0.0034322033,0.058807302,0.010943064,-0.030523283,0.008903735,0.017500903,0.00871713,-0.0029406983,0.013995391,-0.03132302,-0.019660193,-0.00770413,-0.0038853872,0.0015894766,-0.0015294964,-0.006251275,-0.021099718,-0.010256623,-0.008863748,0.028550599,0.02020668,-0.0012962399,-0.003415542,-0.0022509254,0.0119360695,0.027590916,-0.046971202,-0.0015194997,-0.022405956,0.0016677842,-0.00018535563,-0.015421589,-0.031802863,0.03814744,0.0065411795,0.016567878,-0.015621523,0.022899127,-0.011076353,0.02841731,-0.002679118,-0.002342562,0.015341615,0.01804739,-0.020566562,-0.012989056,-0.002990682,0.01643459,0.00042527664,0.008243952,-0.013715484,-0.004835075,-0.009803439,0.03129636,-0.021432944,0.0012087687,-0.015741484,-0.0052016205,0.00080890034,-0.01755422,0.004811749,-0.017967418,-0.026684547,-0.014128681,0.0041386373,-0.013742141,-0.010056688,-0.013268964,-0.0110630235,-0.028337335,0.015981404,-0.00997005,-0.02424535,-0.013968734,-0.028310679,-0.027750863,-0.020699851,0.02235264,0.001057985,0.00081639783,-0.0099367285,0.013522214,-0.012016043,-0.00086471526,0.013568865,0.0019376953,-0.019020405,0.017460918,-0.023045745,0.008503866,0.0064678704,-0.011509543,0.018727167,-0.003372223,-0.0028690554,-0.0027024434,-0.011902748,-0.012182655,-0.015714826,-0.0098634185,0.00593138,0.018753825,0.0010146659,0.013029044,0.0003521757,-0.017620865,0.04102649,0.00552818,0.024485271,-0.009630162,-0.015608194,0.0006718621,-0.0008418062,0.012395918,0.0057980907,0.016221326,0.010616505,0.004838407,-0.012402583,0.019900113,-0.0034521967,0.000247002,-0.03153628,0.0011038032,-0.020819811,0.016234655,-0.00330058,-0.0032289368,0.00078973995,-0.021952773,-0.022459272,0.03118973,0.03673457,-0.021472929,0.0072109587,-0.015075036,0.004855068,-0.0008151483,0.0069643734,0.010023367,-0.010276617,-0.023019087,0.0068244194,-0.0012520878,-0.0015086699,0.022046074,-0.034148756,-0.0022192693,0.002427534,-0.0027124402,0.0060346797,0.015461575,0.0137554705,0.009230294,-0.009583511,0.032629255,0.015994733,-0.019167023,-0.009203636,0.03393549,-0.017274313,-0.012042701,-0.0009930064,0.026777849,-0.013582194,-0.0027590916,-0.017594207,-0.026804507,-0.0014236979,-0.022032745,0.0091236625,-0.0042419364,-0.00858384,-0.0033905501,-0.020739838,0.016821127,0.022539245,0.015381602,0.015141681,0.028817179,-0.019726837,-0.0051283115,-0.011489551,-0.013208984,-0.0047017853,-0.0072309524,0.01767418,0.0025658219,-0.010323267,0.012609182,-0.028097415,0.026871152,-0.010276617,0.021912785,0.0022542577,0.005124979,-0.0019710176,0.004518512,-0.040360045,0.010969722,-0.0031539614,-0.020366628,-0.025778178,-0.0110030435,-0.016221326,0.0036587953,0.016207997,0.003007343,-0.0032555948,0.0044052163,-0.022046074,-0.0008822095,-0.009363583,0.028230704,-0.024538586,0.0029840174,0.0016044717,-0.014181997,0.031349678,-0.014381931,-0.027750863,0.02613806,0.0004136138,-0.005748107,-0.01868718,-0.0010138329,0.0054348772,0.010703143,-0.003682121,0.0030856507,-0.004275259,-0.010403241,0.021113047,-0.022685863,-0.023032416,0.031429652,0.001792743,-0.005644808,-0.011842767,-0.04078657,-0.0026874484,0.06915057,-0.00056939584,-0.013995391,0.010703143,-0.013728813,-0.022939114,-0.015261642,-0.022485929,0.016807798,0.007964044,0.0144219175,0.016821127,0.0076241563,0.005461535,-0.013248971,0.015301628,0.0085171955,-0.004318578,0.011136333,-0.0059047225,-0.010249958,-0.018207338,0.024645219,0.021752838,0.0007614159,-0.013648839,0.01111634,-0.010503208,-0.0038487327,-0.008203966,-0.00397869,0.0029740208,0.008530525,0.005261601,0.01642126,-0.0038753906,-0.013222313,0.026537929,0.024671877,-0.043505676,0.014195326,0.024778508,0.0056914594,-0.025951454,0.017620865,-0.0021359634,0.008643821,0.021299653,0.0041686273,-0.009017031,0.04044002,0.024378639,-0.027777521,-0.014208655,0.0028623908,0.042119466,0.005801423,-0.028124074,-0.03129636,0.022139376,-0.022179363,-0.04067994,0.013688826,0.013328944,0.0046184794,-0.02828402,-0.0063412455,-0.0046184794,-0.011756129,-0.010383247,-0.0018543894,-0.0018593877,-0.00052024535,0.004815081,0.014781799,0.018007403,0.01306903,-0.020433271,0.009043689,0.033189073,-0.006844413,-0.019766824,-0.018767154,0.00533491,-0.0024575242,0.018727167,0.0058080875,-0.013835444,0.0040719924,0.004881726,0.012029372,0.005664801,0.03193615,0.0058047553,0.002695779,0.009290274,0.02361889,0.017834127,0.0049017193,-0.0036388019,0.010776452,-0.019793482,0.0067777685,-0.014208655,-0.024911797,0.002385881,0.0034988478,0.020899786,-0.0025858153,-0.011849431,0.033189073,-0.021312982,0.024965113,-0.014635181,0.014048708,-0.0035921505,-0.003347231,0.030869836,-0.0017161017,-0.0061346465,0.009203636,-0.025165047,0.0068510775,0.021499587,0.013782129,-0.0024475274,-0.0051149824,-0.024445284,0.006167969,0.0068844,-0.00076183246,0.030150073,-0.0055948244,-0.011162991,-0.02057989,-0.009703471,-0.020646535,0.008004031,0.0066378145,-0.019900113,-0.012169327,-0.01439526,0.0044252095,-0.004018677,0.014621852,-0.025085073,-0.013715484,-0.017980747,0.0071043274,0.011456228,-0.01010334,-0.0035321703,-0.03801415,-0.012036037,-0.0028990454,-0.05419549,-0.024058744,-0.024272008,0.015221654,0.027964126,0.03182952,-0.015354944,0.004855068,0.011522872,0.004771762,0.0027874154,0.023405626,0.0004242353,-0.03132302,0.007057676,0.008763781,-0.0027057757,0.023005757,-0.0071176565,-0.005238275,0.029110415,-0.010989714,0.013728813,-0.009630162,-0.029137073,-0.0049317093,-0.0008630492,-0.015248313,0.0043219104,-0.0055681667,-0.013175662,0.029723546,0.025098402,0.012849103,-0.0009996708,0.03118973,-0.0021709518,0.0260181,-0.020526575,0.028097415,-0.016141351,0.010509873,-0.022965772,0.002865723,0.0020493253,0.0020509914,-0.0041419696,-0.00039695262,0.017287642,0.0038987163,0.014795128,-0.014661839,-0.008950386,0.004431874,-0.009383577,0.0012604183,-0.023019087,0.0029273694,-0.033135757,0.009176978,-0.011023037,-0.002102641,0.02663123,-0.03849399,-0.0044152127,0.0004527676,-0.0026924468,0.02828402,0.017727496,0.035135098,0.02728435,-0.005348239,-0.001467017,-0.019766824,0.014715155,0.011982721,0.0045651635,0.023458943,-0.0010046692,-0.0031373003,-0.0006972704,0.0019043729,-0.018967088,-0.024311995,0.0011546199,0.007977373,-0.004755101,-0.010016702,-0.02780418,-0.004688456,0.013022379,-0.005484861,0.0017227661,-0.015394931,-0.028763862,-0.026684547,0.0030589928,-0.018513903,0.028363993,0.0044818576,-0.009270281,0.038920518,-0.016008062,0.0093902415,0.004815081,-0.021059733,0.01451522,-0.0051583014,0.023765508,-0.017874114,-0.016821127,-0.012522544,-0.0028390652,0.0040886537,0.020259995,-0.031216389,-0.014115352,-0.009176978,0.010303274,0.020313311,0.0064112223,-0.02235264,-0.022872468,0.0052449396,0.0005723116,0.0037321046,0.016807798,-0.018527232,-0.009303603,0.0024858483,-0.0012662497,-0.007110992,0.011976057,-0.007790768,-0.042999174,-0.006727785,-0.011829439,0.007024354,0.005278262,-0.017740825,-0.0041519664,0.0085905045,0.027750863,-0.038387362,0.024391968,0.00087721116,0.010509873,-0.00038508154,-0.006857742,0.0183273,-0.0037054466,0.015461575,0.0017394272,-0.0017944091,0.014181997,-0.0052682655,0.009023695,0.00719763,-0.013522214,0.0034422,0.014941746,-0.0016711164,-0.025298337,-0.017634194,0.0058714002,-0.005321581,0.017834127,0.0110630235,-0.03369557,0.029190388,-0.008943722,0.009363583,-0.0034222065,-0.026111402,-0.007037683,-0.006561173,0.02473852,-0.007084334,-0.010110005,-0.008577175,0.0030439978,-0.022712521,0.0054582027,-0.0012620845,-0.0011954397,-0.015741484,0.0129557345,-0.00042111133,0.00846388,0.008930393,0.016487904,0.010469886,-0.007917393,-0.011762793,-0.0214596,0.000917198,0.021672864,0.010269952,-0.007737452,-0.010243294,-0.0067244526,-0.015488233,-0.021552904,0.017127695,0.011109675,0.038067464,0.00871713,-0.0025591573,0.021312982,-0.006237946,0.034628596,-0.0045251767,0.008357248,0.020686522,0.0010696478,0.0076708077,0.03772091,-0.018700508,-0.0020676525,-0.008923728,-0.023298996,0.018233996,-0.010256623,0.0017860786,0.009796774,-0.00897038,-0.01269582,-0.018527232,0.009190307,-0.02372552,-0.042119466,0.008097334,-0.0066778013,-0.021046404,0.0019593548,0.011083017,-0.0016028056,0.012662497,-0.000059095124,0.0071043274,-0.014675168,0.024831824,-0.053582355,0.038387362,0.0005698124,0.015954746,0.021552904,0.031589597,-0.009230294,-0.0006147976,0.002625802,-0.011749465,-0.034362018,-0.0067844326,-0.018793812,0.011442899,-0.008743787,0.017474247,-0.021619547,0.01831397,-0.009037024,-0.0057247817,-0.02728435,0.010363255,0.034415334,-0.024032086,-0.0020126705,-0.0045518344,-0.019353628,-0.018340627,-0.03129636,-0.0034038792,-0.006321252,-0.0016161345,0.033642255,-0.000056075285,-0.005005019,0.004571828,-0.0024075406,-0.00010215386,0.0098634185,0.1980148,-0.003825407,-0.025191706,0.035161756,0.005358236,0.025111731,0.023485601,0.0023342315,-0.011882754,0.018287312,-0.0068910643,0.003912045,0.009243623,-0.001355387,-0.028603915,-0.012802451,-0.030150073,-0.014795128,-0.028630573,-0.0013487226,0.002667455,0.00985009,-0.0033972147,-0.021486258,0.009503538,-0.017847456,0.013062365,-0.014341944,0.005078328,0.025165047,-0.015594865,-0.025924796,-0.0018177348,0.010996379,-0.02993681,0.007324255,0.014475234,-0.028577257,0.005494857,0.00011725306,-0.013315615,0.015941417,0.009376912,0.0025158382,0.008743787,0.023832154,-0.008084005,-0.014195326,-0.008823762,0.0033455652,-0.032362677,-0.021552904,-0.0056081535,0.023298996,-0.025444955,0.0097301295,0.009736794,0.015274971,-0.0012937407,-0.018087378,-0.0039387033,0.008637156,-0.011189649,-0.00023846315,-0.011582852,0.0066411467,-0.018220667,0.0060846633,0.0376676,-0.002709108,0.0072776037,0.0034188742,-0.010249958,-0.0007747449,-0.00795738,-0.022192692,0.03910712,0.032122757,0.023898797,0.0076241563,-0.007397564,-0.003655463,0.011442899,-0.014115352,-0.00505167,-0.031163072,0.030336678,-0.006857742,-0.022259338,0.004048667,0.02072651,0.0030156737,-0.0042119464,0.00041861215,-0.005731446,0.011103011,0.013822115,0.021512916,0.009216965,-0.006537847,-0.027057758,-0.04054665,0.010403241,-0.0056281467,-0.005701456,-0.002709108,-0.00745088,-0.0024841821,0.009356919,-0.022659205,0.004061996,-0.013175662,0.017074378,-0.006141311,-0.014541878,0.02993681,-0.00028448965,-0.025271678,0.011689484,-0.014528549,0.004398552,-0.017274313,0.0045751603,0.012455898,0.004121976,-0.025458284,-0.006744446,0.011822774,-0.015035049,-0.03257594,0.014675168,-0.0039187097,0.019726837,-0.0047251107,0.0022825818,0.011829439,0.005391558,-0.016781142,-0.0058747325,0.010309938,-0.013049036,0.01186276,-0.0011246296,0.0062112883,0.0028190718,-0.021739509,0.009883412,-0.0073175905,-0.012715813,-0.017181009,-0.016607866,-0.042492677,-0.0014478565,-0.01794076,0.012302616,-0.015194997,-0.04433207,-0.020606548,0.009696807,0.010303274,-0.01694109,-0.004018677,0.019353628,-0.001991011,0.000058938927,0.010536531,-0.17274313,0.010143327,0.014235313,-0.024152048,0.025684876,-0.0012504216,0.036601283,-0.003698782,0.0007310093,0.004165295,-0.0029157067,0.017101036,-0.046891227,-0.017460918,0.022965772,0.020233337,-0.024072073,0.017220996,0.009370248,0.0010363255,0.0194336,-0.019606877,0.01818068,-0.020819811,0.007410893,0.0019326969,0.017887443,0.006651143,0.00067394477,-0.011889419,-0.025058415,-0.008543854,0.021579562,0.0047484366,0.014062037,0.0075508473,-0.009510202,-0.009143656,0.0046817916,0.013982063,-0.0027990784,0.011782787,0.014541878,-0.015701497,-0.029350337,0.021979429,0.01332228,-0.026244693,-0.0123492675,-0.003895384,0.0071576433,-0.035454992,-0.00046984528,0.0033522295,0.039347045,0.0005119148,0.00476843,-0.012995721,0.0024042083,-0.006931051,-0.014461905,-0.0127558,0.0034555288,-0.0074842023,-0.030256703,-0.007057676,-0.00807734,0.007804097,-0.006957709,0.017181009,-0.034575284,-0.008603834,-0.005008351,-0.015834786,0.02943031,0.016861115,-0.0050849924,0.014235313,0.0051449724,0.0025924798,-0.0025741523,0.04289254,-0.002104307,0.012969063,-0.008310596,0.00423194,0.0074975314,0.0018810473,-0.014248641,-0.024725191,0.0151016945,-0.017527562,0.0018727167,0.0002830318,0.015168339,0.0144219175,-0.004048667,-0.004358565,0.011836103,-0.010343261,-0.005911387,0.0022825818,0.0073175905,0.00403867,0.013188991,0.03334902,0.006111321,0.008597169,0.030123414,-0.015474904,0.0017877447,-0.024551915,0.013155668,0.023525586,-0.0255116,0.017220996,0.004358565,-0.00934359,0.0099967085,0.011162991,0.03092315,-0.021046404,-0.015514892,0.0011946067,-0.01816735,0.010876419,-0.10124666,-0.03550831,0.0056348112,0.013942076,0.005951374,0.020419942,-0.006857742,-0.020873128,-0.021259667,0.0137554705,0.0057880944,-0.029163731,-0.018767154,-0.021392956,0.030896494,-0.005494857,-0.0027307675,-0.006801094,-0.014821786,0.021392956,-0.0018110704,-0.0018843795,-0.012362596,-0.0072176233,-0.017194338,-0.018713837,-0.024272008,0.03801415,0.00015880188,0.0044951867,-0.028630573,-0.0014070367,-0.00916365,-0.026537929,-0.009576847,-0.013995391,-0.0077107945,0.0050016865,0.00578143,-0.04467862,0.008363913,0.010136662,-0.0006268769,-0.006591163,0.015341615,-0.027377652,-0.00093136,0.029243704,-0.020886457,-0.01041657,-0.02424535,0.005291591,-0.02980352,-0.009190307,0.019460259,-0.0041286405,0.004801752,0.0011787785,-0.001257086,-0.011216307,-0.013395589,0.00088137644,-0.0051616337,0.03876057,-0.0033455652,0.00075850025,-0.006951045,-0.0062112883,0.018140694,-0.006351242,-0.008263946,0.018154023,-0.012189319,0.0075508473,-0.044358727,-0.0040153447,0.0093302615,-0.010636497,0.032789204,-0.005264933,-0.014235313,-0.018393943,0.007297597,-0.016114693,0.015021721,0.020033404,0.0137688,0.0011046362,0.010616505,-0.0039453674,0.012109346,0.021099718,-0.0072842683,-0.019153694,-0.003768759,0.039320387,-0.006747778,-0.0016852784,0.018154023,0.0010963057,-0.015035049,-0.021033075,-0.04345236,0.017287642,0.016341286,-0.008610498,0.00236922,0.009290274,0.028950468,-0.014475234,-0.0035654926,0.015434918,-0.03372223,0.004501851,-0.012929076,-0.008483873,-0.0044685286,-0.0102233,0.01615468,0.0022792495,0.010876419,-0.0059647025,0.01895376,-0.0069976957,-0.0042952523,0.017207667,-0.00036133936,0.0085905045,0.008084005,0.03129636,-0.016994404,-0.014915089,0.020100048,-0.012009379,-0.006684466,0.01306903,0.00015765642,-0.00530492,0.0005277429,0.015421589,0.015528221,0.032202728,-0.003485519,-0.0014286962,0.033908837,0.001367883,0.010509873,0.025271678,-0.020993087,0.019846799,0.006897729,-0.010216636,-0.00725761,0.01818068,-0.028443968,-0.011242964,-0.014435247,-0.013688826,0.006101324,-0.0022509254,0.013848773,-0.0019077052,0.017181009,0.03422873,0.005324913,-0.0035188415,0.014128681,-0.004898387,0.005038341,0.0012320944,-0.005561502,-0.017847456,0.0008538855,-0.0047884234,0.011849431,0.015421589,-0.013942076,0.0029790192,-0.013702155,0.0001199605,-0.024431955,0.019926772,0.022179363,-0.016487904,-0.03964028,0.0050849924,0.017487574,0.022792496,0.0012504216,0.004048667,-0.00997005,0.0076041627,-0.014328616,-0.020259995,0.0005598157,-0.010469886,0.0016852784,0.01716768,-0.008990373,-0.001987679,0.026417969,0.023792166,0.0046917885,-0.0071909656,-0.00032051947,-0.023259008,-0.009170313,0.02071318,-0.03156294,-0.030869836,-0.006324584,0.013795458,-0.00047151142,0.016874444,0.00947688,0.00985009,-0.029883493,0.024205362,-0.013522214,-0.015075036,-0.030603256,0.029270362,0.010503208,0.021539574,0.01743426,-0.023898797,0.022019416,-0.0068777353,0.027857494,-0.021259667,0.0025758184,0.006197959,0.006447877,-0.00025200035,-0.004941706,-0.021246338,-0.005504854,-0.008390571,-0.0097301295,0.027244363,-0.04446536,0.05216949,0.010243294,-0.016008062,0.0122493,-0.0199401,0.009077012,0.019753495,0.006431216,-0.037960835,-0.027377652,0.016381273,-0.0038620618,0.022512587,-0.010996379,-0.0015211658,-0.0102233,0.007071005,0.008230623,-0.009490209,-0.010083347,0.024431955,0.002427534,0.02828402,0.0035721571,-0.022192692,-0.011882754,0.010056688,0.0011904413,-0.01426197,-0.017500903,-0.00010985966,0.005591492,-0.0077707744,-0.012049366,0.011869425,0.00858384,-0.024698535,-0.030283362,0.020140035,0.011949399,-0.013968734,0.042732596,-0.011649498,-0.011982721,-0.016967745,-0.0060913274,-0.007130985,-0.013109017,-0.009710136}; + + // Specifies that the vector search will consider the 150 nearest neighbors + // in the specified index + var options = new VectorSearchOptions() + { + IndexName = "vector_index", + NumberOfCandidates = 150 + }; + + // Builds aggregation pipeline and specifies that the $vectorSearch stage + // returns 10 results + var results = queryableCollection + .VectorSearch(m => m.Embedding, vector, 10, options) + .Select(m => new { m.Title, m.Plot }); + +The results of the preceding example contain the following documents: + +.. code-block:: json + + { "_id" : ObjectId("573a13a0f29313caabd04a4f"), "plot" : "A reporter, learning of time travelers visiting 20th century disasters, tries to change the history they know by averting upcoming disasters.", "title" : "Thrill Seekers" } + { "_id" : ObjectId("573a13d8f29313caabda6557"), "plot" : "At the age of 21, Tim discovers he can travel in time and change what happens and has happened in his own life. His decision to make his world a better place by getting a girlfriend turns out not to be as easy as you might think.", "title" : "About Time" } + { "_id" : ObjectId("573a13a5f29313caabd13b4b"), "plot" : "Hoping to alter the events of the past, a 19th century inventor instead travels 800,000 years into the future, where he finds humankind divided into two warring races.", "title" : "The Time Machine" } + { "_id" : ObjectId("573a13aef29313caabd2e2d7"), "plot" : "After using his mother's newly built time machine, Dolf gets stuck involuntary in the year 1212. He ends up in a children's crusade where he confronts his new friends with modern techniques...", "title" : "Crusade in Jeans" } + { "_id" : ObjectId("573a1399f29313caabceec0e"), "plot" : "An officer for a security agency that regulates time travel, must fend for his life against a shady politician who has a tie to his past.", "title" : "Timecop" } + { "_id" : ObjectId("573a1399f29313caabcee36f"), "plot" : "A time-travel experiment in which a robot probe is sent from the year 2073 to the year 1973 goes terribly wrong thrusting one of the project scientists, a man named Nicholas Sinclair into a...", "title" : "A.P.E.X." } + { "_id" : ObjectId("573a13c6f29313caabd715d3"), "plot" : "Agent J travels in time to M.I.B.'s early days in 1969 to stop an alien from assassinating his friend Agent K and changing history.", "title" : "Men in Black 3" } + { "_id" : ObjectId("573a13d4f29313caabd98c13"), "plot" : "Bound by a shared destiny, a teen bursting with scientific curiosity and a former boy-genius inventor embark on a mission to unearth the secrets of a place somewhere in time and space that exists in their collective memory.", "title" : "Tomorrowland" } + { "_id" : ObjectId("573a13b6f29313caabd477fa"), "plot" : "With the help of his uncle, a man travels to the future to try and bring his girlfriend back to life.", "title" : "Love Story 2050" } + { "_id" : ObjectId("573a13e5f29313caabdc40c9"), "plot" : "A dimension-traveling wizard gets stuck in the 21st century because cell-phone radiation interferes with his magic. With his home world on the brink of war, he seeks help from a jaded ...", "title" : "The Portal" } + +For more information about Atlas Vector Search, Atlas Vector Search indexes, and how +to incorporate them into your application, see :atlas:`Atlas Vector Search Overview ` +in the Atlas manual. For more examples about running Atlas Vector Search queries using the +{+driver-short+}, see :atlas:`Run Vector Search Queries ` +in the Atlas manual and select :guilabel:`C#` from the language dropdown. + +Aggregation Operators +--------------------- + +You can use :manual:`aggregation pipeline operators +` in your aggregation stages to modify +documents and perform calculations. + +The following sections describe aggregation operators that you can +implement by using LINQ methods. + +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 + +.. _csharp-linq-convert: + +$convert +~~~~~~~~ + +The ``$convert`` operator converts a value to a specified type. You can +use this operator to perform type conversions in stages such as +``$project``, ``$addFields``, and ``$set``. + +In the driver, you can use the ``Mql.Convert()`` method to +convert a value from one type to a different specified type. To learn +more about conversion behavior and permitted conversions, see the +:manual:`$convert reference ` +in the {+mdb-server+} manual. + +The ``Convert()`` method takes the following parameters: + +- Value to convert. +- ``ConvertOptions`` instance that specifies the type to convert to + and options. Some conversions require you to specify certain options, but + you can also set options to handle errors or null values. + +The following code performs the following actions by using LINQ methods: + +- Converts the ``RestaurantId`` string values to ``int`` values in a + ``Select()`` projection +- Sets the returned value to ``-1`` if an error occurs during conversion +- Sets the returned value to ``0`` if the input value is ``null`` or missing + +.. code-block:: csharp + + var query = queryableCollection + .Select(r => Mql.Convert(r.RestaurantId, new ConvertOptions { OnError = -1, OnNull = 0 })); + +The driver stores the converted values under the original field name in +the output documents. + +Unsupported Aggregation Stages +------------------------------ + +The {+driver-long+} implementation of LINQ does not support the following +aggregation stages: + +- ``$redact`` +- ``$geoNear`` +- ``$out`` + +To learn how to create an aggregation pipeline with the ``$out`` stage by using Builders, see +the :ref:`` section. + +Supported Methods +----------------- + +The following table describes some methods supported by the +{+driver-long+} implementation of LINQ: + +.. list-table:: + :header-rows: 1 + :widths: 40 60 + + * - Method Name + - Description + + * - ``Any`` + - Determines if any documents match the specified criteria + + * - ``Average`` + - Calculates the average of the specified fields + + * - ``Count`` + - Returns an ``Int32`` that represents the number of documents that match the specified criteria + + * - ``LongCount`` + - Returns an ``Int64`` that represents the number of documents that match the specified criteria + + * - ``Convert`` + - Converts a value from one type to a different specified type + + * - ``DateFromString`` + - Converts a ``string`` to a ``DateTime`` object + + * - ``Distinct`` + - Returns distinct documents that match the specified criteria + + * - ``DistinctMany`` + - Returns distinct documents from an array that match the specified criteria + + * - ``Exists`` + - Tests whether a field exists + + * - ``First`` + - Returns the first matching document, and throws an exception if none are found + + * - ``FirstOrDefault`` + - Returns the first matching document, or ``null`` if none are found + + * - ``GroupBy`` + - Groups documents based on specified criteria + + * - ``GroupJoin`` + - Performs a left outer join to another collection in the same database + + * - ``IsMissing`` + - Returns ``true`` if a field is missing and false otherwies + + * - ``IsNullOrMissing`` + - Returns ``true`` if a field is null or missing and false otherwise + + * - ``Max`` + - Returns the document with the maximum specified value + + * - ``OfType`` + - Returns documents that match the specified type + + * - ``OrderBy``, ``OrderByDescending`` + - Returns results in a specified sort order + + * - ``ThenBy``, ``ThenByDescending`` + - Allows a secondary sort to be specified + + * - ``Select`` + - Selects documents based on specified criteria + + * - ``SelectMany`` + - Projects each element of a sequence and combines the resulting sequences into one document + + * - ``Single`` + - Returns the only matching document, and throws an exception if there is not exactly one document + + * - ``SingleOrDefault`` + - Returns a single matching document or ``null`` if no documents match + + * - ``Skip`` + - Skips over a specified number of documents and returns the rest of the results + + * - ``SkipWhile`` (only in ``Select`` projections) + - Skips over array elements while a condition is true and returns + the remaining elements + + * - ``Sum`` + - Returns the sum of the values in a specified field + + * - ``Take`` + - Specifies the number of results to return + + * - ``TakeWhile`` (only in ``Select`` projections) + - Returns array elements while a condition is true and skips + the remaining elements + + * - ``Where`` + - Returns all documents that match your specified criteria + +View Translated Queries +----------------------- + +When you run a LINQ query, the {+driver-short+} automatically translates your +query into an aggregation pipeline written with the {+query-api+}. You can view +the translated query by using the ``ToString()`` method or the +``LoggedStages`` property. + +To see the translated query for **non-scalar operations**, use the ``ToString()`` +method. Non-scalar operations are operations that return a query object, such +as: + +- ``Where`` +- ``Select`` +- ``SelectMany`` +- ``GroupJoin`` + +The following example calls the ``ToString()`` method on a LINQ query and prints +the translated query: + +.. io-code-block:: + + .. input:: + :language: csharp + + var queryableCollection = _restaurantsCollection.AsQueryable(); + var query = queryableCollection + .Where(r => r.Name == "The Movable Feast"); + + var queryTranslated = query.ToString(); + Console.WriteLine(queryTranslated); + + .. output:: + + sample_restaurants.restaurants.Aggregate([{ "$match" : { "name" : "The Movable Feast" } }]) + +To get the translated query for **scalar operations** use the ``LoggedStages`` +property. Scalar operations are operations that return a scalar result rather than a +query object, such as: + +- ``First`` +- ``Sum`` +- ``Count`` +- ``Min`` +- ``Max`` + +To get a translated query with the ``LoggedStages`` property, you must save +the translated query directly after it is executed, and before executing any +other queries with the same queryable object. + +The following example uses the ``LoggedStages`` property on a LINQ query that +uses a scalar operation, then prints the translated query: + +.. io-code-block:: + + .. input:: + :language: csharp + :emphasize-lines: 6 + + + var queryableCollection = _restaurantsCollection.AsQueryable(); + var query = queryableCollection + .Where(r => r.Name == "The Movable Feast"); + + var result = query.FirstOrDefault(); + var queryTranslated = query.LoggedStages; + + Console.WriteLine(queryTranslated.ToJson()); + + .. output:: + + [{ "$match" : { "name" : "The Movable Feast" } }, { "$limit" : NumberLong(1) }] + +.. important:: + + ``LoggedStages`` is not thread-safe. Executing a query and accessing the + associated ``LoggedStages`` property from multiple threads might have + non-deterministic results. + +API Documentation +----------------- + +For a complete list of supported LINQ methods, see the following API documentation: + +- `LINQ <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Linq.html>`__ +- `MongoQueryable + <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Linq.MongoQueryable.html>`__ \ No newline at end of file From 4e6c7badc86686fc44a6378feefaffb7ef67b1d2 Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Fri, 30 May 2025 13:48:57 -0400 Subject: [PATCH 23/35] DOCSP-49876: Add IBsonReader and IBsonWriter info (#641) --- source/data-formats/bson.txt | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/source/data-formats/bson.txt b/source/data-formats/bson.txt index e04523f2..a8f12abd 100644 --- a/source/data-formats/bson.txt +++ b/source/data-formats/bson.txt @@ -6,6 +6,9 @@ BSON Operations .. default-domain:: mongodb +.. meta:: + :keywords: document, BSON, serializer + .. contents:: On this page :local: :backlinks: none @@ -44,7 +47,8 @@ The code samples in this guide use the following BSON document as an example: Create a BSON Document ---------------------- -To build a BSON document in {+language+}, create an instance of the ``BsonDocument`` class. +To build a representation of a BSON document in {+language+}, create an instance of the +``BsonDocument`` class. The ``BsonDocument`` constructor accepts ``BsonElement`` arguments that map to the fields and values in the document. Each ``BsonElement`` can be either an instance of the ``BsonElement`` class or a field-value pair inside curly braces ( ``{}`` ). @@ -212,6 +216,22 @@ BSON document stored in ``myFile.bson``: ``System.IO.Stream`` object. This means that you can read or write any location that can be accessed by a stream. +Read and Write Other Formats +---------------------------- + +The preceding examples show how to read and write BSON data by using the +``BsonBinaryReader`` and ``BsonBinaryWriter`` classes. These classes implement the +``IBsonReader`` and ``IBsonWriter`` interfaces. To read and write data in other formats, +the {+driver-short+} provides the following alternative implementations of the ``IBsonReader`` +and ``IBsonWriter`` interfaces: + +- ``JsonReader`` and ``JsonWriter``: Read and write JSON data +- ``BsonDocumentReader`` and ``BsonDocumentWriter``: Read and write BSON data + contained in a ``BsonDocument`` object + +Because these classes implement the same interfaces, you can call their methods in the same way +as the preceding ``BsonBinaryReader`` and ``BsonBinaryWriter`` examples. + .. _csharp-bson-api: API Documentation @@ -224,3 +244,5 @@ guide, see the following API documentation: - `BsonElement <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonElement.html>`__ - `BsonBinaryReader <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.IO.BsonBinaryReader.html>`__ - `BsonBinaryWriter <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.IO.BsonBinaryWriter.html>`__ +- `IBsonReader <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.IO.IBsonReader.html>`__ +- `IBsonWriter <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.IO.IBsonWriter.html>`__ \ No newline at end of file From ba55cded7b8766a40c56a24c044cdcb57fcdaf59 Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Mon, 2 Jun 2025 14:11:16 -0400 Subject: [PATCH 24/35] DOCSP-50338: Reorganize Data Formats pages (#642) --- config/redirects | 12 +++--- snooty.toml | 3 +- source/data-formats.txt | 41 ------------------- source/data-formats/custom-types.txt | 26 ------------ source/document-formats.txt | 29 +++++++++++++ .../bson.txt | 0 .../extended-json.txt | 0 source/index.txt | 25 +++++++---- .../custom-types => }/serialization.txt | 10 ++++- .../class-mapping.txt | 0 .../{data-formats => serialization}/guids.txt | 0 .../custom-types => serialization}/poco.txt | 0 .../polymorphic-objects.txt | 0 source/{data-formats => }/time-series.txt | 0 14 files changed, 64 insertions(+), 82 deletions(-) delete mode 100644 source/data-formats.txt delete mode 100644 source/data-formats/custom-types.txt create mode 100644 source/document-formats.txt rename source/{data-formats => document-formats}/bson.txt (100%) rename source/{data-formats => document-formats}/extended-json.txt (100%) rename source/{data-formats/custom-types => }/serialization.txt (96%) rename source/{data-formats/custom-types => serialization}/class-mapping.txt (100%) rename source/{data-formats => serialization}/guids.txt (100%) rename source/{data-formats/custom-types => serialization}/poco.txt (100%) rename source/{data-formats/custom-types => serialization}/polymorphic-objects.txt (100%) rename source/{data-formats => }/time-series.txt (100%) diff --git a/config/redirects b/config/redirects index 0f70d847..1e61969b 100644 --- a/config/redirects +++ b/config/redirects @@ -61,8 +61,8 @@ raw: ${prefix}/master -> ${base}/upcoming/ [*-master]: ${prefix}/${version}/fundamentals/gridfs/ -> ${base}/${version}/crud/gridfs/ [*-master]: ${prefix}/${version}/fundamentals/specify-query/ -> ${base}/${version}/crud/query/specify-query/ [*-master]: ${prefix}/${version}/fundamentals/transactions/ -> ${base}/${version}/crud/transactions/ -[*-master]: ${prefix}/${version}/fundamentals/bson/ -> ${base}/${version}/data-formats/bson/ -[*-master]: ${prefix}/${version}/fundamentals/time-series/ -> ${base}/${version}/data-formats/time-series/ +[*-master]: ${prefix}/${version}/fundamentals/bson/ -> ${base}/${version}/document-formats/bson/ +[*-master]: ${prefix}/${version}/fundamentals/time-series/ -> ${base}/${version}/time-series/ [*-master]: ${prefix}/${version}/fundamentals/logging/ -> ${base}/${version}/logging-and-monitoring/logging/ [*-master]: ${prefix}/${version}/fundamentals/monitoring/ -> ${base}/${version}/logging-and-monitoring/monitoring/ [*-master]: ${prefix}/${version}/fundamentals/database-collection/ -> ${base}/${version}/databases-collections/ @@ -82,10 +82,10 @@ raw: ${prefix}/master -> ${base}/upcoming/ [*-master]: ${prefix}/${version}/fundamentals/crud/write-operations/update-one/ -> ${base}/${version}/crud/update-one/ [*-master]: ${prefix}/${version}/fundamentals/crud/write-operations/update-one/arrays/ -> ${base}/${version}/crud/update-one/arrays/ [*-master]: ${prefix}/${version}/fundamentals/crud/write-operations/update-one/fields/ -> ${base}/${version}/crud/update-one/fields/ -[*-master]: ${prefix}/${version}/fundamentals/serialization/class-mapping/ -> ${base}/${version}/data-formats/custom-types/class-mapping/ -[*-master]: ${prefix}/${version}/fundamentals/serialization/poco/ -> ${base}/${version}/data-formats/custom-types/poco/ -[*-master]: ${prefix}/${version}/fundamentals/serialization/polymorphic-objects/ -> ${base}/${version}/data-formats/custom-types/polymorphic-objects/ -[*-master]: ${prefix}/${version}/fundamentals/serialization/ -> ${base}/${version}/data-formats/custom-types/serialization/ +[*-master]: ${prefix}/${version}/fundamentals/serialization/class-mapping/ -> ${base}/${version}/serialization/class-mapping/ +[*-master]: ${prefix}/${version}/fundamentals/serialization/poco/ -> ${base}/${version}/serialization/poco/ +[*-master]: ${prefix}/${version}/fundamentals/serialization/polymorphic-objects/ -> ${base}/${version}/serialization/polymorphic-objects/ +[*-master]: ${prefix}/${version}/fundamentals/serialization/ -> ${base}/${version}/serialization/ [*-master]: ${prefix}/${version}/fundamentals/databases-collections/run-command/ -> ${base}/${version}/run-command/ [*-master]: ${prefix}/${version}/fundamentals/authentication/ -> ${base}/${version}/security/authentication/ [*-master]: ${prefix}/${version}/fundamentals/authentication/aws-iam/ -> ${base}/${version}/security/authentication/aws-iam/ diff --git a/snooty.toml b/snooty.toml index 00aa0586..a97c0c42 100644 --- a/snooty.toml +++ b/snooty.toml @@ -3,7 +3,8 @@ toc_landing_pages = [ "/connect/connection-options", "/security/authentication", "/aggregation", - "/aggregation/stages" + "/aggregation/stages", + "/serialization" ] name = "csharp" title = "C#/.NET" diff --git a/source/data-formats.txt b/source/data-formats.txt deleted file mode 100644 index 7bd3b913..00000000 --- a/source/data-formats.txt +++ /dev/null @@ -1,41 +0,0 @@ -.. _csharp-data-formats: - -======================== -Specialized Data Formats -======================== - -.. contents:: On this page - :local: - :backlinks: none - :depth: 2 - :class: singlecol - -.. facet:: - :name: genre - :values: reference - -.. meta:: - :keywords: bson, guid, serialization, extended json, custom types, time series - -.. toctree:: - :titlesonly: - :maxdepth: 1 - - BSON - Extended JSON - Custom Types - GUIDs - Time Series Data - -Overview --------- - -You can use several types of specialized data formats in your {+driver-short+} -application. To learn how to work with these data formats, see the following -sections: - -- Learn how to work with BSON documents in the :ref:`csharp-bson` guide. -- Learn how to translate BSON to Extended JSON in the :ref:`csharp-extended-json` guide. -- Learn how to serialize custom types in the :ref:`csharp-custom-types` guide. -- Learn about globally unique identifiers (GUIDs) and how to maintain cross-language - compatibility while working with them in the :ref:`csharp-guids` guide. \ No newline at end of file diff --git a/source/data-formats/custom-types.txt b/source/data-formats/custom-types.txt deleted file mode 100644 index d05e1fc3..00000000 --- a/source/data-formats/custom-types.txt +++ /dev/null @@ -1,26 +0,0 @@ -.. _csharp-custom-types: - -============ -Custom Types -============ - -.. contents:: On this page - :local: - :backlinks: none - :depth: 2 - :class: singlecol - -.. facet:: - :name: genre - :values: reference - -.. meta:: - :keywords: polymorphism, serialization, deserialization, poco - -.. toctree:: - :caption: Custom Types - - Class Mapping - POCOs - Polymorphic Objects - Serialization \ No newline at end of file diff --git a/source/document-formats.txt b/source/document-formats.txt new file mode 100644 index 00000000..aec17602 --- /dev/null +++ b/source/document-formats.txt @@ -0,0 +1,29 @@ +.. _csharp-document-formats: + +================ +Document Formats +================ + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: bson, json, object, notation, read, write + +.. toctree:: + :caption: Document Formats + + BSON + Extended JSON + +Learn about using different document formats with the {+driver-short+} in the following guides: + +- :ref:`csharp-bson` +- :ref:`csharp-extended-json` \ No newline at end of file diff --git a/source/data-formats/bson.txt b/source/document-formats/bson.txt similarity index 100% rename from source/data-formats/bson.txt rename to source/document-formats/bson.txt diff --git a/source/data-formats/extended-json.txt b/source/document-formats/extended-json.txt similarity index 100% rename from source/data-formats/extended-json.txt rename to source/document-formats/extended-json.txt diff --git a/source/index.txt b/source/index.txt index 50626999..682b8914 100644 --- a/source/index.txt +++ b/source/index.txt @@ -18,13 +18,15 @@ MongoDB C# Driver Databases & Collections CRUD Operations Aggregation - Data Formats Indexes Run a Database Command Atlas Search Atlas Vector Search + Time Series Logging and Monitoring Security + Serialization + Document Formats Integrations Reference API Documentation <{+api-root+}> @@ -65,12 +67,6 @@ Transform Your Data with Aggregation Learn how to use the {+driver-short+} to perform aggregation operations in the :ref:`csharp-aggregation` section. -Data Formats ------------- - -Learn how to work with specialized data formats and custom types in the -:ref:`csharp-data-formats` section. - Optimize Queries with Indexes ----------------------------- @@ -96,6 +92,11 @@ rather than keyword matches in the `Atlas Vector Search `__ documentation. +Time Series +----------- + +Learn how to work with time series collections in the :ref:`csharp-time-series` section. + Logging and Monitoring ---------------------- @@ -108,6 +109,16 @@ Secure Your Data Learn about ways you can authenticate your application and encrypt your data in the :ref:`csharp-security` section. +Serialization +------------- + +Learn how to serialize and deserialize data in the :ref:`csharp-serialization` section. + +Document Formats +---------------- + +Learn about different notations you can use to read and write data in the :ref:`csharp-document-formats` section. + Reference --------- diff --git a/source/data-formats/custom-types/serialization.txt b/source/serialization.txt similarity index 96% rename from source/data-formats/custom-types/serialization.txt rename to source/serialization.txt index af352a0b..f652628c 100644 --- a/source/data-formats/custom-types/serialization.txt +++ b/source/serialization.txt @@ -16,7 +16,15 @@ Serialization :backlinks: none :depth: 2 :class: singlecol - + +.. toctree:: + :caption: Custom Types + + Class Mapping + POCOs + Polymorphic Objects + GUIDs + Overview -------- diff --git a/source/data-formats/custom-types/class-mapping.txt b/source/serialization/class-mapping.txt similarity index 100% rename from source/data-formats/custom-types/class-mapping.txt rename to source/serialization/class-mapping.txt diff --git a/source/data-formats/guids.txt b/source/serialization/guids.txt similarity index 100% rename from source/data-formats/guids.txt rename to source/serialization/guids.txt diff --git a/source/data-formats/custom-types/poco.txt b/source/serialization/poco.txt similarity index 100% rename from source/data-formats/custom-types/poco.txt rename to source/serialization/poco.txt diff --git a/source/data-formats/custom-types/polymorphic-objects.txt b/source/serialization/polymorphic-objects.txt similarity index 100% rename from source/data-formats/custom-types/polymorphic-objects.txt rename to source/serialization/polymorphic-objects.txt diff --git a/source/data-formats/time-series.txt b/source/time-series.txt similarity index 100% rename from source/data-formats/time-series.txt rename to source/time-series.txt From aca2c08af014a9a38f997535b698ae42e6a74648 Mon Sep 17 00:00:00 2001 From: Rea Rustagi <85902999+rustagir@users.noreply.github.com> Date: Mon, 9 Jun 2025 11:09:43 -0400 Subject: [PATCH 25/35] DOCSP-49745: geoNear agg stage (#645) --- source/aggregation/stages.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/source/aggregation/stages.txt b/source/aggregation/stages.txt index 673d84b4..6efb03fb 100644 --- a/source/aggregation/stages.txt +++ b/source/aggregation/stages.txt @@ -171,6 +171,12 @@ to your pipeline. dimensions, or facets, in a single stage. - ``Facet()`` + * - :manual:`$geoNear ` + - Returns documents in order of nearest to farthest from a + specified point. This method adds a field to output documents + that contains the distance from the specified point. + - ``GeoNear()`` + * - :manual:`$graphLookup ` - Performs a recursive search on a collection. This method adds a new array field to each output document that contains the traversal @@ -354,4 +360,5 @@ following API documentation: - `AggregateOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.AggregateOptions.html>`__ - `EmptyPipelineDefinition <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.EmptyPipelineDefinition-1.-ctor.html>`__ - `BsonDocument <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonDocument.html>`__ -- `PipelineDefinitionBuilder.AppendStage() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.PipelineDefinitionBuilder.AppendStage.html>`__ \ No newline at end of file +- `PipelineDefinitionBuilder.AppendStage() + <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.PipelineDefinitionBuilder.AppendStage.html>`__ From 8b0882983059297cd3743a0f8d404ac81060d93f Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Mon, 16 Jun 2025 09:18:19 -0400 Subject: [PATCH 26/35] DOCSP-49085: Port existing Vector Search page (#643) Created ticket in follow-up epic for Damien's feedback! --- snooty.toml | 1 + source/atlas-vector-search.txt | 300 +++++++++++++----- .../code-examples/MemorySerialization.cs | 37 +++ .../VectorSearchExamples.cs | 51 +++ .../VectorSearchQueryExample.cs | 86 +++++ source/indexes.txt | 2 +- source/serialization.txt | 65 ++++ 7 files changed, 465 insertions(+), 77 deletions(-) create mode 100644 source/includes/fundamentals/code-examples/MemorySerialization.cs create mode 100644 source/includes/fundamentals/code-examples/atlas-vector-search/VectorSearchExamples.cs create mode 100644 source/includes/fundamentals/code-examples/atlas-vector-search/VectorSearchQueryExample.cs diff --git a/snooty.toml b/snooty.toml index a97c0c42..7d9b7198 100644 --- a/snooty.toml +++ b/snooty.toml @@ -44,3 +44,4 @@ not-available = "N/A" analyzer = "MongoDB C# Analyzer" analyzer-short = "C# Analyzer" query-api = "MongoDB Query API" +avs = "Atlas Vector Search" diff --git a/source/atlas-vector-search.txt b/source/atlas-vector-search.txt index 73e37027..0e77f7d2 100644 --- a/source/atlas-vector-search.txt +++ b/source/atlas-vector-search.txt @@ -1,15 +1,15 @@ .. _csharp-atlas-vector-search: -=================== -Atlas Vector Search -=================== +================================ +Run an Atlas Vector Search Query +================================ .. facet:: :name: genre :values: reference - + .. meta:: - :keywords: semantic + :keywords: .NET, search, semantic, AI, RAG .. contents:: On this page :local: @@ -17,83 +17,231 @@ Atlas Vector Search :depth: 2 :class: singlecol -Sample Class ------------- +Overview +-------- + +You can use {+avs+} to perform vector search on your data stored in +Atlas. Vector search allows you to query your data based on semantic meaning +rather than just keyword matches, which helps you retrieve more relevant search +results. It enables your AI-powered applications to support use cases such as +semantic search, hybrid search, and generative search, including +Retrieval-Augmented Generation (RAG). + +By using Atlas as a vector database, you can seamlessly index vector data along +with your other data in Atlas. This allows you to filter on fields in your +collection and perform vector search queries against vector data. You can also +combine vector search with full-text search queries to return the most relevant +results for your use case. You can integrate {+avs+} with popular AI +frameworks and services to easily implement vector search in your applications. + +To learn more about {+avs+}, see the :atlas:`{+avs+} +` guide in the MongoDB Atlas +documentation. -The code examples in this guide demonstrate how you can use builders to -create types to interact with documents in the sample collection ``plants.flowers``. -Documents in this collection are modeled by the following ``Flower`` class: +Sample Data +~~~~~~~~~~~ -.. literalinclude:: /includes/fundamentals/code-examples/builders.cs +The examples in this guide use the ``sample_mflix.embedded_movies`` collection +in the ``sample_mflix`` database. To obtain the sample dataset for this collection, +see :ref:`csharp-get-started`. + +The examples in this guide use the following sample class to model documents in the +``sample_mflix.embedded_movies`` collection: + +.. literalinclude:: /includes/fundamentals/code-examples/atlas-vector-search/VectorSearchQueryExample.cs :language: csharp - :dedent: - :start-after: start-model - :end-before: end-model + :start-after: start-sample-class + :end-before: end-sample-class + +.. _csharp-supported-vector-types: + +Supported Vector Embedding Types +-------------------------------- + +:atlas:`Vector embeddings +` +are vectors you use to represent your data. These embeddings +capture meaningful relationships in your data and enable tasks like semantic +search and retrieval. + +The {+driver-short+} supports vector embeddings of several types. The following +sections describe the supported vector embedding types. + +.. _csharp-vector-array-representation: + +Array Representations +~~~~~~~~~~~~~~~~~~~~~ + +The {+driver-short+} supports the following representations of the array +type in vector embeddings: + +- ``BsonArray`` +- ``Memory`` +- ``ReadOnlyMemory`` +- ``float[]`` and ``double[]`` + +The following example shows a class with properties of the preceding types: + +.. literalinclude:: /includes/fundamentals/code-examples/atlas-vector-search/VectorSearchExamples.cs + :language: csharp + :start-after: start-bson-arrays + :end-before: end-bson-arrays + +.. tip:: + + To learn more about using the ``Memory`` and ``ReadOnlyMemory`` + types, see the :ref:`csharp-array-serialization` section of the + Serialization guide. + +.. _csharp-binary-vector-representation: + +Binary Vector Representations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The {+driver-short+} supports the following binary vector representations in +vector embeddings: + +- ``BinaryVectorFloat32`` (not supported on big-endian architectures) +- ``BinaryVectorInt8`` +- ``BinaryVectorPackedBit`` +- ``Memory``, ``Memory``, ``Memory`` +- ``ReadOnlyMemory``, ``ReadOnlyMemory``, ``ReadOnlyMemory`` +- ``float[]``, ``byte[]``, ``sbyte[]`` + +.. note:: + + You must use the ``BinaryVector`` attribute when specifying binary vector + representations of the ``Memory``, ``ReadOnlyMemory``, or array + types. + +The following example shows a class with properties of the preceding types: -Each builder class takes a generic type parameter -``TDocument`` which represents the type of document that you are working -with. In this guide, the ``Flower`` class is the document type used in -each builder class example. +.. literalinclude:: /includes/fundamentals/code-examples/atlas-vector-search/VectorSearchExamples.cs + :language: csharp + :start-after: start-binary-vectors + :end-before: end-binary-vectors + +Binary Vector Data Serialization +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Perform an Atlas Vector Search ------------------------------- +You can serialize ``Int8`` binary vector typed data as ``byte`` or ``sbyte``. +You can also serialize ``Float32`` binary vector typed data as ``float``. The +following example serializes ``Int8`` and ``Float32`` binary vector data: + +.. literalinclude:: /includes/fundamentals/code-examples/atlas-vector-search/VectorSearchExamples.cs + :language: csharp + :start-after: start-binary-int-float-serialize + :end-before: end-binary-int-float-serialize -You can use builders to create a ``$vectorSearch`` aggregation pipeline stage to perform an -approximate nearest neighbor search on a vector in the specified field. Your collection *must* -have a defined Atlas Vector Search index before you can perform a vector search on your data. +You can deserialize ``PackedBit`` vector data to a :ref:`binary vector +represented ` ``byte`` data type only if the +vector data has a padding value of ``0``. If the vector data has a padding value not +equal to ``0``, you can deserialize it only to a ``BsonVectorPackedBit``. + +Vector Search Query Example +--------------------------- + +You can perform a vector search query by calling the ``VectorSearch()`` method +in an :ref:`aggregation pipeline `. To perform a vector +search on a collection, you must first have a collection with a field that contains +vector data and a vector search index that covers that field. .. tip:: - To obtain the sample dataset used in the following example, see :ref:`csharp-get-started`. - To create the sample Atlas Vector Search index used in the following example, see - :atlas:`Create an Atlas Vector Search Index ` in the - Atlas manual. - -Consider the ``embedded_movies`` collection in the ``sample_mflix`` database. You -can use a ``$vectorSearch`` stage to perform a semantic search on the ``plot_embedding`` -field of the documents in the collection. - -The following example shows how to use builders to generate an aggregation pipeline to -perform the following operations: - -- Performs a vector search on the Atlas Vector Search index of the ``plot_embedding`` field using vector embeddings for the string ``"time travel"`` -- Fetches the ``Title`` and ``Plot`` fields from documents found in the vector search - -.. code-block:: csharp - - // Defines vector embeddings for the string "time travel" - var vector = new[] {-0.0016261312,-0.028070757,-0.011342932,-0.012775794,-0.0027440966,0.008683807,-0.02575152,-0.02020668,-0.010283281,-0.0041719596,0.021392956,0.028657231,-0.006634482,0.007490867,0.018593878,0.0038187427,0.029590257,-0.01451522,0.016061379,0.00008528442,-0.008943722,0.01627464,0.024311995,-0.025911469,0.00022596726,-0.008863748,0.008823762,-0.034921836,0.007910728,-0.01515501,0.035801545,-0.0035688248,-0.020299982,-0.03145631,-0.032256044,-0.028763862,-0.0071576433,-0.012769129,0.012322609,-0.006621153,0.010583182,0.024085402,-0.001623632,0.007864078,-0.021406285,0.002554159,0.012229307,-0.011762793,0.0051682983,0.0048484034,0.018087378,0.024325324,-0.037694257,-0.026537929,-0.008803768,-0.017767483,-0.012642504,-0.0062712682,0.0009771782,-0.010409906,0.017754154,-0.004671795,-0.030469967,0.008477209,-0.005218282,-0.0058480743,-0.020153364,-0.0032805866,0.004248601,0.0051449724,0.006791097,0.007650814,0.003458861,-0.0031223053,-0.01932697,-0.033615597,0.00745088,0.006321252,-0.0038154104,0.014555207,0.027697546,-0.02828402,0.0066711367,0.0077107945,0.01794076,0.011349596,-0.0052715978,0.014755142,-0.019753495,-0.011156326,0.011202978,0.022126047,0.00846388,0.030549942,-0.0041386373,0.018847128,-0.00033655585,0.024925126,-0.003555496,-0.019300312,0.010749794,0.0075308536,-0.018287312,-0.016567878,-0.012869096,-0.015528221,0.0078107617,-0.011156326,0.013522214,-0.020646535,-0.01211601,0.055928253,0.011596181,-0.017247654,0.0005939711,-0.026977783,-0.003942035,-0.009583511,-0.0055248477,-0.028737204,0.023179034,0.003995351,0.0219661,-0.008470545,0.023392297,0.010469886,-0.015874773,0.007890735,-0.009690142,-0.00024970944,0.012775794,0.0114762215,0.013422247,0.010429899,-0.03686786,-0.006717788,-0.027484283,0.011556195,-0.036068123,-0.013915418,-0.0016327957,0.0151016945,-0.020473259,0.004671795,-0.012555866,0.0209531,0.01982014,0.024485271,0.0105431955,-0.005178295,0.033162415,-0.013795458,0.007150979,0.010243294,0.005644808,0.017260984,-0.0045618312,0.0024725192,0.004305249,-0.008197301,0.0014203656,0.0018460588,0.005015015,-0.011142998,0.01439526,0.022965772,0.02552493,0.007757446,-0.0019726837,0.009503538,-0.032042783,0.008403899,-0.04609149,0.013808787,0.011749465,0.036388017,0.016314628,0.021939443,-0.0250051,-0.017354285,-0.012962398,0.00006107364,0.019113706,0.03081652,-0.018114036,-0.0084572155,0.009643491,-0.0034721901,0.0072642746,-0.0090636825,0.01642126,0.013428912,0.027724205,0.0071243206,-0.6858542,-0.031029783,-0.014595194,-0.011449563,0.017514233,0.01743426,0.009950057,0.0029706885,-0.015714826,-0.001806072,0.011856096,0.026444625,-0.0010663156,-0.006474535,0.0016161345,-0.020313311,0.0148351155,-0.0018393943,0.0057347785,0.018300641,-0.018647194,0.03345565,-0.008070676,0.0071443142,0.014301958,0.0044818576,0.003838736,-0.007350913,-0.024525259,-0.001142124,-0.018620536,0.017247654,0.007037683,0.010236629,0.06046009,0.0138887605,-0.012122675,0.037694257,0.0055081863,0.042492677,0.00021784494,-0.011656162,0.010276617,0.022325981,0.005984696,-0.009496873,0.013382261,-0.0010563189,0.0026507939,-0.041639622,0.008637156,0.026471283,-0.008403899,0.024858482,-0.00066686375,-0.0016252982,0.027590916,0.0051449724,0.0058647357,-0.008743787,-0.014968405,0.027724205,-0.011596181,0.0047650975,-0.015381602,0.0043718936,0.002159289,0.035908177,-0.008243952,-0.030443309,0.027564257,0.042625964,-0.0033688906,0.01843393,0.019087048,0.024578573,0.03268257,-0.015608194,-0.014128681,-0.0033538956,-0.0028757197,-0.004121976,-0.032389335,0.0034322033,0.058807302,0.010943064,-0.030523283,0.008903735,0.017500903,0.00871713,-0.0029406983,0.013995391,-0.03132302,-0.019660193,-0.00770413,-0.0038853872,0.0015894766,-0.0015294964,-0.006251275,-0.021099718,-0.010256623,-0.008863748,0.028550599,0.02020668,-0.0012962399,-0.003415542,-0.0022509254,0.0119360695,0.027590916,-0.046971202,-0.0015194997,-0.022405956,0.0016677842,-0.00018535563,-0.015421589,-0.031802863,0.03814744,0.0065411795,0.016567878,-0.015621523,0.022899127,-0.011076353,0.02841731,-0.002679118,-0.002342562,0.015341615,0.01804739,-0.020566562,-0.012989056,-0.002990682,0.01643459,0.00042527664,0.008243952,-0.013715484,-0.004835075,-0.009803439,0.03129636,-0.021432944,0.0012087687,-0.015741484,-0.0052016205,0.00080890034,-0.01755422,0.004811749,-0.017967418,-0.026684547,-0.014128681,0.0041386373,-0.013742141,-0.010056688,-0.013268964,-0.0110630235,-0.028337335,0.015981404,-0.00997005,-0.02424535,-0.013968734,-0.028310679,-0.027750863,-0.020699851,0.02235264,0.001057985,0.00081639783,-0.0099367285,0.013522214,-0.012016043,-0.00086471526,0.013568865,0.0019376953,-0.019020405,0.017460918,-0.023045745,0.008503866,0.0064678704,-0.011509543,0.018727167,-0.003372223,-0.0028690554,-0.0027024434,-0.011902748,-0.012182655,-0.015714826,-0.0098634185,0.00593138,0.018753825,0.0010146659,0.013029044,0.0003521757,-0.017620865,0.04102649,0.00552818,0.024485271,-0.009630162,-0.015608194,0.0006718621,-0.0008418062,0.012395918,0.0057980907,0.016221326,0.010616505,0.004838407,-0.012402583,0.019900113,-0.0034521967,0.000247002,-0.03153628,0.0011038032,-0.020819811,0.016234655,-0.00330058,-0.0032289368,0.00078973995,-0.021952773,-0.022459272,0.03118973,0.03673457,-0.021472929,0.0072109587,-0.015075036,0.004855068,-0.0008151483,0.0069643734,0.010023367,-0.010276617,-0.023019087,0.0068244194,-0.0012520878,-0.0015086699,0.022046074,-0.034148756,-0.0022192693,0.002427534,-0.0027124402,0.0060346797,0.015461575,0.0137554705,0.009230294,-0.009583511,0.032629255,0.015994733,-0.019167023,-0.009203636,0.03393549,-0.017274313,-0.012042701,-0.0009930064,0.026777849,-0.013582194,-0.0027590916,-0.017594207,-0.026804507,-0.0014236979,-0.022032745,0.0091236625,-0.0042419364,-0.00858384,-0.0033905501,-0.020739838,0.016821127,0.022539245,0.015381602,0.015141681,0.028817179,-0.019726837,-0.0051283115,-0.011489551,-0.013208984,-0.0047017853,-0.0072309524,0.01767418,0.0025658219,-0.010323267,0.012609182,-0.028097415,0.026871152,-0.010276617,0.021912785,0.0022542577,0.005124979,-0.0019710176,0.004518512,-0.040360045,0.010969722,-0.0031539614,-0.020366628,-0.025778178,-0.0110030435,-0.016221326,0.0036587953,0.016207997,0.003007343,-0.0032555948,0.0044052163,-0.022046074,-0.0008822095,-0.009363583,0.028230704,-0.024538586,0.0029840174,0.0016044717,-0.014181997,0.031349678,-0.014381931,-0.027750863,0.02613806,0.0004136138,-0.005748107,-0.01868718,-0.0010138329,0.0054348772,0.010703143,-0.003682121,0.0030856507,-0.004275259,-0.010403241,0.021113047,-0.022685863,-0.023032416,0.031429652,0.001792743,-0.005644808,-0.011842767,-0.04078657,-0.0026874484,0.06915057,-0.00056939584,-0.013995391,0.010703143,-0.013728813,-0.022939114,-0.015261642,-0.022485929,0.016807798,0.007964044,0.0144219175,0.016821127,0.0076241563,0.005461535,-0.013248971,0.015301628,0.0085171955,-0.004318578,0.011136333,-0.0059047225,-0.010249958,-0.018207338,0.024645219,0.021752838,0.0007614159,-0.013648839,0.01111634,-0.010503208,-0.0038487327,-0.008203966,-0.00397869,0.0029740208,0.008530525,0.005261601,0.01642126,-0.0038753906,-0.013222313,0.026537929,0.024671877,-0.043505676,0.014195326,0.024778508,0.0056914594,-0.025951454,0.017620865,-0.0021359634,0.008643821,0.021299653,0.0041686273,-0.009017031,0.04044002,0.024378639,-0.027777521,-0.014208655,0.0028623908,0.042119466,0.005801423,-0.028124074,-0.03129636,0.022139376,-0.022179363,-0.04067994,0.013688826,0.013328944,0.0046184794,-0.02828402,-0.0063412455,-0.0046184794,-0.011756129,-0.010383247,-0.0018543894,-0.0018593877,-0.00052024535,0.004815081,0.014781799,0.018007403,0.01306903,-0.020433271,0.009043689,0.033189073,-0.006844413,-0.019766824,-0.018767154,0.00533491,-0.0024575242,0.018727167,0.0058080875,-0.013835444,0.0040719924,0.004881726,0.012029372,0.005664801,0.03193615,0.0058047553,0.002695779,0.009290274,0.02361889,0.017834127,0.0049017193,-0.0036388019,0.010776452,-0.019793482,0.0067777685,-0.014208655,-0.024911797,0.002385881,0.0034988478,0.020899786,-0.0025858153,-0.011849431,0.033189073,-0.021312982,0.024965113,-0.014635181,0.014048708,-0.0035921505,-0.003347231,0.030869836,-0.0017161017,-0.0061346465,0.009203636,-0.025165047,0.0068510775,0.021499587,0.013782129,-0.0024475274,-0.0051149824,-0.024445284,0.006167969,0.0068844,-0.00076183246,0.030150073,-0.0055948244,-0.011162991,-0.02057989,-0.009703471,-0.020646535,0.008004031,0.0066378145,-0.019900113,-0.012169327,-0.01439526,0.0044252095,-0.004018677,0.014621852,-0.025085073,-0.013715484,-0.017980747,0.0071043274,0.011456228,-0.01010334,-0.0035321703,-0.03801415,-0.012036037,-0.0028990454,-0.05419549,-0.024058744,-0.024272008,0.015221654,0.027964126,0.03182952,-0.015354944,0.004855068,0.011522872,0.004771762,0.0027874154,0.023405626,0.0004242353,-0.03132302,0.007057676,0.008763781,-0.0027057757,0.023005757,-0.0071176565,-0.005238275,0.029110415,-0.010989714,0.013728813,-0.009630162,-0.029137073,-0.0049317093,-0.0008630492,-0.015248313,0.0043219104,-0.0055681667,-0.013175662,0.029723546,0.025098402,0.012849103,-0.0009996708,0.03118973,-0.0021709518,0.0260181,-0.020526575,0.028097415,-0.016141351,0.010509873,-0.022965772,0.002865723,0.0020493253,0.0020509914,-0.0041419696,-0.00039695262,0.017287642,0.0038987163,0.014795128,-0.014661839,-0.008950386,0.004431874,-0.009383577,0.0012604183,-0.023019087,0.0029273694,-0.033135757,0.009176978,-0.011023037,-0.002102641,0.02663123,-0.03849399,-0.0044152127,0.0004527676,-0.0026924468,0.02828402,0.017727496,0.035135098,0.02728435,-0.005348239,-0.001467017,-0.019766824,0.014715155,0.011982721,0.0045651635,0.023458943,-0.0010046692,-0.0031373003,-0.0006972704,0.0019043729,-0.018967088,-0.024311995,0.0011546199,0.007977373,-0.004755101,-0.010016702,-0.02780418,-0.004688456,0.013022379,-0.005484861,0.0017227661,-0.015394931,-0.028763862,-0.026684547,0.0030589928,-0.018513903,0.028363993,0.0044818576,-0.009270281,0.038920518,-0.016008062,0.0093902415,0.004815081,-0.021059733,0.01451522,-0.0051583014,0.023765508,-0.017874114,-0.016821127,-0.012522544,-0.0028390652,0.0040886537,0.020259995,-0.031216389,-0.014115352,-0.009176978,0.010303274,0.020313311,0.0064112223,-0.02235264,-0.022872468,0.0052449396,0.0005723116,0.0037321046,0.016807798,-0.018527232,-0.009303603,0.0024858483,-0.0012662497,-0.007110992,0.011976057,-0.007790768,-0.042999174,-0.006727785,-0.011829439,0.007024354,0.005278262,-0.017740825,-0.0041519664,0.0085905045,0.027750863,-0.038387362,0.024391968,0.00087721116,0.010509873,-0.00038508154,-0.006857742,0.0183273,-0.0037054466,0.015461575,0.0017394272,-0.0017944091,0.014181997,-0.0052682655,0.009023695,0.00719763,-0.013522214,0.0034422,0.014941746,-0.0016711164,-0.025298337,-0.017634194,0.0058714002,-0.005321581,0.017834127,0.0110630235,-0.03369557,0.029190388,-0.008943722,0.009363583,-0.0034222065,-0.026111402,-0.007037683,-0.006561173,0.02473852,-0.007084334,-0.010110005,-0.008577175,0.0030439978,-0.022712521,0.0054582027,-0.0012620845,-0.0011954397,-0.015741484,0.0129557345,-0.00042111133,0.00846388,0.008930393,0.016487904,0.010469886,-0.007917393,-0.011762793,-0.0214596,0.000917198,0.021672864,0.010269952,-0.007737452,-0.010243294,-0.0067244526,-0.015488233,-0.021552904,0.017127695,0.011109675,0.038067464,0.00871713,-0.0025591573,0.021312982,-0.006237946,0.034628596,-0.0045251767,0.008357248,0.020686522,0.0010696478,0.0076708077,0.03772091,-0.018700508,-0.0020676525,-0.008923728,-0.023298996,0.018233996,-0.010256623,0.0017860786,0.009796774,-0.00897038,-0.01269582,-0.018527232,0.009190307,-0.02372552,-0.042119466,0.008097334,-0.0066778013,-0.021046404,0.0019593548,0.011083017,-0.0016028056,0.012662497,-0.000059095124,0.0071043274,-0.014675168,0.024831824,-0.053582355,0.038387362,0.0005698124,0.015954746,0.021552904,0.031589597,-0.009230294,-0.0006147976,0.002625802,-0.011749465,-0.034362018,-0.0067844326,-0.018793812,0.011442899,-0.008743787,0.017474247,-0.021619547,0.01831397,-0.009037024,-0.0057247817,-0.02728435,0.010363255,0.034415334,-0.024032086,-0.0020126705,-0.0045518344,-0.019353628,-0.018340627,-0.03129636,-0.0034038792,-0.006321252,-0.0016161345,0.033642255,-0.000056075285,-0.005005019,0.004571828,-0.0024075406,-0.00010215386,0.0098634185,0.1980148,-0.003825407,-0.025191706,0.035161756,0.005358236,0.025111731,0.023485601,0.0023342315,-0.011882754,0.018287312,-0.0068910643,0.003912045,0.009243623,-0.001355387,-0.028603915,-0.012802451,-0.030150073,-0.014795128,-0.028630573,-0.0013487226,0.002667455,0.00985009,-0.0033972147,-0.021486258,0.009503538,-0.017847456,0.013062365,-0.014341944,0.005078328,0.025165047,-0.015594865,-0.025924796,-0.0018177348,0.010996379,-0.02993681,0.007324255,0.014475234,-0.028577257,0.005494857,0.00011725306,-0.013315615,0.015941417,0.009376912,0.0025158382,0.008743787,0.023832154,-0.008084005,-0.014195326,-0.008823762,0.0033455652,-0.032362677,-0.021552904,-0.0056081535,0.023298996,-0.025444955,0.0097301295,0.009736794,0.015274971,-0.0012937407,-0.018087378,-0.0039387033,0.008637156,-0.011189649,-0.00023846315,-0.011582852,0.0066411467,-0.018220667,0.0060846633,0.0376676,-0.002709108,0.0072776037,0.0034188742,-0.010249958,-0.0007747449,-0.00795738,-0.022192692,0.03910712,0.032122757,0.023898797,0.0076241563,-0.007397564,-0.003655463,0.011442899,-0.014115352,-0.00505167,-0.031163072,0.030336678,-0.006857742,-0.022259338,0.004048667,0.02072651,0.0030156737,-0.0042119464,0.00041861215,-0.005731446,0.011103011,0.013822115,0.021512916,0.009216965,-0.006537847,-0.027057758,-0.04054665,0.010403241,-0.0056281467,-0.005701456,-0.002709108,-0.00745088,-0.0024841821,0.009356919,-0.022659205,0.004061996,-0.013175662,0.017074378,-0.006141311,-0.014541878,0.02993681,-0.00028448965,-0.025271678,0.011689484,-0.014528549,0.004398552,-0.017274313,0.0045751603,0.012455898,0.004121976,-0.025458284,-0.006744446,0.011822774,-0.015035049,-0.03257594,0.014675168,-0.0039187097,0.019726837,-0.0047251107,0.0022825818,0.011829439,0.005391558,-0.016781142,-0.0058747325,0.010309938,-0.013049036,0.01186276,-0.0011246296,0.0062112883,0.0028190718,-0.021739509,0.009883412,-0.0073175905,-0.012715813,-0.017181009,-0.016607866,-0.042492677,-0.0014478565,-0.01794076,0.012302616,-0.015194997,-0.04433207,-0.020606548,0.009696807,0.010303274,-0.01694109,-0.004018677,0.019353628,-0.001991011,0.000058938927,0.010536531,-0.17274313,0.010143327,0.014235313,-0.024152048,0.025684876,-0.0012504216,0.036601283,-0.003698782,0.0007310093,0.004165295,-0.0029157067,0.017101036,-0.046891227,-0.017460918,0.022965772,0.020233337,-0.024072073,0.017220996,0.009370248,0.0010363255,0.0194336,-0.019606877,0.01818068,-0.020819811,0.007410893,0.0019326969,0.017887443,0.006651143,0.00067394477,-0.011889419,-0.025058415,-0.008543854,0.021579562,0.0047484366,0.014062037,0.0075508473,-0.009510202,-0.009143656,0.0046817916,0.013982063,-0.0027990784,0.011782787,0.014541878,-0.015701497,-0.029350337,0.021979429,0.01332228,-0.026244693,-0.0123492675,-0.003895384,0.0071576433,-0.035454992,-0.00046984528,0.0033522295,0.039347045,0.0005119148,0.00476843,-0.012995721,0.0024042083,-0.006931051,-0.014461905,-0.0127558,0.0034555288,-0.0074842023,-0.030256703,-0.007057676,-0.00807734,0.007804097,-0.006957709,0.017181009,-0.034575284,-0.008603834,-0.005008351,-0.015834786,0.02943031,0.016861115,-0.0050849924,0.014235313,0.0051449724,0.0025924798,-0.0025741523,0.04289254,-0.002104307,0.012969063,-0.008310596,0.00423194,0.0074975314,0.0018810473,-0.014248641,-0.024725191,0.0151016945,-0.017527562,0.0018727167,0.0002830318,0.015168339,0.0144219175,-0.004048667,-0.004358565,0.011836103,-0.010343261,-0.005911387,0.0022825818,0.0073175905,0.00403867,0.013188991,0.03334902,0.006111321,0.008597169,0.030123414,-0.015474904,0.0017877447,-0.024551915,0.013155668,0.023525586,-0.0255116,0.017220996,0.004358565,-0.00934359,0.0099967085,0.011162991,0.03092315,-0.021046404,-0.015514892,0.0011946067,-0.01816735,0.010876419,-0.10124666,-0.03550831,0.0056348112,0.013942076,0.005951374,0.020419942,-0.006857742,-0.020873128,-0.021259667,0.0137554705,0.0057880944,-0.029163731,-0.018767154,-0.021392956,0.030896494,-0.005494857,-0.0027307675,-0.006801094,-0.014821786,0.021392956,-0.0018110704,-0.0018843795,-0.012362596,-0.0072176233,-0.017194338,-0.018713837,-0.024272008,0.03801415,0.00015880188,0.0044951867,-0.028630573,-0.0014070367,-0.00916365,-0.026537929,-0.009576847,-0.013995391,-0.0077107945,0.0050016865,0.00578143,-0.04467862,0.008363913,0.010136662,-0.0006268769,-0.006591163,0.015341615,-0.027377652,-0.00093136,0.029243704,-0.020886457,-0.01041657,-0.02424535,0.005291591,-0.02980352,-0.009190307,0.019460259,-0.0041286405,0.004801752,0.0011787785,-0.001257086,-0.011216307,-0.013395589,0.00088137644,-0.0051616337,0.03876057,-0.0033455652,0.00075850025,-0.006951045,-0.0062112883,0.018140694,-0.006351242,-0.008263946,0.018154023,-0.012189319,0.0075508473,-0.044358727,-0.0040153447,0.0093302615,-0.010636497,0.032789204,-0.005264933,-0.014235313,-0.018393943,0.007297597,-0.016114693,0.015021721,0.020033404,0.0137688,0.0011046362,0.010616505,-0.0039453674,0.012109346,0.021099718,-0.0072842683,-0.019153694,-0.003768759,0.039320387,-0.006747778,-0.0016852784,0.018154023,0.0010963057,-0.015035049,-0.021033075,-0.04345236,0.017287642,0.016341286,-0.008610498,0.00236922,0.009290274,0.028950468,-0.014475234,-0.0035654926,0.015434918,-0.03372223,0.004501851,-0.012929076,-0.008483873,-0.0044685286,-0.0102233,0.01615468,0.0022792495,0.010876419,-0.0059647025,0.01895376,-0.0069976957,-0.0042952523,0.017207667,-0.00036133936,0.0085905045,0.008084005,0.03129636,-0.016994404,-0.014915089,0.020100048,-0.012009379,-0.006684466,0.01306903,0.00015765642,-0.00530492,0.0005277429,0.015421589,0.015528221,0.032202728,-0.003485519,-0.0014286962,0.033908837,0.001367883,0.010509873,0.025271678,-0.020993087,0.019846799,0.006897729,-0.010216636,-0.00725761,0.01818068,-0.028443968,-0.011242964,-0.014435247,-0.013688826,0.006101324,-0.0022509254,0.013848773,-0.0019077052,0.017181009,0.03422873,0.005324913,-0.0035188415,0.014128681,-0.004898387,0.005038341,0.0012320944,-0.005561502,-0.017847456,0.0008538855,-0.0047884234,0.011849431,0.015421589,-0.013942076,0.0029790192,-0.013702155,0.0001199605,-0.024431955,0.019926772,0.022179363,-0.016487904,-0.03964028,0.0050849924,0.017487574,0.022792496,0.0012504216,0.004048667,-0.00997005,0.0076041627,-0.014328616,-0.020259995,0.0005598157,-0.010469886,0.0016852784,0.01716768,-0.008990373,-0.001987679,0.026417969,0.023792166,0.0046917885,-0.0071909656,-0.00032051947,-0.023259008,-0.009170313,0.02071318,-0.03156294,-0.030869836,-0.006324584,0.013795458,-0.00047151142,0.016874444,0.00947688,0.00985009,-0.029883493,0.024205362,-0.013522214,-0.015075036,-0.030603256,0.029270362,0.010503208,0.021539574,0.01743426,-0.023898797,0.022019416,-0.0068777353,0.027857494,-0.021259667,0.0025758184,0.006197959,0.006447877,-0.00025200035,-0.004941706,-0.021246338,-0.005504854,-0.008390571,-0.0097301295,0.027244363,-0.04446536,0.05216949,0.010243294,-0.016008062,0.0122493,-0.0199401,0.009077012,0.019753495,0.006431216,-0.037960835,-0.027377652,0.016381273,-0.0038620618,0.022512587,-0.010996379,-0.0015211658,-0.0102233,0.007071005,0.008230623,-0.009490209,-0.010083347,0.024431955,0.002427534,0.02828402,0.0035721571,-0.022192692,-0.011882754,0.010056688,0.0011904413,-0.01426197,-0.017500903,-0.00010985966,0.005591492,-0.0077707744,-0.012049366,0.011869425,0.00858384,-0.024698535,-0.030283362,0.020140035,0.011949399,-0.013968734,0.042732596,-0.011649498,-0.011982721,-0.016967745,-0.0060913274,-0.007130985,-0.013109017,-0.009710136}; - - // Specifies that the vector search will consider the 150 nearest neighbors - // in the specified index - var options = new VectorSearchOptions() - { - IndexName = "vector_index", - NumberOfCandidates = 150 - }; - - // Builds aggregation pipeline and specifies that the $vectorSearch stage - // returns 10 results - var pipeline = new EmptyPipelineDefinition() - .VectorSearch(m => m.Embedding, vector, 10, options) - .Project(Builders.Projection - .Include(m => m.Title) - .Include(m => m.Plot)); - -The results of the preceding example contain the following documents: - -.. code-block:: json - - { "_id" : ObjectId("573a13a0f29313caabd04a4f"), "plot" : "A reporter, learning of time travelers visiting 20th century disasters, tries to change the history they know by averting upcoming disasters.", "title" : "Thrill Seekers" } - { "_id" : ObjectId("573a13d8f29313caabda6557"), "plot" : "At the age of 21, Tim discovers he can travel in time and change what happens and has happened in his own life. His decision to make his world a better place by getting a girlfriend turns out not to be as easy as you might think.", "title" : "About Time" } - { "_id" : ObjectId("573a13a5f29313caabd13b4b"), "plot" : "Hoping to alter the events of the past, a 19th century inventor instead travels 800,000 years into the future, where he finds humankind divided into two warring races.", "title" : "The Time Machine" } - { "_id" : ObjectId("573a13aef29313caabd2e2d7"), "plot" : "After using his mother's newly built time machine, Dolf gets stuck involuntary in the year 1212. He ends up in a children's crusade where he confronts his new friends with modern techniques...", "title" : "Crusade in Jeans" } - { "_id" : ObjectId("573a1399f29313caabceec0e"), "plot" : "An officer for a security agency that regulates time travel, must fend for his life against a shady politician who has a tie to his past.", "title" : "Timecop" } - { "_id" : ObjectId("573a1399f29313caabcee36f"), "plot" : "A time-travel experiment in which a robot probe is sent from the year 2073 to the year 1973 goes terribly wrong thrusting one of the project scientists, a man named Nicholas Sinclair into a...", "title" : "A.P.E.X." } - { "_id" : ObjectId("573a13c6f29313caabd715d3"), "plot" : "Agent J travels in time to M.I.B.'s early days in 1969 to stop an alien from assassinating his friend Agent K and changing history.", "title" : "Men in Black 3" } - { "_id" : ObjectId("573a13d4f29313caabd98c13"), "plot" : "Bound by a shared destiny, a teen bursting with scientific curiosity and a former boy-genius inventor embark on a mission to unearth the secrets of a place somewhere in time and space that exists in their collective memory.", "title" : "Tomorrowland" } - { "_id" : ObjectId("573a13b6f29313caabd477fa"), "plot" : "With the help of his uncle, a man travels to the future to try and bring his girlfriend back to life.", "title" : "Love Story 2050" } - { "_id" : ObjectId("573a13e5f29313caabdc40c9"), "plot" : "A dimension-traveling wizard gets stuck in the 21st century because cell-phone radiation interferes with his magic. With his home world on the brink of war, he seeks help from a jaded ...", "title" : "The Portal" } - -To learn more about Atlas Vector Search, see :atlas:`Atlas Vector Search Overview ` -in the Atlas manual. \ No newline at end of file + To learn more about configuring a collection for vector search, see the :atlas:`{+avs+} + ` guide in the MongoDB Atlas + documentation. + +You can convert ``BinaryVectorFloat32``, ``BinaryVectorInt8``, and +``BinaryVectorPackedBit`` data to the ``BsonBinaryData`` type to use in a vector +search query by using the ``ToQueryVector()`` method. The following example +converts ``BinaryVectorInt8`` into a ``BsonBinaryData`` object: + +.. literalinclude:: /includes/fundamentals/code-examples/atlas-vector-search/VectorSearchExamples.cs + :language: csharp + :start-after: start-to-query-vector + :end-before: end-to-query-vector + +You can specify your :ref:`array-represented +` vector data as an instance of the +``QueryVector`` class to use in a vector search query. The following example +creates an array of ``ReadOnlyMemory`` values as a ``QueryVector`` object +to use in a vector search query: + +.. literalinclude:: /includes/fundamentals/code-examples/atlas-vector-search/VectorSearchExamples.cs + :language: csharp + :start-after: start-array-query-vector + :end-before: end-array-query-vector + +Aggregation Pipeline Example +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This example performs the following steps to run an {+avs+} query on a collection that +contains vector data and a vector search index on the ``PlotEmbedding`` field: + +1. Creates an array that contains the :ref:`array-represented + ` vector data to search for +#. Specifies a ``VectorSearchOptions`` object that contains the name of the index + and the number of nearest neighbors to use during the search +#. Creates an aggregation pipeline that uses the ``VectorSearch()`` stage to + perform the vector search query and a ``Project()`` stage to filter the + results +#. Prints the results of the query + +.. literalinclude:: /includes/fundamentals/code-examples/atlas-vector-search/VectorSearchQueryExample.cs + :language: csharp + :dedent: + :start-after: start-search-example + :end-before: end-search-example + :emphasize-lines: 11 + +LINQ Example +~~~~~~~~~~~~ + +The following code sample performs the same vector search query as the preceding example, but uses +the LINQ syntax instead of the aggregation pipeline syntax: + +.. literalinclude:: /includes/fundamentals/code-examples/atlas-vector-search/VectorSearchQueryExample.cs + :language: csharp + :start-after: start-linq-example + :end-before: end-linq-example + :dedent: + :emphasize-lines: 2 + +Builders Example +~~~~~~~~~~~~~~~~ + +The following code sample performs the same vector search query as the preceding example, +but uses builder classes to construct the aggregation pipeline stages: + +.. literalinclude:: /includes/fundamentals/code-examples/atlas-vector-search/VectorSearchQueryExample.cs + :language: csharp + :start-after: start-builders-example + :end-before: end-builders-example + :dedent: + :emphasize-lines: 2 + +Additional Information +---------------------- + +To learn more about {+avs+}, see the :atlas:`{+avs+} +` guide in the MongoDB Atlas +documentation. + +API Documentation +~~~~~~~~~~~~~~~~~ + +To learn more about any of the functions or types discussed in this +guide, see the following API Documentation: + +- `BinaryVectorFloat32 <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BinaryVectorFloat32.html>`__ +- `BinaryVectorInt8 <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BinaryVectorInt8.html>`__ +- `BinaryVectorPackedBit <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BinaryVectorPackedBit.html>`__ +- `QueryVector <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.QueryVector.html>`__ +- `ToQueryVector() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.BinaryVectorDriverExtensions.ToQueryVector.html>`__ +- `IAggregateFluentExtensions.VectorSearch() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IAggregateFluentExtensions.VectorSearch.html>`__ +- `Aggregate() + <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollectionExtensions.Aggregate.html>`__ +- `MongoQueryable.VectorSearch() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Linq.MongoQueryable.VectorSearch.html>`__ +- `PipelineStageDefinitionBuilder.VectorSearch() + <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.PipelineStageDefinitionBuilder.VectorSearch.html>`__ \ No newline at end of file diff --git a/source/includes/fundamentals/code-examples/MemorySerialization.cs b/source/includes/fundamentals/code-examples/MemorySerialization.cs new file mode 100644 index 00000000..00231843 --- /dev/null +++ b/source/includes/fundamentals/code-examples/MemorySerialization.cs @@ -0,0 +1,37 @@ +using MongoDB.Bson;Add commentMore actions +using MongoDB.Bson.Serialization.Conventions; +using MongoDB.Driver; + +public class Program +{ + public static void Main(string[] args) + { + // Replace with your connection string + const string uri = ""; + + var mongoClient = new MongoClient(uri); + var database = mongoClient.GetDatabase("db"); + var _collection = database.GetCollection("lines"); + + var line = new Line + { + X = new Memory(new[] { 1, 2, 3, 4, 5 }), + Y = new ReadOnlyMemory(new[] { 1f, 1.41f, 1.73f, 2f, 2.24f }) + }; + + var filter = Builders.Filter.Empty; + + var result = _collection.Find(filter).FirstOrDefault().ToJson(); + Console.WriteLine(result); + } + +} + +// start-line-class +public class Line +{ + public ObjectId Id { get; set; } + public Memory X { get; set; } + public ReadOnlyMemory Y { get; set; } +} +// end-line-class \ No newline at end of file diff --git a/source/includes/fundamentals/code-examples/atlas-vector-search/VectorSearchExamples.cs b/source/includes/fundamentals/code-examples/atlas-vector-search/VectorSearchExamples.cs new file mode 100644 index 00000000..b3ccce25 --- /dev/null +++ b/source/includes/fundamentals/code-examples/atlas-vector-search/VectorSearchExamples.cs @@ -0,0 +1,51 @@ +// start-bson-arrays +public class BsonArrayVectors +{ + public BsonArray BsonArrayVector { get; set; } + + public Memory MemoryVector { get; set; } + + public ReadOnlyMemory ReadOnlyMemoryVector { get; set; } + + public float[] FloatArrayVector { get; set; } +} +// end-bson-arrays + +// start-binary-vectors +public class BinaryVectors +{ + public BinaryVectorInt8 ValuesInt8 { get; set; } + + public BinaryVectorPackedBit ValuesPackedBit { get; set; } + + public BinaryVectorFloat32 ValuesFloat { get; set; } + + [BinaryVector(BinaryVectorDataType.Int8)] + public Memory ValuesByte { get; set; } + + [BinaryVector(BinaryVectorDataType.Float32)] + public float[] ValuesFloat { get; set; } + +} +// end-binary-vectors + +// start-binary-int-float-serialize +[BinaryVector(BinaryVectorDataType.Int8)] +public Memory ValuesByte { get; set; } + +[BinaryVector(BinaryVectorDataType.Int8)] +public Memory ValuesSByte { get; set; } + +[BinaryVector(BinaryVectorDataType.Float32)] +public float[] ValuesFloat { get; set; } +// end-binary-int-float-serialize + +// start-to-query-vector +var binaryVector = new BinaryVectorInt8(new sbyte[] { 0, 1, 2, 3, 4 }); + +var queryVector = binaryVector.ToQueryVector(); +// end-to-query-vector + +// start-array-query-vector +QueryVector v = new QueryVector(new ReadOnlyMemory([1.2f, 2.3f])); +// end-array-query-vector \ No newline at end of file diff --git a/source/includes/fundamentals/code-examples/atlas-vector-search/VectorSearchQueryExample.cs b/source/includes/fundamentals/code-examples/atlas-vector-search/VectorSearchQueryExample.cs new file mode 100644 index 00000000..badf8283 --- /dev/null +++ b/source/includes/fundamentals/code-examples/atlas-vector-search/VectorSearchQueryExample.cs @@ -0,0 +1,86 @@ +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; +using MongoDB.Bson.Serialization.Conventions; +using MongoDB.Driver; + +namespace CsharpExamples.AtlasSearch; + +public class VectorSearchQuery +{ + + private static IMongoCollection collection; + private static string _mongoConnectionString = ""; + + public static void Main(string[] args) + { + Setup(); + + // start-search-example + QueryVector vector = new[] { -0.0016261312, -0.028070757, -0.011342932, -0.012775794, -0.0027440966, 0.008683807, -0.02575152, -0.02020668, -0.010283281, -0.0041719596, 0.021392956, 0.028657231, -0.006634482, 0.007490867, 0.018593878, 0.0038187427, 0.029590257, -0.01451522, 0.016061379, 0.00008528442, -0.008943722, 0.01627464, 0.024311995, -0.025911469, 0.00022596726, -0.008863748, 0.008823762, -0.034921836, 0.007910728, -0.01515501, 0.035801545, -0.0035688248, -0.020299982, -0.03145631, -0.032256044, -0.028763862, -0.0071576433, -0.012769129, 0.012322609, -0.006621153, 0.010583182, 0.024085402, -0.001623632, 0.007864078, -0.021406285, 0.002554159, 0.012229307, -0.011762793, 0.0051682983, 0.0048484034, 0.018087378, 0.024325324, -0.037694257, -0.026537929, -0.008803768, -0.017767483, -0.012642504, -0.0062712682, 0.0009771782, -0.010409906, 0.017754154, -0.004671795, -0.030469967, 0.008477209, -0.005218282, -0.0058480743, -0.020153364, -0.0032805866, 0.004248601, 0.0051449724, 0.006791097, 0.007650814, 0.003458861, -0.0031223053, -0.01932697, -0.033615597, 0.00745088, 0.006321252, -0.0038154104, 0.014555207, 0.027697546, -0.02828402, 0.0066711367, 0.0077107945, 0.01794076, 0.011349596, -0.0052715978, 0.014755142, -0.019753495, -0.011156326, 0.011202978, 0.022126047, 0.00846388, 0.030549942, -0.0041386373, 0.018847128, -0.00033655585, 0.024925126, -0.003555496, -0.019300312, 0.010749794, 0.0075308536, -0.018287312, -0.016567878, -0.012869096, -0.015528221, 0.0078107617, -0.011156326, 0.013522214, -0.020646535, -0.01211601, 0.055928253, 0.011596181, -0.017247654, 0.0005939711, -0.026977783, -0.003942035, -0.009583511, -0.0055248477, -0.028737204, 0.023179034, 0.003995351, 0.0219661, -0.008470545, 0.023392297, 0.010469886, -0.015874773, 0.007890735, -0.009690142, -0.00024970944, 0.012775794, 0.0114762215, 0.013422247, 0.010429899, -0.03686786, -0.006717788, -0.027484283, 0.011556195, -0.036068123, -0.013915418, -0.0016327957, 0.0151016945, -0.020473259, 0.004671795, -0.012555866, 0.0209531, 0.01982014, 0.024485271, 0.0105431955, -0.005178295, 0.033162415, -0.013795458, 0.007150979, 0.010243294, 0.005644808, 0.017260984, -0.0045618312, 0.0024725192, 0.004305249, -0.008197301, 0.0014203656, 0.0018460588, 0.005015015, -0.011142998, 0.01439526, 0.022965772, 0.02552493, 0.007757446, -0.0019726837, 0.009503538, -0.032042783, 0.008403899, -0.04609149, 0.013808787, 0.011749465, 0.036388017, 0.016314628, 0.021939443, -0.0250051, -0.017354285, -0.012962398, 0.00006107364, 0.019113706, 0.03081652, -0.018114036, -0.0084572155, 0.009643491, -0.0034721901, 0.0072642746, -0.0090636825, 0.01642126, 0.013428912, 0.027724205, 0.0071243206, -0.6858542, -0.031029783, -0.014595194, -0.011449563, 0.017514233, 0.01743426, 0.009950057, 0.0029706885, -0.015714826, -0.001806072, 0.011856096, 0.026444625, -0.0010663156, -0.006474535, 0.0016161345, -0.020313311, 0.0148351155, -0.0018393943, 0.0057347785, 0.018300641, -0.018647194, 0.03345565, -0.008070676, 0.0071443142, 0.014301958, 0.0044818576, 0.003838736, -0.007350913, -0.024525259, -0.001142124, -0.018620536, 0.017247654, 0.007037683, 0.010236629, 0.06046009, 0.0138887605, -0.012122675, 0.037694257, 0.0055081863, 0.042492677, 0.00021784494, -0.011656162, 0.010276617, 0.022325981, 0.005984696, -0.009496873, 0.013382261, -0.0010563189, 0.0026507939, -0.041639622, 0.008637156, 0.026471283, -0.008403899, 0.024858482, -0.00066686375, -0.0016252982, 0.027590916, 0.0051449724, 0.0058647357, -0.008743787, -0.014968405, 0.027724205, -0.011596181, 0.0047650975, -0.015381602, 0.0043718936, 0.002159289, 0.035908177, -0.008243952, -0.030443309, 0.027564257, 0.042625964, -0.0033688906, 0.01843393, 0.019087048, 0.024578573, 0.03268257, -0.015608194, -0.014128681, -0.0033538956, -0.0028757197, -0.004121976, -0.032389335, 0.0034322033, 0.058807302, 0.010943064, -0.030523283, 0.008903735, 0.017500903, 0.00871713, -0.0029406983, 0.013995391, -0.03132302, -0.019660193, -0.00770413, -0.0038853872, 0.0015894766, -0.0015294964, -0.006251275, -0.021099718, -0.010256623, -0.008863748, 0.028550599, 0.02020668, -0.0012962399, -0.003415542, -0.0022509254, 0.0119360695, 0.027590916, -0.046971202, -0.0015194997, -0.022405956, 0.0016677842, -0.00018535563, -0.015421589, -0.031802863, 0.03814744, 0.0065411795, 0.016567878, -0.015621523, 0.022899127, -0.011076353, 0.02841731, -0.002679118, -0.002342562, 0.015341615, 0.01804739, -0.020566562, -0.012989056, -0.002990682, 0.01643459, 0.00042527664, 0.008243952, -0.013715484, -0.004835075, -0.009803439, 0.03129636, -0.021432944, 0.0012087687, -0.015741484, -0.0052016205, 0.00080890034, -0.01755422, 0.004811749, -0.017967418, -0.026684547, -0.014128681, 0.0041386373, -0.013742141, -0.010056688, -0.013268964, -0.0110630235, -0.028337335, 0.015981404, -0.00997005, -0.02424535, -0.013968734, -0.028310679, -0.027750863, -0.020699851, 0.02235264, 0.001057985, 0.00081639783, -0.0099367285, 0.013522214, -0.012016043, -0.00086471526, 0.013568865, 0.0019376953, -0.019020405, 0.017460918, -0.023045745, 0.008503866, 0.0064678704, -0.011509543, 0.018727167, -0.003372223, -0.0028690554, -0.0027024434, -0.011902748, -0.012182655, -0.015714826, -0.0098634185, 0.00593138, 0.018753825, 0.0010146659, 0.013029044, 0.0003521757, -0.017620865, 0.04102649, 0.00552818, 0.024485271, -0.009630162, -0.015608194, 0.0006718621, -0.0008418062, 0.012395918, 0.0057980907, 0.016221326, 0.010616505, 0.004838407, -0.012402583, 0.019900113, -0.0034521967, 0.000247002, -0.03153628, 0.0011038032, -0.020819811, 0.016234655, -0.00330058, -0.0032289368, 0.00078973995, -0.021952773, -0.022459272, 0.03118973, 0.03673457, -0.021472929, 0.0072109587, -0.015075036, 0.004855068, -0.0008151483, 0.0069643734, 0.010023367, -0.010276617, -0.023019087, 0.0068244194, -0.0012520878, -0.0015086699, 0.022046074, -0.034148756, -0.0022192693, 0.002427534, -0.0027124402, 0.0060346797, 0.015461575, 0.0137554705, 0.009230294, -0.009583511, 0.032629255, 0.015994733, -0.019167023, -0.009203636, 0.03393549, -0.017274313, -0.012042701, -0.0009930064, 0.026777849, -0.013582194, -0.0027590916, -0.017594207, -0.026804507, -0.0014236979, -0.022032745, 0.0091236625, -0.0042419364, -0.00858384, -0.0033905501, -0.020739838, 0.016821127, 0.022539245, 0.015381602, 0.015141681, 0.028817179, -0.019726837, -0.0051283115, -0.011489551, -0.013208984, -0.0047017853, -0.0072309524, 0.01767418, 0.0025658219, -0.010323267, 0.012609182, -0.028097415, 0.026871152, -0.010276617, 0.021912785, 0.0022542577, 0.005124979, -0.0019710176, 0.004518512, -0.040360045, 0.010969722, -0.0031539614, -0.020366628, -0.025778178, -0.0110030435, -0.016221326, 0.0036587953, 0.016207997, 0.003007343, -0.0032555948, 0.0044052163, -0.022046074, -0.0008822095, -0.009363583, 0.028230704, -0.024538586, 0.0029840174, 0.0016044717, -0.014181997, 0.031349678, -0.014381931, -0.027750863, 0.02613806, 0.0004136138, -0.005748107, -0.01868718, -0.0010138329, 0.0054348772, 0.010703143, -0.003682121, 0.0030856507, -0.004275259, -0.010403241, 0.021113047, -0.022685863, -0.023032416, 0.031429652, 0.001792743, -0.005644808, -0.011842767, -0.04078657, -0.0026874484, 0.06915057, -0.00056939584, -0.013995391, 0.010703143, -0.013728813, -0.022939114, -0.015261642, -0.022485929, 0.016807798, 0.007964044, 0.0144219175, 0.016821127, 0.0076241563, 0.005461535, -0.013248971, 0.015301628, 0.0085171955, -0.004318578, 0.011136333, -0.0059047225, -0.010249958, -0.018207338, 0.024645219, 0.021752838, 0.0007614159, -0.013648839, 0.01111634, -0.010503208, -0.0038487327, -0.008203966, -0.00397869, 0.0029740208, 0.008530525, 0.005261601, 0.01642126, -0.0038753906, -0.013222313, 0.026537929, 0.024671877, -0.043505676, 0.014195326, 0.024778508, 0.0056914594, -0.025951454, 0.017620865, -0.0021359634, 0.008643821, 0.021299653, 0.0041686273, -0.009017031, 0.04044002, 0.024378639, -0.027777521, -0.014208655, 0.0028623908, 0.042119466, 0.005801423, -0.028124074, -0.03129636, 0.022139376, -0.022179363, -0.04067994, 0.013688826, 0.013328944, 0.0046184794, -0.02828402, -0.0063412455, -0.0046184794, -0.011756129, -0.010383247, -0.0018543894, -0.0018593877, -0.00052024535, 0.004815081, 0.014781799, 0.018007403, 0.01306903, -0.020433271, 0.009043689, 0.033189073, -0.006844413, -0.019766824, -0.018767154, 0.00533491, -0.0024575242, 0.018727167, 0.0058080875, -0.013835444, 0.0040719924, 0.004881726, 0.012029372, 0.005664801, 0.03193615, 0.0058047553, 0.002695779, 0.009290274, 0.02361889, 0.017834127, 0.0049017193, -0.0036388019, 0.010776452, -0.019793482, 0.0067777685, -0.014208655, -0.024911797, 0.002385881, 0.0034988478, 0.020899786, -0.0025858153, -0.011849431, 0.033189073, -0.021312982, 0.024965113, -0.014635181, 0.014048708, -0.0035921505, -0.003347231, 0.030869836, -0.0017161017, -0.0061346465, 0.009203636, -0.025165047, 0.0068510775, 0.021499587, 0.013782129, -0.0024475274, -0.0051149824, -0.024445284, 0.006167969, 0.0068844, -0.00076183246, 0.030150073, -0.0055948244, -0.011162991, -0.02057989, -0.009703471, -0.020646535, 0.008004031, 0.0066378145, -0.019900113, -0.012169327, -0.01439526, 0.0044252095, -0.004018677, 0.014621852, -0.025085073, -0.013715484, -0.017980747, 0.0071043274, 0.011456228, -0.01010334, -0.0035321703, -0.03801415, -0.012036037, -0.0028990454, -0.05419549, -0.024058744, -0.024272008, 0.015221654, 0.027964126, 0.03182952, -0.015354944, 0.004855068, 0.011522872, 0.004771762, 0.0027874154, 0.023405626, 0.0004242353, -0.03132302, 0.007057676, 0.008763781, -0.0027057757, 0.023005757, -0.0071176565, -0.005238275, 0.029110415, -0.010989714, 0.013728813, -0.009630162, -0.029137073, -0.0049317093, -0.0008630492, -0.015248313, 0.0043219104, -0.0055681667, -0.013175662, 0.029723546, 0.025098402, 0.012849103, -0.0009996708, 0.03118973, -0.0021709518, 0.0260181, -0.020526575, 0.028097415, -0.016141351, 0.010509873, -0.022965772, 0.002865723, 0.0020493253, 0.0020509914, -0.0041419696, -0.00039695262, 0.017287642, 0.0038987163, 0.014795128, -0.014661839, -0.008950386, 0.004431874, -0.009383577, 0.0012604183, -0.023019087, 0.0029273694, -0.033135757, 0.009176978, -0.011023037, -0.002102641, 0.02663123, -0.03849399, -0.0044152127, 0.0004527676, -0.0026924468, 0.02828402, 0.017727496, 0.035135098, 0.02728435, -0.005348239, -0.001467017, -0.019766824, 0.014715155, 0.011982721, 0.0045651635, 0.023458943, -0.0010046692, -0.0031373003, -0.0006972704, 0.0019043729, -0.018967088, -0.024311995, 0.0011546199, 0.007977373, -0.004755101, -0.010016702, -0.02780418, -0.004688456, 0.013022379, -0.005484861, 0.0017227661, -0.015394931, -0.028763862, -0.026684547, 0.0030589928, -0.018513903, 0.028363993, 0.0044818576, -0.009270281, 0.038920518, -0.016008062, 0.0093902415, 0.004815081, -0.021059733, 0.01451522, -0.0051583014, 0.023765508, -0.017874114, -0.016821127, -0.012522544, -0.0028390652, 0.0040886537, 0.020259995, -0.031216389, -0.014115352, -0.009176978, 0.010303274, 0.020313311, 0.0064112223, -0.02235264, -0.022872468, 0.0052449396, 0.0005723116, 0.0037321046, 0.016807798, -0.018527232, -0.009303603, 0.0024858483, -0.0012662497, -0.007110992, 0.011976057, -0.007790768, -0.042999174, -0.006727785, -0.011829439, 0.007024354, 0.005278262, -0.017740825, -0.0041519664, 0.0085905045, 0.027750863, -0.038387362, 0.024391968, 0.00087721116, 0.010509873, -0.00038508154, -0.006857742, 0.0183273, -0.0037054466, 0.015461575, 0.0017394272, -0.0017944091, 0.014181997, -0.0052682655, 0.009023695, 0.00719763, -0.013522214, 0.0034422, 0.014941746, -0.0016711164, -0.025298337, -0.017634194, 0.0058714002, -0.005321581, 0.017834127, 0.0110630235, -0.03369557, 0.029190388, -0.008943722, 0.009363583, -0.0034222065, -0.026111402, -0.007037683, -0.006561173, 0.02473852, -0.007084334, -0.010110005, -0.008577175, 0.0030439978, -0.022712521, 0.0054582027, -0.0012620845, -0.0011954397, -0.015741484, 0.0129557345, -0.00042111133, 0.00846388, 0.008930393, 0.016487904, 0.010469886, -0.007917393, -0.011762793, -0.0214596, 0.000917198, 0.021672864, 0.010269952, -0.007737452, -0.010243294, -0.0067244526, -0.015488233, -0.021552904, 0.017127695, 0.011109675, 0.038067464, 0.00871713, -0.0025591573, 0.021312982, -0.006237946, 0.034628596, -0.0045251767, 0.008357248, 0.020686522, 0.0010696478, 0.0076708077, 0.03772091, -0.018700508, -0.0020676525, -0.008923728, -0.023298996, 0.018233996, -0.010256623, 0.0017860786, 0.009796774, -0.00897038, -0.01269582, -0.018527232, 0.009190307, -0.02372552, -0.042119466, 0.008097334, -0.0066778013, -0.021046404, 0.0019593548, 0.011083017, -0.0016028056, 0.012662497, -0.000059095124, 0.0071043274, -0.014675168, 0.024831824, -0.053582355, 0.038387362, 0.0005698124, 0.015954746, 0.021552904, 0.031589597, -0.009230294, -0.0006147976, 0.002625802, -0.011749465, -0.034362018, -0.0067844326, -0.018793812, 0.011442899, -0.008743787, 0.017474247, -0.021619547, 0.01831397, -0.009037024, -0.0057247817, -0.02728435, 0.010363255, 0.034415334, -0.024032086, -0.0020126705, -0.0045518344, -0.019353628, -0.018340627, -0.03129636, -0.0034038792, -0.006321252, -0.0016161345, 0.033642255, -0.000056075285, -0.005005019, 0.004571828, -0.0024075406, -0.00010215386, 0.0098634185, 0.1980148, -0.003825407, -0.025191706, 0.035161756, 0.005358236, 0.025111731, 0.023485601, 0.0023342315, -0.011882754, 0.018287312, -0.0068910643, 0.003912045, 0.009243623, -0.001355387, -0.028603915, -0.012802451, -0.030150073, -0.014795128, -0.028630573, -0.0013487226, 0.002667455, 0.00985009, -0.0033972147, -0.021486258, 0.009503538, -0.017847456, 0.013062365, -0.014341944, 0.005078328, 0.025165047, -0.015594865, -0.025924796, -0.0018177348, 0.010996379, -0.02993681, 0.007324255, 0.014475234, -0.028577257, 0.005494857, 0.00011725306, -0.013315615, 0.015941417, 0.009376912, 0.0025158382, 0.008743787, 0.023832154, -0.008084005, -0.014195326, -0.008823762, 0.0033455652, -0.032362677, -0.021552904, -0.0056081535, 0.023298996, -0.025444955, 0.0097301295, 0.009736794, 0.015274971, -0.0012937407, -0.018087378, -0.0039387033, 0.008637156, -0.011189649, -0.00023846315, -0.011582852, 0.0066411467, -0.018220667, 0.0060846633, 0.0376676, -0.002709108, 0.0072776037, 0.0034188742, -0.010249958, -0.0007747449, -0.00795738, -0.022192692, 0.03910712, 0.032122757, 0.023898797, 0.0076241563, -0.007397564, -0.003655463, 0.011442899, -0.014115352, -0.00505167, -0.031163072, 0.030336678, -0.006857742, -0.022259338, 0.004048667, 0.02072651, 0.0030156737, -0.0042119464, 0.00041861215, -0.005731446, 0.011103011, 0.013822115, 0.021512916, 0.009216965, -0.006537847, -0.027057758, -0.04054665, 0.010403241, -0.0056281467, -0.005701456, -0.002709108, -0.00745088, -0.0024841821, 0.009356919, -0.022659205, 0.004061996, -0.013175662, 0.017074378, -0.006141311, -0.014541878, 0.02993681, -0.00028448965, -0.025271678, 0.011689484, -0.014528549, 0.004398552, -0.017274313, 0.0045751603, 0.012455898, 0.004121976, -0.025458284, -0.006744446, 0.011822774, -0.015035049, -0.03257594, 0.014675168, -0.0039187097, 0.019726837, -0.0047251107, 0.0022825818, 0.011829439, 0.005391558, -0.016781142, -0.0058747325, 0.010309938, -0.013049036, 0.01186276, -0.0011246296, 0.0062112883, 0.0028190718, -0.021739509, 0.009883412, -0.0073175905, -0.012715813, -0.017181009, -0.016607866, -0.042492677, -0.0014478565, -0.01794076, 0.012302616, -0.015194997, -0.04433207, -0.020606548, 0.009696807, 0.010303274, -0.01694109, -0.004018677, 0.019353628, -0.001991011, 0.000058938927, 0.010536531, -0.17274313, 0.010143327, 0.014235313, -0.024152048, 0.025684876, -0.0012504216, 0.036601283, -0.003698782, 0.0007310093, 0.004165295, -0.0029157067, 0.017101036, -0.046891227, -0.017460918, 0.022965772, 0.020233337, -0.024072073, 0.017220996, 0.009370248, 0.0010363255, 0.0194336, -0.019606877, 0.01818068, -0.020819811, 0.007410893, 0.0019326969, 0.017887443, 0.006651143, 0.00067394477, -0.011889419, -0.025058415, -0.008543854, 0.021579562, 0.0047484366, 0.014062037, 0.0075508473, -0.009510202, -0.009143656, 0.0046817916, 0.013982063, -0.0027990784, 0.011782787, 0.014541878, -0.015701497, -0.029350337, 0.021979429, 0.01332228, -0.026244693, -0.0123492675, -0.003895384, 0.0071576433, -0.035454992, -0.00046984528, 0.0033522295, 0.039347045, 0.0005119148, 0.00476843, -0.012995721, 0.0024042083, -0.006931051, -0.014461905, -0.0127558, 0.0034555288, -0.0074842023, -0.030256703, -0.007057676, -0.00807734, 0.007804097, -0.006957709, 0.017181009, -0.034575284, -0.008603834, -0.005008351, -0.015834786, 0.02943031, 0.016861115, -0.0050849924, 0.014235313, 0.0051449724, 0.0025924798, -0.0025741523, 0.04289254, -0.002104307, 0.012969063, -0.008310596, 0.00423194, 0.0074975314, 0.0018810473, -0.014248641, -0.024725191, 0.0151016945, -0.017527562, 0.0018727167, 0.0002830318, 0.015168339, 0.0144219175, -0.004048667, -0.004358565, 0.011836103, -0.010343261, -0.005911387, 0.0022825818, 0.0073175905, 0.00403867, 0.013188991, 0.03334902, 0.006111321, 0.008597169, 0.030123414, -0.015474904, 0.0017877447, -0.024551915, 0.013155668, 0.023525586, -0.0255116, 0.017220996, 0.004358565, -0.00934359, 0.0099967085, 0.011162991, 0.03092315, -0.021046404, -0.015514892, 0.0011946067, -0.01816735, 0.010876419, -0.10124666, -0.03550831, 0.0056348112, 0.013942076, 0.005951374, 0.020419942, -0.006857742, -0.020873128, -0.021259667, 0.0137554705, 0.0057880944, -0.029163731, -0.018767154, -0.021392956, 0.030896494, -0.005494857, -0.0027307675, -0.006801094, -0.014821786, 0.021392956, -0.0018110704, -0.0018843795, -0.012362596, -0.0072176233, -0.017194338, -0.018713837, -0.024272008, 0.03801415, 0.00015880188, 0.0044951867, -0.028630573, -0.0014070367, -0.00916365, -0.026537929, -0.009576847, -0.013995391, -0.0077107945, 0.0050016865, 0.00578143, -0.04467862, 0.008363913, 0.010136662, -0.0006268769, -0.006591163, 0.015341615, -0.027377652, -0.00093136, 0.029243704, -0.020886457, -0.01041657, -0.02424535, 0.005291591, -0.02980352, -0.009190307, 0.019460259, -0.0041286405, 0.004801752, 0.0011787785, -0.001257086, -0.011216307, -0.013395589, 0.00088137644, -0.0051616337, 0.03876057, -0.0033455652, 0.00075850025, -0.006951045, -0.0062112883, 0.018140694, -0.006351242, -0.008263946, 0.018154023, -0.012189319, 0.0075508473, -0.044358727, -0.0040153447, 0.0093302615, -0.010636497, 0.032789204, -0.005264933, -0.014235313, -0.018393943, 0.007297597, -0.016114693, 0.015021721, 0.020033404, 0.0137688, 0.0011046362, 0.010616505, -0.0039453674, 0.012109346, 0.021099718, -0.0072842683, -0.019153694, -0.003768759, 0.039320387, -0.006747778, -0.0016852784, 0.018154023, 0.0010963057, -0.015035049, -0.021033075, -0.04345236, 0.017287642, 0.016341286, -0.008610498, 0.00236922, 0.009290274, 0.028950468, -0.014475234, -0.0035654926, 0.015434918, -0.03372223, 0.004501851, -0.012929076, -0.008483873, -0.0044685286, -0.0102233, 0.01615468, 0.0022792495, 0.010876419, -0.0059647025, 0.01895376, -0.0069976957, -0.0042952523, 0.017207667, -0.00036133936, 0.0085905045, 0.008084005, 0.03129636, -0.016994404, -0.014915089, 0.020100048, -0.012009379, -0.006684466, 0.01306903, 0.00015765642, -0.00530492, 0.0005277429, 0.015421589, 0.015528221, 0.032202728, -0.003485519, -0.0014286962, 0.033908837, 0.001367883, 0.010509873, 0.025271678, -0.020993087, 0.019846799, 0.006897729, -0.010216636, -0.00725761, 0.01818068, -0.028443968, -0.011242964, -0.014435247, -0.013688826, 0.006101324, -0.0022509254, 0.013848773, -0.0019077052, 0.017181009, 0.03422873, 0.005324913, -0.0035188415, 0.014128681, -0.004898387, 0.005038341, 0.0012320944, -0.005561502, -0.017847456, 0.0008538855, -0.0047884234, 0.011849431, 0.015421589, -0.013942076, 0.0029790192, -0.013702155, 0.0001199605, -0.024431955, 0.019926772, 0.022179363, -0.016487904, -0.03964028, 0.0050849924, 0.017487574, 0.022792496, 0.0012504216, 0.004048667, -0.00997005, 0.0076041627, -0.014328616, -0.020259995, 0.0005598157, -0.010469886, 0.0016852784, 0.01716768, -0.008990373, -0.001987679, 0.026417969, 0.023792166, 0.0046917885, -0.0071909656, -0.00032051947, -0.023259008, -0.009170313, 0.02071318, -0.03156294, -0.030869836, -0.006324584, 0.013795458, -0.00047151142, 0.016874444, 0.00947688, 0.00985009, -0.029883493, 0.024205362, -0.013522214, -0.015075036, -0.030603256, 0.029270362, 0.010503208, 0.021539574, 0.01743426, -0.023898797, 0.022019416, -0.0068777353, 0.027857494, -0.021259667, 0.0025758184, 0.006197959, 0.006447877, -0.00025200035, -0.004941706, -0.021246338, -0.005504854, -0.008390571, -0.0097301295, 0.027244363, -0.04446536, 0.05216949, 0.010243294, -0.016008062, 0.0122493, -0.0199401, 0.009077012, 0.019753495, 0.006431216, -0.037960835, -0.027377652, 0.016381273, -0.0038620618, 0.022512587, -0.010996379, -0.0015211658, -0.0102233, 0.007071005, 0.008230623, -0.009490209, -0.010083347, 0.024431955, 0.002427534, 0.02828402, 0.0035721571, -0.022192692, -0.011882754, 0.010056688, 0.0011904413, -0.01426197, -0.017500903, -0.00010985966, 0.005591492, -0.0077707744, -0.012049366, 0.011869425, 0.00858384, -0.024698535, -0.030283362, 0.020140035, 0.011949399, -0.013968734, 0.042732596, -0.011649498, -0.011982721, -0.016967745, -0.0060913274, -0.007130985, -0.013109017, -0.009710136 }; + + var options = new VectorSearchOptions() + { + IndexName = "vector_index", + NumberOfCandidates = 150 + }; + + // Run vector search query + var results = collection.Aggregate() + .VectorSearch(movie => movie.PlotEmbedding, vector, 10, options) + .Project(Builders.Projection + .Include(movie => movie.Title) + .Include(movie => movie.Plot)) + .ToList(); + + // Print the results + foreach (var movie in results) + { + Console.WriteLine(movie.ToJson()); + } + // end-search-example + } + + private static void Setup() + { + // This allows automapping of the camelCase database fields to our models. + var camelCaseConvention = new ConventionPack { new CamelCaseElementNameConvention() }; + ConventionRegistry.Register("CamelCase", camelCaseConvention, type => true); + + // Establish the connection to MongoDB and get the embedded_movies database + var mongoClient = new MongoClient(_mongoConnectionString); + var movieDatabase = mongoClient.GetDatabase("sample_mflix"); + collection = movieDatabase.GetCollection("embedded_movies"); + } + + private static void BuildersExample() + { + // start-builders-example + var pipeline = new EmptyPipelineDefinition() + .VectorSearch(m => m.PlotEmbedding, vector, 10, options) + .Project(Builders.Projection + .Include(m => m.Title) + .Include(m => m.Plot)); + // end-builders-example + } + + private static void LinqExample() + { + // start-linq-example + var results = collection.AsQueryable() + .VectorSearch(m => m.PlotEmbedding, vector, 10, options) + .Select(m => new { m.Title, m.Plot }); + // end-linq-example + } +} + +// start-sample-class +[BsonIgnoreExtraElements] +public class Movie +{ + public ObjectId Id { get; set; } + public string Plot { get; set; } + public string Title { get; set; } + [BsonElement("plot_embedding")] + public float[] PlotEmbedding { get; set; } +} +// end-sample-class \ No newline at end of file diff --git a/source/indexes.txt b/source/indexes.txt index dbc2f98c..57825581 100644 --- a/source/indexes.txt +++ b/source/indexes.txt @@ -86,7 +86,7 @@ and provide sample code for creating each index type. .. note:: - These example uses the ``sample_mflix.movies`` and ``sample_mflix.theaters`` collections + The examples on this page use the ``sample_mflix.movies`` and ``sample_mflix.theaters`` collections from the :atlas:`Atlas sample datasets `. To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see :ref:`csharp-get-started`. diff --git a/source/serialization.txt b/source/serialization.txt index f652628c..101c4ac3 100644 --- a/source/serialization.txt +++ b/source/serialization.txt @@ -184,6 +184,71 @@ Implementing the `IBsonArraySerializer interface enables the driver to access serialization information for individual items in an array. +.. _csharp-array-serialization: + +Improve Array Serialization Performance +--------------------------------------- + +You can improve your application's performance by representing +arrays of primitives as `Memory `__ +and `ReadOnlyMemory `__ +structs instead of by using types such as standard {+language+} arrays or +``BsonArray`` objects. The driver implements fast serialization and +deserialization paths for ``Memory`` and ``ReadOnlyMemory``, which +enhances speed and reduces memory usage. + +.. note:: + + Truncation and overflow checks are not supported for ``Memory`` or + ``ReadOnlyMemory``, but these checks are implemented for standard + arrays. + +You can effect these performance improvements by storing the following +primitive types in ``Memory`` or ``ReadOnlyMemory`` structs: + +- ``bool`` +- ``sbyte`` +- ``byte`` +- ``char`` +- ``short`` +- ``ushort`` +- ``int`` +- ``uint`` +- ``long`` +- ``ulong`` +- ``float`` +- ``double`` +- ``decimal`` + +The following example defines a ``Line`` POCO that contains array fields +modeled by ``Memory`` and ``ReadOnlyMemory`` structs: + +.. literalinclude:: /includes/fundamentals/code-examples/MemorySerialization.cs + :start-after: start-line-class + :end-before: end-line-class + :language: csharp + :dedent: + +The following document represents how a sample ``Line`` object is +represented in MongoDB: + +.. code-block:: json + + { + "_id": ..., + "X": [ 1, 2, 3, 4, 5 ], + "Y": [ 1, 1.409999966621399, 1.7300000190734863, 2, 2.240000009536743 ] + } + +.. tip:: Model Vectors + + :ref:`csharp-atlas-vector-search` involves creating and querying + large numerical arrays. If your application uses + {+avs+}, you might benefit from the performance + improvements from using ``Memory`` and ``ReadOnlyMemory`` to store + array representations of embeddings and query vectors. To learn more, + see :ref:`csharp-supported-vector-types` in the {+avs+} guide. + Additional Information ---------------------- From 6286ca94eb3c35cc3fdf6b76f04be9da83156664 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Tue, 17 Jun 2025 15:10:08 -0500 Subject: [PATCH 27/35] DOCSP-49868 - MongoUrl (#629) --- config/intersphinx.yaml | 2 +- source/atlas-search.txt | 2 +- source/connect/connection-options.txt | 1731 +++++++++++++---- .../connect/connection-options/stable-api.txt | 11 +- source/connect/connection-troubleshooting.txt | 8 +- source/connect/mongoclient.txt | 17 +- source/crud/gridfs.txt | 2 +- source/crud/insert.txt | 10 +- source/crud/query/query-filter.txt | 4 +- source/document-formats/bson.txt | 4 +- .../connection/ConnectionOptions.cs | 855 ++++++++ .../connection/LocalConnectionConfig.cs | 11 - .../connection/MongoClientSettings.cs | 15 - .../connection/MongoClientSettingsConfig.cs | 17 - .../connection-options/allowInsecureTls.rst | 7 + .../connection-options/applicationName.rst | 4 + .../connection-options/compressors.rst | 3 + .../connection-options/connectTimeout.rst | 2 + .../connection-options/directConnection.rst | 8 + .../connection-options/heartbeatInterval.rst | 2 + .../connection-options/heartbeatTimeout.rst | 2 + .../fundamentals/connection-options/ipv6.rst | 1 + .../connection-options/loadBalanced.rst | 9 + .../connection-options/localThreshold.rst | 3 + .../connection-options/maxConnecting.rst | 2 + .../maxConnectionIdleTime.rst | 2 + .../maxConnectionLifetime.rst | 2 + .../maxConnectionPoolSize.rst | 2 + .../minConnectionPoolSize.rst | 3 + .../connection-options/readPreference.rst | 6 + .../connection-options/replicaSetName.rst | 1 + .../connection-options/retryReads.rst | 1 + .../connection-options/retryWrites.rst | 1 + .../connection-options/scheme.rst | 10 + .../connection-options/server.rst | 2 + .../serverMonitoringMode.rst | 8 + .../serverSelectionTimeout.rst | 2 + .../connection-options/servers.rst | 2 + .../connection-options/socketTimeout.rst | 2 + .../connection-options/srvMaxHosts.rst | 7 + .../connection-options/srvServiceName.rst | 8 + .../connection-options/useTls.rst | 3 + .../connection-options/waitQueueTimeout.rst | 2 + source/includes/quick-start/query-output.rst | 2 +- source/indexes.txt | 5 +- source/security/authentication/kerberos.txt | 2 +- source/security/tls-ssl.txt | 4 +- source/serialization.txt | 6 +- source/serialization/class-mapping.txt | 12 +- source/serialization/poco.txt | 7 +- 50 files changed, 2319 insertions(+), 515 deletions(-) create mode 100644 source/includes/fundamentals/code-examples/connection/ConnectionOptions.cs delete mode 100644 source/includes/fundamentals/code-examples/connection/LocalConnectionConfig.cs delete mode 100644 source/includes/fundamentals/code-examples/connection/MongoClientSettings.cs delete mode 100644 source/includes/fundamentals/code-examples/connection/MongoClientSettingsConfig.cs create mode 100644 source/includes/fundamentals/connection-options/allowInsecureTls.rst create mode 100644 source/includes/fundamentals/connection-options/applicationName.rst create mode 100644 source/includes/fundamentals/connection-options/compressors.rst create mode 100644 source/includes/fundamentals/connection-options/connectTimeout.rst create mode 100644 source/includes/fundamentals/connection-options/directConnection.rst create mode 100644 source/includes/fundamentals/connection-options/heartbeatInterval.rst create mode 100644 source/includes/fundamentals/connection-options/heartbeatTimeout.rst create mode 100644 source/includes/fundamentals/connection-options/ipv6.rst create mode 100644 source/includes/fundamentals/connection-options/loadBalanced.rst create mode 100644 source/includes/fundamentals/connection-options/localThreshold.rst create mode 100644 source/includes/fundamentals/connection-options/maxConnecting.rst create mode 100644 source/includes/fundamentals/connection-options/maxConnectionIdleTime.rst create mode 100644 source/includes/fundamentals/connection-options/maxConnectionLifetime.rst create mode 100644 source/includes/fundamentals/connection-options/maxConnectionPoolSize.rst create mode 100644 source/includes/fundamentals/connection-options/minConnectionPoolSize.rst create mode 100644 source/includes/fundamentals/connection-options/readPreference.rst create mode 100644 source/includes/fundamentals/connection-options/replicaSetName.rst create mode 100644 source/includes/fundamentals/connection-options/retryReads.rst create mode 100644 source/includes/fundamentals/connection-options/retryWrites.rst create mode 100644 source/includes/fundamentals/connection-options/scheme.rst create mode 100644 source/includes/fundamentals/connection-options/server.rst create mode 100644 source/includes/fundamentals/connection-options/serverMonitoringMode.rst create mode 100644 source/includes/fundamentals/connection-options/serverSelectionTimeout.rst create mode 100644 source/includes/fundamentals/connection-options/servers.rst create mode 100644 source/includes/fundamentals/connection-options/socketTimeout.rst create mode 100644 source/includes/fundamentals/connection-options/srvMaxHosts.rst create mode 100644 source/includes/fundamentals/connection-options/srvServiceName.rst create mode 100644 source/includes/fundamentals/connection-options/useTls.rst create mode 100644 source/includes/fundamentals/connection-options/waitQueueTimeout.rst diff --git a/config/intersphinx.yaml b/config/intersphinx.yaml index 5cad55e4..3e317721 100644 --- a/config/intersphinx.yaml +++ b/config/intersphinx.yaml @@ -1,4 +1,4 @@ -# Weirdly, giza wants a non-empty list of two or more, so we have to include extraneous/unused one --hence the python +# Weirdly, giza wants a non-empty list of two or more, so we must include extraneous/unused one --hence the python name: python url: https://docs.python.org/2/ path: python2.inv diff --git a/source/atlas-search.txt b/source/atlas-search.txt index 770674ef..c2c946b9 100644 --- a/source/atlas-search.txt +++ b/source/atlas-search.txt @@ -122,7 +122,7 @@ Use the ``Compound()`` method to combine two or more operators into a single search. The following example searches the ``guitars`` collection for any documents -that match all of the following criteria: +that match all the following criteria: - The ``rating`` field exists on the document - The ``in_stock`` field is not ``false`` diff --git a/source/connect/connection-options.txt b/source/connect/connection-options.txt index 2d4198e0..0759047c 100644 --- a/source/connect/connection-options.txt +++ b/source/connect/connection-options.txt @@ -1,8 +1,8 @@ .. _csharp-connection-options: -================== -Connection Options -================== +========================== +Specify Connection Options +========================== .. facet:: :name: genre @@ -18,7 +18,7 @@ Connection Options :class: singlecol .. toctree:: - :caption: Specify Connection Options + :caption: Specify Connection Options Compress Network Traffic Customize Server Selection @@ -27,441 +27,1344 @@ Connection Options Connection Pools Connect from AWS Lambda -This section describes the MongoDB connection and authentication options -available in the {+driver-short+}. You can configure your connection using either -the connection URI or a ``MongoClientSettings`` object. +Overview +-------- + +This page describes the connection options available in the {+driver-short+} and +explains how to apply them to your MongoDB connection. + +How to Specify Connection Options +--------------------------------- + +The following sections describe the ways in which you can specify connection options. .. _csharp-connection-uri: ------------------------- Using the Connection URI ------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~ If you pass a connection URI to the ``MongoClient`` constructor, you can include connection options in the string as ``=`` pairs. In the following example, the connection URI contains the ``connectTimeoutMS`` option with a value of ``60000`` and the ``tls`` option with a value of ``true``: -.. literalinclude:: /includes/fundamentals/code-examples/connection/LocalConnectionConfig.cs +.. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs :language: csharp :dedent: - :start-after: // start local connection config - :end-before: // end local connection config + :start-after: // start-connection-uri + :end-before: // end-connection-uri + +To learn more about the options that you can specify in a connection URI, see +:manual:`Connection String Options ` in the +{+mdb-server+} manual. .. _csharp-mongo-client-settings: ------------------------------ -Using ``MongoClientSettings`` ------------------------------ +Using MongoClientSettings +~~~~~~~~~~~~~~~~~~~~~~~~~ You can use a ``MongoClientSettings`` object to configure connection settings in code rather than in a connection URI. Configuring the connection this way makes it easier to change settings at runtime, helps you catch errors during compilation, and provides more configuration options than the connection URI. -To use a ``MongoClientSettings`` object, create an instance of the class, set -its properties, and pass it as an argument to the ``MongoClient`` constructor: +To set connection options in a ``MongoClientSettings`` object, perform the +following steps: + +1. Create an instance of the ``MongoClientSettings`` class +#. Set properties on the instance to configure the connection +#. Pass the instance to the ``MongoClient`` constructor + +The following code example shows how to perform the preceding steps: + +.. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :dedent: + :start-after: // start-mongo-client-settings + :end-before: // end-mongo-client-settings + +You can also create a ``MongoClientSettings`` object from a connection string by calling the +``MongoClientSettings.FromConnectionString()`` method and passing the connection string, +as shown in the following example. This is useful if you already have a connection string +but want to modify some settings programmatically, or if you must specify settings +that aren't available in the connection string. + +.. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :dedent: + :start-after: // start-from-connection-string + :end-before: // end-from-connection-string + +Alternatively, you can create a ``MongoClientSettings`` object from a ``MongoUrl`` object +by calling the ``MongoClientSettings.FromUrl()`` method and passing the ``MongoUrl`` +object, as shown in the following example. This is useful if you already have a ``MongoUrl`` +object but want to specify settings that aren't available in the ``MongoUrl`` class. -.. literalinclude:: /includes/fundamentals/code-examples/connection/MongoClientSettingsConfig.cs +.. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs :language: csharp :dedent: - :start-after: // start mongo client settings config - :end-before: // end mongo client settings config + :start-after: // start-from-url + :end-before: // end-from-url + +.. _csharp-mongo-url-builder: + +Using MongoUrlBuilder +~~~~~~~~~~~~~~~~~~~~~ + +You can use a ``MongoUrlBuilder`` object to create and configure connection settings on +a ``MongoUrl`` object. A ``MongoUrl`` is a strongly typed representation of a +connection URI, and is useful when reading a connection URI directly from +another source. Using a ``MongoUrl`` object has many of the same advantages as using +a ``MongoClientSettings`` object, although the two classes contain different properties +and methods. + +To use a ``MongoUrlBuilder`` object, create an instance of the class and set the +necessary configuration properties. To create a ``MongoUrl`` object from the +``MongoUrlBuilder``, call the ``MongoUrlBuilder.ToMongoUrl()`` method. You can pass the +``MongoUrl`` object to the ``MongoClient`` constructor. The following code example shows +this process: + +.. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :dedent: 8 + :start-after: // start-mongo-url-builder + :end-before: // end-mongo-url-builder Connection Options ------------------ -The following table lists each connection option available in the -``MongoClientSettings`` class and, if possible, how to achieve the same result in -the connection string. If a ``MongoClientSettings`` property maps to more than one -option in the connection string, the **Connection URI Example** shows all -relevant options. - -.. note:: - - If you're using a query parameter for a time duration, the value must be in - milliseconds. For example, to specify 60 seconds, use the value ``60000``. If you're - using a ``MongoClientSettings`` object for a time duration, use the appropriate - ``TimeSpan`` value. - -.. list-table:: - :header-rows: 1 - :widths: 30 70 - - * - **MongoClientSettings** Property - - Description - - * - **AllowInsecureTls** - - | Specifies whether to relax TLS constraints as much as possible. This can include - | allowing invalid certificates or hostname mismatches. - | - | If this property is set to ``true`` and ``SslSettings.CheckCertificateRevocation`` - | is set to ``false``, the {+driver-short+} will throw an exception. - | - | **Data Type**: {+bool-data-type+} - | **Default**: ``false`` - | **Connection URI Example**: ``tlsInsecure=true`` - - * - **ApplicationName** - - | The app name the driver passes to the server in the client metadata as part of - | the connection handshake. The server prints this value to the MongoDB logs once - | the connection is established. The value is also recorded in the slow query logs - | and profile collections. - | - | **Data Type**: {+string-data-type+} - | **Default**: ``null`` - | **Connection URI Example**: ``appName=yourApp`` - - * - **AutoEncryptionOptions** - - | Settings for automatic client-side encryption. - | - | **Data Type**: `AutoEncryptionOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Encryption.AutoEncryptionOptions.html>`__ - | **Default**: ``null`` - | **Connection URI Example**: {+not-available+} - - * - **ClusterConfigurator** - - | Low-level configuration options for sockets, TLS, cluster, and others. - | - | **Data Type**: Action<`ClusterBuilder <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Core.Configuration.ClusterBuilder.html>`__> - | **Default**: ``null`` - | **Connection URI Example**: {+not-available+} - - * - **Compressors** - - | The preferred compression types, in order, for wire-protocol messages sent to - | or received from the server. The driver uses the first of these compression types - | that the server supports. - | - | **Data Type**: `CompressorConfiguration <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Core.Configuration.CompressorConfiguration.html>`__ - | **Default**: ``null`` - | **Connection URI Example**: ``compressors=snappy,zstd`` - - * - **ConnectTimeout** - - | The length of time the driver tries to establish a single TCP socket connection - | to the server before timing out. - | - | **DataType**: ``TimeSpan`` - | **Default**: 30 seconds - | **Connection URI Example**: ``connectTimeoutMS=0`` - - * - **Credential** - - | Settings for how the driver authenticates to the server. This includes - | authentication credentials, mechanism, source, and other settings. - | - | If you don't specify an authentication mechanism, the driver uses either - | ``SCRAM-SHA-1`` or ``SCRAM-SHA-256``, depending on the server version. See - | :ref:`authentication mechanisms ` for available - | authentication mechanisms. - | - | **Data Type**: `MongoCredential <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.MongoCredential.html>`__ - | **Default**: ``null`` - | **Connection URI Example**: - - .. code-block:: none - :copyable: false - - mongodb://user1:password1&authMechanism=GSSAPI - &authMechanismProperties=SERVICE_NAME:other,REALM:otherrealm - &authSource=$external - - * - **DirectConnection** - - | Specifies whether to force dispatch **all** operations to the host. - | - | If you specify this option, the driver doesn't accept the - | :manual:`DNS seed list connection format. ` - | You must use the :manual:`standard connection URI format ` - | instead. - | - | This property must be set to ``false`` if you specify more than one - | host name. - | - | **Data Type**: {+bool-data-type+} - | **Default**: ``false`` - | **Connection URI Example**: ``directConnection=true`` - - * - **HeartbeatInterval** - - | The interval between regular server-monitoring checks. Must be greater than or - | equal to 500 milliseconds. - | - | **Data Type**: ``TimeSpan`` - | **Default**: 10 seconds - | **Connection URI Example**: ``heartbeatFrequencyMS=5000`` - - * - **HeartbeatTimeout** - - | The length of time a monitoring socket can be idle before timing out. - | - | **Data Type**: ``TimeSpan`` - | **Default**: Same value as ``ConnectTimeout`` - | **Connection URI Example**: ``heartbeatTimeoutMS=5000`` - - * - **IPv6** - - | Specifies whether the host address is in IPv6 format. - | - | **Data Type**: {+bool-data-type+} - | **Default**: ``false`` - | **Connection URI Example**: ``ipv6=true`` - - * - **IsFrozen** - - | Indicates whether the settings have been frozen. Frozen settings can't be changed. - | This option is read-only. - | - | **Data Type**: {+bool-data-type+} - | **Default**: ``false`` - | **Connection URI Example**: {+not-available+} - - * - **LoadBalanced** - - | Specifies whether the driver is connecting to a load balancer. You can set this - | property to ``true`` only if: - - - You specify just one host name. - - You're not connecting to a replica set. - - You're not using the ``SrvMaxHosts`` property. - - You're not using the ``DirectConnection`` property. - - | **Data Type**: {+bool-data-type+} - | **Default**: ``false`` - | **Connection URI Example**: ``loadBalanced=true`` - - * - **LocalThreshold** - - | The latency window for server eligibility. If a server's round trip takes longer - | than the fastest server's round-trip time plus this value, the server isn't - | eligible for selection. - | - | **Data Type**: ``TimeSpan`` - | **Default**: 15 milliseconds - | **Connection URI Example**: ``localThresholdMS=0`` - - * - **LoggingSettings** - - | The settings used for :ref:`logging. ` - | - | **Data Type**: `LoggingSettings <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Core.Configuration.LoggingSettings.html>`__ - | **Default**: ``null`` - | **Connection URI Example**: {+not-available+} - - * - **MaxConnecting** - - | The greatest number of connections a driver's connection pool may be - | establishing concurrently. - | - | **Data Type**: {+int-data-type+} - | **Default**: ``2`` - | **Connection URI Example**: ``maxConnecting=3`` - - * - **MaxConnectionIdleTime** - - | The length of time a connection can be idle before the driver closes it. - | - | **Data Type**: ``TimeSpan`` - | **Default**: 10 minutes - | **Connection URI Example**: ``maxIdleTimeMS=300000`` - - * - **MaxConnectionLifeTime** - - | The length of time a connection can be pooled before expiring. - | - | **Data Type**: ``TimeSpan`` - | **Default**: 30 minutes - | **Connection URI Example**: ``maxLifetimeMS=50000`` - - * - **MaxConnectionPoolSize** - - | The greatest number of clients or connections the driver can create in its - | connection pool. This count includes connections in use. - | - | **Data Type**: {+int-data-type+} - | **Default**: ``100`` - | **Connection URI Example**: ``maxPoolSize=150`` - - * - **MinConnectionPoolSize** - - | The number of connections the driver should create and keep in the connection - | pool even when no operations are occurring. This count includes connections - | in use. - | - | **Data Type**: {+int-data-type+} - | **Default**: ``0`` - | **Connection URI Example**: ``minPoolSize=1`` - - * - **ReadConcern** - - | The client's default read concern. - | See :ref:`read concern ` for more information. - | - | **Data Type**: `ReadConcern <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ReadConcern.html>`__ - | **Default**: ``ReadConcern.Default`` - | **Connection URI Example**: ``readConcernLevel=local`` - - * - **ReadEncoding** - - | The UTF-8 encoding to use for string deserialization. - | Strict encoding will throw an exception when an invalid UTF-8 byte sequence - | is encountered. - | - | **Data Type**: ``UTF8Encoding`` - | **Default**: Strict encoding - | **Connection URI Example**: {+not-available+} - - * - **ReadPreference** - - | The client's default read-preference settings. ``MaxStaleness`` represents the - | longest replication lag, in wall-clock time, that a secondary can experience and - | still be eligible for server selection. Specifying ``-1`` means no maximum. - | See :ref:`read preference ` for more information. - | - | **Data Type**: `ReadPreference <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ReadPreference.html>`__ - | **Default**: ``ReadPreference.Primary`` - | **Connection URI Example**: - - .. code-block:: none - :copyable: false - - readPreference=primaryPreferred - &maxStalenessSeconds=90 - &readPreferenceTags=dc:ny,rack:1 - - | You can include the ``readPreferenceTags`` parameter in the connection URI more - than once. If you do, the client treats each instance as a separate tag set. - The order of the tags in the URI determines the order for read preference. You can - use this parameter only if the read-preference mode is not ``primary``. - - * - **ReplicaSetName** - - | The name of the replica set to connect to. - | - | **Data Type**: {+string-data-type+} - | **Default**: ``null`` - | **Connection URI Example**: ``replicaSet=yourReplicaSet`` - - * - **RetryReads** - - | Enables retryable reads. - | - | **Data Type**: {+bool-data-type+} - | **Default**: ``true`` - | **Connection URI Example**: ``retryReads=false`` - - * - **RetryWrites** - - | Enables retryable writes. - | - | **Data Type**: {+bool-data-type+} - | **Default**: ``true`` - | **Connection URI Example**: ``retryWrites=false`` - - * - **Scheme** - - | Specifies whether to use the standard connection string format (``MongoDB``) - | or the DNS seed list format (``MongoDBPlusSrv``). - | See :manual:`the MongoDB Manual` for more - | information about connection string formats. - | - | If the ``DirectConnection`` property is set to ``true`` and you - | try to use the DNS seed list format, the {+driver-short+} will throw an - | exception. - | - | **Data Type**: `ConnectionStringScheme <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Core.Configuration.ConnectionStringScheme.html>`__ - | **Default**: ``ConnectionStringScheme.MongoDB`` - | **Connection URI Example**: ``mongodb+srv://`` - - * - **Server** - - | The host and port number where MongoDB is running. - | - | **Data Type**: `MongoServerAddress <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.MongoServerAddress.html>`__ - | **Default**: ``localhost:27017`` - | **Connection URI Example**: ``mongodb://sample.host:27017`` - - * - **ServerApi** - - | Allows opting into Stable API versioning. See - | :manual:`the MongoDB Manual` for more information about - | Stable API versioning. - | - | **Data Type**: `ServerApi <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ServerApi.html>`__ - | **Default**: ``null`` - | **Connection URI Example**: {+not-available+} - - * - **ServerMonitoringMode** - - | Specifies the server monitoring protocol to use. When - | this option is set to ``Auto``, the monitoring mode is determined - | by the environment in which the driver is running. The driver - | uses polling mode in function-as-a-service (FaaS) environments, - | such as AWS Lambda, and the streaming mode in other environments. - | - | **Data Type**: `ServerMonitoringMode <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Core.Servers.ServerMonitoringMode.html>`__ - | **Default**: ``Auto`` - | **Connection URI Example**: ``serverMonitoringMode=poll`` - - * - **Servers** - - | The cluster members where MongoDB is running. - | - | **Data Type**: IEnumerable<`MongoServerAddress <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.MongoServerAddress.html>`__> - | **Default**: ``localhost:27017`` - | **Connection URI Example**: ``mongodb://sample.host1:27017,sample.host2:27017`` - - * - **ServerSelectionTimeout** - - | The length of time the driver tries to select a server before timing out. - | - | **Data Type**: ``TimeSpan`` - | **Default**: 30 seconds - | **Connection URI Example**: ``serverSelectionTimeoutMS=15000`` - - * - **SocketTimeout** - - | The length of time the driver tries to send or receive on a socket before - | timing out. - | - | **Data Type**: ``TimeSpan`` - | **Default**: OS default - | **Connection URI Example**: ``socketTimeoutMS=0`` - - * - **SrvMaxHosts** - - | The greatest number of SRV results to randomly select when initially populating - | the seedlist or, during SRV polling, adding new hosts to the topology. - | - | You can use this property only if the connection-string scheme is set - | to ``ConnectionStringScheme.MongoDBPlusSrv``. You cannot use it when connecting - | to a replica set. - | - | **Data Type**: {+int-data-type+} - | **Default**: ``0`` - | **Connection URI Example**: ``srvMaxHosts=3`` - - * - **SslSettings** - - | TLS/SSL options, including client certificates, revocation handling, and - | enabled and disabled TLS/SSL protocols. - | - | If ``SslSettings.CheckCertificateRevocation`` is set to ``false`` and - | ``AllowInsecureTls`` is set to ``true``, the {+driver-short+} will throw - | an exception. - | - | **Data Type**: `SslSettings <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.SslSettings.html>`__ - | **Default**: ``null`` - | **Connection URI Example**: ``tlsDisableCertificateRevocationCheck=false`` - - * - **TranslationOptions** - - | Specifies options, such as the {+mdb-server+} version, for translating LINQ - | queries to the Query API. - | - | **Data Type**: `ExpressionTranslationOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ExpressionTranslationOptions.html>`__ - | **Default**: ``null`` - | **Connection URI Example**: {+not-available+} - - * - **UseTls** - - | Specifies whether to require TLS for connections to the server. If you use - | a scheme of ``"mongodb+srv"`` or specify other TLS options, - | this option defaults to ``true``. - | - | **Data Type**: {+bool-data-type+} - | **Default**: ``false`` - | **Connection URI Example**: ``tls=true`` - - * - **WaitQueueTimeout** - - | The length of time the driver tries to check out a connection from a - | server's connection pool before timing out. - | - | **Data Type**: ``TimeSpan`` - | **Default**: 2 minutes - | **Connection URI Example**: ``waitQueueTimeoutMS=0`` - - * - **WriteConcern** - - | The default write-concern settings, including write timeout and - | journaling, for the client. - | See :ref:`write concern ` for more information. - | - | **Data Type**: `WriteConcern <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.WriteConcern.html>`__ - | **Default**: ``WriteConcern.Acknowledged`` - | **Connection URI Example**: ``w=majority&wTimeoutMS=0&journal=true`` - - * - **WriteEncoding** - - | Specifies whether UTF-8 string serialization is strict or lenient. With strict - | encoding, the driver will throw an exception when it encounters an invalid - | UTF-8 byte sequence. - | - | **Data Type**: ``UTF8Encoding`` - | **Default**: Strict encoding - | **Connection URI Example**: {+not-available+} +The following sections describe the connection options available in the +{+driver-short+} and how to specify them by using a ``MongoClientSettings`` or +``MongoUrlBuilder`` object. + +.. _csharp-replica-set-options: + +Replica Set Options +~~~~~~~~~~~~~~~~~~~ + +.. tabs:: + + .. tab:: MongoClientSettings + :tabid: mongo-client-settings + + DirectConnection + ```````````````` + + .. include:: /includes/fundamentals/connection-options/directConnection.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-direct-connection + :end-before: // end-settings-direct-connection + + ReplicaSetName + `````````````` + + .. include:: /includes/fundamentals/connection-options/replicaSetName.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-replica-set-name + :end-before: // end-settings-replica-set-name + + .. tab:: MongoUrlBuilder + :tabid: mongo-url-builder + + DirectConnection + ```````````````` + + .. include:: /includes/fundamentals/connection-options/directConnection.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-direct-connection + :end-before: // end-builder-direct-connection + + ReplicaSetName + `````````````` + + .. include:: /includes/fundamentals/connection-options/replicaSetName.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-replica-set-name + :end-before: // end-builder-replica-set-name + +TLS Options +~~~~~~~~~~~ + +.. tabs:: + + .. tab:: MongoClientSettings + :tabid: mongo-client-settings + + AllowInsecureTls + ```````````````` + + .. include:: /includes/fundamentals/connection-options/allowInsecureTls.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-allow-insecure-tls + :end-before: // end-settings-allow-insecure-tls + + SslSettings + ``````````` + + TLS/SSL options, including client certificates, revocation handling, and + enabled and disabled TLS/SSL protocols. The default value is ``null``. + + If ``SslSettings.CheckCertificateRevocation`` is set to ``false`` and + ``AllowInsecureTls`` is set to ``true``, the {+driver-short+} throws + an exception. + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-ssl-settings + :end-before: // end-settings-ssl-settings + + UseTls + `````` + + .. include:: /includes/fundamentals/connection-options/useTls.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-use-tls + :end-before: // end-settings-use-tls + + .. tab:: MongoUrlBuilder + :tabid: mongo-url-builder + + AllowInsecureTls + ```````````````` + + .. include:: /includes/fundamentals/connection-options/allowInsecureTls.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-allow-insecure-tls + :end-before: // end-builder-allow-insecure-tls + + TlsDisableCertificateRevocationCheck + ```````````````````````````````````` + + Whether to disable certificate revocation checking during the TLS handshake. The + default value is ``false``. + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-tls-disable + :end-before: // end-builder-tls-disable + + UseTls + `````` + + .. include:: /includes/fundamentals/connection-options/useTls.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-use-tls + :end-before: // end-builder-use-tls + +Timeout Options +~~~~~~~~~~~~~~~ + +.. tabs:: + + .. tab:: MongoClientSettings + :tabid: mongo-client-settings + + ConnectTimeout + `````````````` + + .. include:: /includes/fundamentals/connection-options/connectTimeout.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-connect-timeout + :end-before: // end-settings-connect-timeout + + SocketTimeout + ````````````` + + .. include:: /includes/fundamentals/connection-options/socketTimeout.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-connect-timeout + :end-before: // end-settings-connect-timeout + + .. tab:: MongoUrlBuilder + :tabid: mongo-url-builder + + ConnectTimeout + `````````````` + + .. include:: /includes/fundamentals/connection-options/connectTimeout.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-connect-timeout + :end-before: // end-builder-connect-timeout + + SocketTimeout + ````````````` + + .. include:: /includes/fundamentals/connection-options/socketTimeout.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-socket-timeout + :end-before: // end-builder-socket-timeout + +Compression Options +~~~~~~~~~~~~~~~~~~~ + +.. tabs:: + + .. tab:: MongoClientSettings + :tabid: mongo-client-settings + + Compressors + ``````````` + + .. include:: /includes/fundamentals/connection-options/compressors.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-compressors + :end-before: // end-settings-compressors + + .. tab:: MongoUrlBuilder + :tabid: mongo-url-builder + + Compressors + ``````````` + + .. include:: /includes/fundamentals/connection-options/compressors.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-compressors + :end-before: // end-builder-compressors + +Connection Pool Options +~~~~~~~~~~~~~~~~~~~~~~~ + +.. tabs:: + + .. tab:: MongoClientSettings + :tabid: mongo-client-settings + + MaxConnecting + ````````````` + + .. include:: /includes/fundamentals/connection-options/maxConnecting.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-max-connecting + :end-before: // end-settings-max-connecting + + MaxConnectionIdleTime + ````````````````````` + + .. include:: /includes/fundamentals/connection-options/maxConnectionIdleTime.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-max-connection-idle-time + :end-before: // end-settings-max-connection-idle-time + + MaxConnectionLifeTime + ````````````````````` + + .. include:: /includes/fundamentals/connection-options/maxConnectionLifetime.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-max-connection-life-time + :end-before: // end-settings-max-connection-life-time + + MaxConnectionPoolSize + ````````````````````` + + .. include:: /includes/fundamentals/connection-options/maxConnectionPoolSize.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-max-connection-pool-size + :end-before: // end-settings-max-connection-pool-size + + MinConnectionPoolSize + ````````````````````` + + .. include:: /includes/fundamentals/connection-options/minConnectionPoolSize.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-min-connection-pool-size + :end-before: // end-settings-min-connection-pool-size + + WaitQueueTimeout + ```````````````` + + .. include:: /includes/fundamentals/connection-options/waitQueueTimeout.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-wait-queue-timeout + :end-before: // end-settings-wait-queue-timeout + + .. tab:: MongoUrlBuilder + :tabid: mongo-url-builder + + MaxConnecting + ````````````` + + .. include:: /includes/fundamentals/connection-options/maxConnecting.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-max-connecting + :end-before: // end-builder-max-connecting + + MaxConnectionIdleTime + ````````````````````` + + .. include:: /includes/fundamentals/connection-options/maxConnectionIdleTime.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-max-connection-idle-time + :end-before: // end-builder-max-connection-idle-time + + MaxConnectionLifeTime + ````````````````````` + + .. include:: /includes/fundamentals/connection-options/maxConnectionLifetime.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-max-connection-life-time + :end-before: // end-builder-max-connection-life-time + + MaxConnectionPoolSize + ````````````````````` + + .. include:: /includes/fundamentals/connection-options/maxConnectionPoolSize.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-max-connection-pool-size + :end-before: // end-builder-max-connection-pool-size + + MinConnectionPoolSize + ````````````````````` + + .. include:: /includes/fundamentals/connection-options/minConnectionPoolSize.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-min-connection-pool-size + :end-before: // end-builder-min-connection-pool-size + + WaitQueueTimeout + ```````````````` + + .. include:: /includes/fundamentals/connection-options/waitQueueTimeout.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-wait-queue-timeout + :end-before: // end-builder-wait-queue-timeout + +Write Concern Options +~~~~~~~~~~~~~~~~~~~~~ + +.. tabs:: + + .. tab:: MongoClientSettings + :tabid: mongo-client-settings + + WriteConcern + ```````````` + + The default write-concern settings, including write timeout and + journaling, for the client. The default value is ``WriteConcern.Acknowledged``. + See :manual:`Write Concern ` in the + {+mdb-server+} manual for more information. + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-write-concern + :end-before: // end-settings-write-concern + + .. tab:: MongoUrlBuilder + :tabid: mongo-url-builder + + FSync + ````` + + The FSync component of the write concern. The default value is ``false``. To learn + more about the ``fsync`` command, see :manual:`fsync ` + in the {+mdb-server+} manual. + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-fsync + :end-before: // end-builder-fsync + + Journal + ``````` + + The ``j`` component of the write concern, which requests acknowledgment that the + MongoDB instances have written to the on-disk journal. The default value depends on + the value in the ``writeConcernMajorityJournalDefault`` setting. To learn more about the + ``j`` option, see :manual:`Write Concern ` + in the {+mdb-server+} manual. + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-journal + :end-before: // end-builder-journal + + W + `` + + The ``w`` component of the write concern, which requests acknowledgment that the write + operation has propagated to a specified number of MongoDB instances. The default + value is ``"majority"`` or ``1``, depending on the number of arbiters and voting nodes. + To learn more about the ``w`` option, see :manual:`Write Concern ` + in the {+mdb-server+} manual. + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-w + :end-before: // end-builder-w + + WTimeout + ```````` + + The ``wtimeout`` component of the write concern, which specifies a time limit for the + write concern. To learn more about the ``wtimeout`` option, see + :manual:`Write Concern ` + in the {+mdb-server+} manual. + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-w-timeout + :end-before: // end-builder-w-timeout + +Read Concern Options +~~~~~~~~~~~~~~~~~~~~ + +.. tabs:: + + .. tab:: MongoClientSettings + :tabid: mongo-client-settings + + ReadConcern + ``````````` + + The client's read concern. The default value is ``ReadConcern.Default``. + For more information, see :manual:`Read Concern ` in the + {+mdb-server+} manual. + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-read-concern + :end-before: // end-settings-read-concern + + .. tab:: MongoUrlBuilder + :tabid: mongo-url-builder + + ReadConcernLevel + ```````````````` + + The client's read concern level. The default value is ``ReadConcern.Local``. + For more information, see :ref:`read concern `. + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-read-concern-level + :end-before: // end-builder-read-concern-level + +Read Preference Options +~~~~~~~~~~~~~~~~~~~~~~~ + +.. tabs:: + + .. tab:: MongoClientSettings + :tabid: mongo-client-settings + + ReadPreference + `````````````` + + .. include:: /includes/fundamentals/connection-options/readPreference.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-read-preference + :end-before: // end-settings-read-preference + + .. tab:: MongoUrlBuilder + :tabid: mongo-url-builder + + .. include:: /includes/fundamentals/connection-options/readPreference.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-read-preference + :end-before: // end-builder-read-preference + +Authentication Options +~~~~~~~~~~~~~~~~~~~~~~ + +.. tabs:: + + .. tab:: MongoClientSettings + :tabid: mongo-client-settings + + Credential + `````````` + + Settings for how the driver authenticates to the server. This includes + authentication credentials, mechanism, source, and other settings. The default + value is ``null``. + + If you don't specify an authentication mechanism, the driver uses either + ``SCRAM-SHA-1`` or ``SCRAM-SHA-256``, depending on the server version. See + :ref:`Authentication Mechanisms ` for available + authentication mechanisms. + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-credential + :end-before: // end-settings-credential + + .. tab:: MongoUrlBuilder + :tabid: mongo-url-builder + + AuthenticationMechanism + ``````````````````````` + + The mechanism that the driver uses to authenticate to {+mdb-server+}. + If you don't specify an authentication mechanism, the driver uses either + ``SCRAM-SHA-1`` or ``SCRAM-SHA-256``, depending on the server version. See + :ref:`authentication mechanisms ` for available + authentication mechanisms. + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-authentication + :end-before: // end-builder-authentication + :emphasize-lines: 3 + + AuthenticationMechanismProperties + ````````````````````````````````` + + Configuration settings for the authentication mechanism specified in the + ``AuthenticationMechanism`` property. + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-authentication + :end-before: // end-builder-authentication + :emphasize-lines: 4-8 + + AuthenticationSource + ```````````````````` + + The source to authenticate the client against. + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-authentication + :end-before: // end-builder-authentication + :emphasize-lines: 9 + + Password + ```````` + + The password to use for authentication. + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-username-password + :end-before: // end-builder-username-password + :emphasize-lines: 4 + + Username + ```````` + + The username to use for authentication. + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-username-password + :end-before: // end-builder-username-password + :emphasize-lines: 3 + +Server Selection and Discovery Options +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. tabs:: + + .. tab:: MongoClientSettings + :tabid: mongo-client-settings + + HeartbeatInterval + ````````````````` + + .. include:: /includes/fundamentals/connection-options/heartbeatInterval.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-heartbeat-interval + :end-before: // end-settings-heartbeat-interval + + HeartbeatTimeout + ```````````````` + + .. include:: /includes/fundamentals/connection-options/heartbeatTimeout.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-heartbeat-timeout + :end-before: // end-settings-heartbeat-timeout + + LocalThreshold + `````````````` + + .. include:: /includes/fundamentals/connection-options/localThreshold.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-local-threshold + :end-before: // end-settings-local-threshold + + ServerSelectionTimeout + `````````````````````` + + .. include:: /includes/fundamentals/connection-options/localThreshold.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-server-selection-timeout + :end-before: // end-settings-server-selection-timeout + + .. tab:: MongoUrlBuilder + :tabid: mongo-url-builder + + HeartbeatInterval + ````````````````` + + .. include:: /includes/fundamentals/connection-options/heartbeatInterval.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-heartbeat-interval + :end-before: // end-builder-heartbeat-interval + + HeartbeatTimeout + ```````````````` + + .. include:: /includes/fundamentals/connection-options/heartbeatTimeout.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-heartbeat-timeout + :end-before: // end-builder-heartbeat-timeout + + LocalThreshold + `````````````` + + .. include:: /includes/fundamentals/connection-options/localThreshold.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-local-threshold + :end-before: // end-builder-local-threshold + + ServerSelectionTimeout + `````````````````````` + + .. include:: /includes/fundamentals/connection-options/localThreshold.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-server-selection-timeout + :end-before: // end-builder-server-selection-timeout + +Encoding Options +~~~~~~~~~~~~~~~~ + +ReadEncoding +```````````` + +The UTF-8 encoding to use for string deserialization. The default value is +strict encoding, where the driver throws an exception when it encounters an invalid +UTF-8 byte sequence + +.. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-read-encoding + :end-before: // end-settings-read-encoding + +WriteEncoding +````````````` + +The UTF-8 encoding to use for string serialization. The default value is +strict encoding, where the driver throws an exception when it encounters an invalid +UTF-8 byte sequence + +.. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-write-encoding + :end-before: // end-settings-write-encoding + +.. note:: MongoClientSettings Only + + The ``ReadEncoding`` and ``WriteEncoding`` properties are available only in the + ``MongoClientSettings`` class. + +Stable API +~~~~~~~~~~ + +ServerApi +````````` + +Allows opting into Stable API versioning. The default value is ``null``. See +:manual:`Stable API ` in the {+mdb-server+} manual for more +information about Stable API versioning. + +.. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-server-api + :end-before: // end-settings-server-api + +.. note:: MongoClientSettings Only + + The ``ServerApi`` property is available only in the ``MongoClientSettings`` class. + +Retry Options +~~~~~~~~~~~~~ + +.. tabs:: + + .. tab:: MongoClientSettings + :tabid: mongo-client-settings + + RetryReads + `````````` + + .. include:: /includes/fundamentals/connection-options/retryReads.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-retry-reads + :end-before: // end-settings-retry-reads + + RetryWrites + ``````````` + + .. include:: /includes/fundamentals/connection-options/retryWrites.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-retry-writes + :end-before: // end-settings-retry-writes + + .. tab:: MongoUrlBuilder + :tabid: mongo-url-builder + + RetryReads + `````````` + + .. include:: /includes/fundamentals/connection-options/retryReads.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-retry-reads + :end-before: // end-builder-retry-reads + + RetryWrites + ``````````` + + .. include:: /includes/fundamentals/connection-options/retryWrites.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-retry-writes + :end-before: // end-builder-retry-writes + +Miscellaneous Options +~~~~~~~~~~~~~~~~~~~~~ + +.. tabs:: + + .. tab:: MongoClientSettings + :tabid: mongo-client-settings + + ApplicationName + ``````````````` + + .. include:: /includes/fundamentals/connection-options/applicationName.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-application-name + :end-before: // end-settings-application-name + + AutoEncryptionOptions + ````````````````````` + + Settings for automatic client-side encryption. The default value is ``null``. To + learn more about client-side encryption, see + :ref:`In-Use Encryption `. + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-auto-encryption-options + :end-before: // end-settings-auto-encryption-options + + ClusterConfigurator + ``````````````````` + + Low-level configuration options for sockets, TLS, cluster, and others. The default + value is ``null``. + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-cluster-configurator + :end-before: // end-settings-cluster-configurator + + IPv6 + ```` + + .. include:: /includes/fundamentals/connection-options/ipv6.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-ipv6 + :end-before: // end-settings-ipv6 + + IsFrozen + ```````` + + A read-only option that indicates whether the settings have been frozen. You can't + change frozen settings. The default value is ``false``. + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-is-frozen + :end-before: // end-settings-is-frozen + + .. tip:: Freeze Settings + + You can freeze the settings on a ``MongoClientSettings`` object by calling its + `Freeze() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.MongoClientSettings.Freeze.html>`__ + method. This prevents any further changes to the settings. + + Alternatively, you can call the `FrozenCopy() + <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.MongoClientSettings.FrozenCopy.html>`__ + method to create a new ``MongoClientSettings`` object with the current settings frozen. + + LibraryInfo + ``````````` + + The name and version of a custom library built on the {+driver-short+}. The driver + sends this information to the server. + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-library-info + :end-before: // end-settings-library-info + + LoadBalanced + ```````````` + + .. include:: /includes/fundamentals/connection-options/loadBalanced.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-load-balanced + :end-before: // end-settings-load-balanced + + LoggingSettings + ``````````````` + + The settings used for :ref:`logging. ` The default value is ``null``. + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-logging-settings + :end-before: // end-settings-logging-settings + + Scheme + `````` + + .. include:: /includes/fundamentals/connection-options/scheme.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-scheme + :end-before: // end-settings-scheme + + Server + `````` + + .. include:: /includes/fundamentals/connection-options/server.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-server + :end-before: // end-settings-server + + ServerMonitoringMode + ```````````````````` + + .. include:: /includes/fundamentals/connection-options/serverMonitoringMode.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-server-monitoring-mode + :end-before: // end-settings-server-monitoring-mode + + Servers + ``````` + + .. include:: /includes/fundamentals/connection-options/servers.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-servers + :end-before: // end-settings-servers + + SrvMaxHosts + ``````````` + + .. include:: /includes/fundamentals/connection-options/srvMaxHosts.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-srv-max-hosts + :end-before: // end-settings-srv-max-hosts + + SrvServiceName + `````````````` + + .. include:: /includes/fundamentals/connection-options/srvServiceName.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-srv-service-name + :end-before: // end-settings-srv-service-name + + TranslationOptions + `````````````````` + + Specifies options, such as the {+mdb-server+} version, for translating LINQ + queries to the Query API. The default value is ``null``. + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-settings-translation-options + :end-before: // end-settings-translation-options + + .. tab:: MongoUrlBuilder + :tabid: mongo-url-builder + + ApplicationName + ``````````````` + + .. include:: /includes/fundamentals/connection-options/applicationName.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-application-name + :end-before: // end-builder-application-name + + DatabaseName + ```````````` + + The name of the database that the client connects to. + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-database-name + :end-before: // end-builder-database-name + + IPv6 + ```` + + .. include:: /includes/fundamentals/connection-options/ipv6.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-ipv6 + :end-before: // end-builder-ipv6 + + LoadBalanced + ```````````` + + .. include:: /includes/fundamentals/connection-options/loadBalanced.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-load-balanced + :end-before: // end-builder-load-balanced + + Scheme + `````` + + .. include:: /includes/fundamentals/connection-options/scheme.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-scheme + :end-before: // end-builder-scheme + + Server + `````` + + .. include:: /includes/fundamentals/connection-options/server.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-server + :end-before: // end-builder-server + + ServerMonitoringMode + ```````````````````` + + .. include:: /includes/fundamentals/connection-options/serverMonitoringMode.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-server-monitoring-mode + :end-before: // end-builder-server-monitoring-mode + + Servers + ``````` + + .. include:: /includes/fundamentals/connection-options/servers.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-servers + :end-before: // end-builder-servers + + SrvMaxHosts + ``````````` + + .. include:: /includes/fundamentals/connection-options/srvMaxHosts.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-srv-max-hosts + :end-before: // end-builder-srv-max-hosts + + SrvServiceName + `````````````` + + .. include:: /includes/fundamentals/connection-options/srvServiceName.rst + + .. literalinclude:: /includes/fundamentals/code-examples/connection/ConnectionOptions.cs + :language: csharp + :copyable: true + :dedent: 8 + :start-after: // start-builder-srv-service-name + :end-before: // end-builder-srv-service-name + +Additional Information +---------------------- + +For more information about the types used on this page, see the +following API documentation: + +- `MongoClientSettings <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.MongoClientSettings.html>`__ +- `MongoUrl <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.MongoUrl.html>`__ +- `MongoUrlBuilder <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.MongoUrlBuilder.html>`__ +- `AutoEncryptionOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.AutoEncryptionOptions.html>`__ +- `ClusterDescriptionChangedEvent <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Core.Events.ClusterDescriptionChangedEvent.html>`__ +- `ClusterOpenedEvent <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Core.Events.ClusterOpenedEvent.html>`__ +- `CollectionNamespace <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.CollectionNamespace.html>`__ +- `CompressorConfiguration <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Core.Configuration.CompressorConfiguration.html>`__ +- `CompressorType <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Core.Compression.CompressorType.html>`__ +- `ConnectionStringScheme <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Core.Configuration.ConnectionStringScheme.html>`__ +- `ExpressionTranslationOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ExpressionTranslationOptions.html>`__ +- `LoggingSettings <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Core.Configuration.LoggingSettings.html>`__ +- `MongoCredential <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Credential.html>`__ +- `MongoServerAddress <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.MongoServerAddress.html>`__ +- `ReadConcern <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ReadConcern.html>`__ +- `ReadConcernLevel <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ReadConcernLevel.html>`__ +- `ReadPreference <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ReadPreference.html>`__ +- `ServerApi <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ServerApi.html>`__ +- `WriteConcern <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.WriteConcern.html>`__ \ No newline at end of file diff --git a/source/connect/connection-options/stable-api.txt b/source/connect/connection-options/stable-api.txt index 5417a318..f41f8d3b 100644 --- a/source/connect/connection-options/stable-api.txt +++ b/source/connect/connection-options/stable-api.txt @@ -12,13 +12,6 @@ :depth: 2 :class: singlecol -.. note:: - - The {+stable-api+} feature requires {+mdb-server+} 5.0 or later. - - You should use the {+stable-api+} feature only if all of the MongoDB - servers you're connecting to support this feature. - Overview -------- @@ -46,10 +39,10 @@ version of the {+stable-api+}. .. tip:: Once you've created a ``MongoClient``, you can't change its {+stable-api+} version. - If you need to run commands using more than one version of the + If you must run commands using more than one version of the {+stable-api+}, instantiate a separate client with that version. - If you need to run commands not covered by the {+stable-api+}, make sure the + If you must run commands not covered by the {+stable-api+}, make sure the "strict" option is disabled. See the section on :ref:`{+stable-api+} Options ` for more information. diff --git a/source/connect/connection-troubleshooting.txt b/source/connect/connection-troubleshooting.txt index 6c914198..7afa2669 100644 --- a/source/connect/connection-troubleshooting.txt +++ b/source/connect/connection-troubleshooting.txt @@ -168,7 +168,7 @@ You can also set configuration settings by creating a ``MongoClientSettings`` object and passing that to the ``MongoClient`` constructor. You can use the ``Credential`` property to set the login credentials including specifying the authentication database. For more information about using ``MongoClientSettings`` -as well as some examples, see +and to see some examples, see :ref:`Using MongoClientSettings `. You can check if this is the issue by attempting to connect to a MongoDB @@ -249,7 +249,7 @@ The following section describes a method that may help resolve the issue. Check the Number of Connections ------------------------------- -If you need to create more open connections, increase ``MaxConnectionPoolSize``. For more +If you must create more open connections, increase ``MaxConnectionPoolSize``. For more information about checking the number of connections, see :ref:`Check the Number of Connections ` in the Error Sending Message section. @@ -279,7 +279,7 @@ time the driver spends attempting to establish the connection by using the :manual:`Timeout Options ` in the Server manual. -You should ensure the ``connectTimeoutMS`` setting is not lower than +Ensure the ``connectTimeoutMS`` setting is not lower than the highest network latency you have to a member of the set. If one of the secondary members has a latency of 10000 milliseconds, setting the ``connectTimeoutMS`` to 9000 prevents the driver from ever connecting to that @@ -301,7 +301,7 @@ You can set this option on the connection string. The following example sets You can also set configuration settings by creating a ``MongoClientSettings`` object and passing that to the ``MongoClient`` constructor. For more information -about using ``MongoClientSettings`` as well as some examples, see +about using ``MongoClientSettings`` and to see some examples, see :ref:`Using MongoClientSettings `. Check the Number of Connections diff --git a/source/connect/mongoclient.txt b/source/connect/mongoclient.txt index b2bdff0f..e4ef8697 100644 --- a/source/connect/mongoclient.txt +++ b/source/connect/mongoclient.txt @@ -97,20 +97,15 @@ connection URI to connect to a MongoDB deployment running on port ``27017`` of ` const string uri = "mongodb://localhost:27017/"; var client = new MongoClient(uri); -Configure the MongoClient -------------------------- +Configure the Connection +------------------------ -You can configure settings for the ``MongoClient`` object by passing a -``MongoClientSettings`` object to the constructor. The following example creates a -``MongoClient`` object and sets the ``UseTls`` property to ``true``: +You can configure your connection in the following ways: -.. code-block:: csharp - - var connectionString = "mongodb://localhost:27017/" - var settings = MongoClientSettings.FromConnectionString(connectionString); - settings.UseTls = true; +- Specifying parameters in the connection URI +- Specifying settings on a ``MongoClientSettings`` or ``MongoUrlBuilder`` object -To view a full list of the settings you can configure, see the +To learn more about configuring your connection, see the :ref:`csharp-connection-options` guide. API Documentation diff --git a/source/crud/gridfs.txt b/source/crud/gridfs.txt index c5906346..3e12fa98 100644 --- a/source/crud/gridfs.txt +++ b/source/crud/gridfs.txt @@ -690,7 +690,7 @@ code. .. note:: File Revisions 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 + 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()`` or ``DeleteAsync()`` method. diff --git a/source/crud/insert.txt b/source/crud/insert.txt index 0530e7df..8f4a16ad 100644 --- a/source/crud/insert.txt +++ b/source/crud/insert.txt @@ -248,10 +248,8 @@ Assume you want to insert the following documents: If you attempt to insert these documents with default ``InsertManyOptions``, the driver throws a ``MongoBulkWriteException`` at the third -document because of the repeated ``_id`` value, but the documents before -the error-producing document are still inserted into your collection. - -If you look inside your collection, you should be able to see the following documents: +document because of the repeated ``_id`` value. The operation adds only the first two documents +to the collection: .. code-block:: json :copyable: false @@ -262,9 +260,7 @@ If you look inside your collection, you should be able to see the following docu If you set ``IsOrdered`` to ``false`` in your insert operation, the driver will continue to insert your documents even if some documents produce errors. With this modified insert behavior, the driver throws an exception but inserts all documents -that do not produce errors. - -If you look inside your collection, you should be able to see the following documents: +that do not produce errors: .. code-block:: json :copyable: false diff --git a/source/crud/query/query-filter.txt b/source/crud/query/query-filter.txt index d409d099..fd936a88 100644 --- a/source/crud/query/query-filter.txt +++ b/source/crud/query/query-filter.txt @@ -586,12 +586,12 @@ bitwise operations and the equivalent {+mdb-server+} operators: - {+mdb-server+} Operator * - ``BitsAllClear()`` - - Matches documents where all of the specified bit positions are clear (``0``) in + - Matches documents where all the specified bit positions are clear (``0``) in the specified field. - :manual:`$bitsAllClear ` * - ``BitsAllSet()`` - - Matches documents where all of the specified bit positions are set (``1``) in + - Matches documents where all the specified bit positions are set (``1``) in the specified field. - :manual:`$bitsAllSet ` diff --git a/source/document-formats/bson.txt b/source/document-formats/bson.txt index a8f12abd..b628533a 100644 --- a/source/document-formats/bson.txt +++ b/source/document-formats/bson.txt @@ -99,8 +99,8 @@ write to a file, perform the following steps: #. For each BSON document and subdocument you want to create, call ``WriteStartDocument()``. #. Within each BSON document and subdocument, call ``WriteName()`` to set the field - name and the appropriate ``Write*`` method to set its value. Each data type has a - dedicated ``Write*`` method that you should use. + name and the appropriate ``Write*`` method to set its value. Use the + dedicated ``Write*`` method that corresponds to each data type. #. To start and end arrays, use ``WriteStartArray()`` and ``WriteEndArray()``. #. At the end of each document and subdocument, call ``WriteEndDocument()``. diff --git a/source/includes/fundamentals/code-examples/connection/ConnectionOptions.cs b/source/includes/fundamentals/code-examples/connection/ConnectionOptions.cs new file mode 100644 index 00000000..0097a059 --- /dev/null +++ b/source/includes/fundamentals/code-examples/connection/ConnectionOptions.cs @@ -0,0 +1,855 @@ +using System.Net.Security; +using System.Security.Authentication; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using Microsoft.Extensions.Logging; +using MongoDB.Driver; +using MongoDB.Driver.Core.Compression; +using MongoDB.Driver.Core.Configuration; +using MongoDB.Driver.Core.Events; + +namespace Connection; + +public class ConnectionOptions +{ + public void ConnectionUriExample() + { + // start-connection-uri + const string uri = "mongodb+srv:/localhost:27017/?connectTimeoutMS=60000&tls=true"; + // end-connection-uri + } + + public void MongoClientSettingsExample() + { + // start-mongo-client-settings + var settings = new MongoClientSettings() + { + Scheme = ConnectionStringScheme.MongoDBPlusSrv, + Server = new MongoServerAddress("localhost", 27017), + ConnectTimeout = TimeSpan.FromMilliseconds(60000), + UseTls = true + }; + + var client = new MongoClient(settings); + // end-mongo-client-settings + } + + public void FromConnectionStringExample() + { + // start-from-connection-string + const string connectionUri = "mongodb+srv://localhost:27017/?connectTimeoutMS=60000&tls=true"; + var settings = MongoClientSettings.FromConnectionString(connectionUri); + settings.ServerApi = new ServerApi(ServerApiVersion.V1); + + var client = new MongoClient(settings); + // end-from-connection-string + } + + public void FromUrlExample() + { + // start-from-url + const string connectionUri = "mongodb+srv://localhost:27017/?connectTimeoutMS=60000&tls=true"; + var url = new MongoUrl(connectionUri); + var settings = MongoClientSettings.FromUrl(url); + settings.ServerApi = new ServerApi(ServerApiVersion.V1); + + var client = new MongoClient(settings); + // end-from-url + } + + public void MongoUrlBuilderExample() + { + // start-mongo-url-builder + const string connectionUri = "mongodb+srv://localhost:27017/?connectTimeoutMS=60000&tls=true"; + var builder = new MongoUrlBuilder(connectionUri) + { + ServerMonitoringMode = MongoDB.Driver.Core.Servers.ServerMonitoringMode.Stream + }; + var url = builder.ToMongoUrl(); + + var client = new MongoClient(url); + // end-mongo-url-builder + } + + public void ReplicaSetName() + { + // start-settings-replica-set-name + var settings = new MongoClientSettings + { + ReplicaSetName = "yourReplicaSet", + }; + // end-settings-replica-set-name + + // start-builder-replica-set-name + var builder = new MongoUrlBuilder + { + ReplicaSetName = "yourReplicaSet", + }; + // end-builder-replica-set-name + } + + public void DirectConnection() + { + // start-settings-direct-connection + var settings = new MongoClientSettings + { + DirectConnection = true, + }; + // end-settings-direct-connection + + // start-builder-direct-connection + var builder = new MongoUrlBuilder + { + DirectConnection = true, + }; + // end-builder-direct-connection + } + + public void AllowInsecureTls() + { + // start-settings-allow-insecure-tls + var settings = new MongoClientSettings + { + AllowInsecureTls = true, + }; + // end-settings-allow-insecure-tls + + // start-builder-allow-insecure-tls + var builder = new MongoUrlBuilder + { + AllowInsecureTls = true, + }; + // end-builder-allow-insecure-tls + } + + public void UseTls() + { + // start-settings-use-tls + var settings = new MongoClientSettings + { + UseTls = true, + }; + // end-settings-use-tls + + // start-builder-use-tls + var builder = new MongoUrlBuilder + { + UseTls = true, + }; + // end-builder-use-tls + } + + public void ConnectTimeout() + { + // start-settings-connect-timeout + var settings = new MongoClientSettings + { + ConnectTimeout = TimeSpan.FromSeconds(60), + }; + // end-settings-connect-timeout + + // start-builder-connect-timeout + var builder = new MongoUrlBuilder + { + ConnectTimeout = TimeSpan.FromSeconds(60), + }; + // end-builder-connect-timeout + } + + public void SocketTimeout() + { + // start-settings-socket-timeout + var settings = new MongoClientSettings + { + SocketTimeout = TimeSpan.FromSeconds(60), + }; + // end-settings-socket-timeout + + // start-builder-socket-timeout + var builder = new MongoUrlBuilder + { + SocketTimeout = TimeSpan.FromSeconds(60), + }; + // end-builder-socket-timeout + } + + public void Compressors() + { + // start-settings-compressors + var settings = new MongoClientSettings + { + Compressors = new List() + { + new(CompressorType.Zlib), + new(CompressorType.Snappy) + } + }; + // end-settings-compressors + + // start-builder-compressors + var builder = new MongoUrlBuilder + { + Compressors = new List() + { + new(CompressorType.Zlib), + new(CompressorType.Snappy) + } + }; + // end-builder-compressors + } + + public void MaxConnecting() + { + // start-settings-max-connecting + var settings = new MongoClientSettings + { + MaxConnecting = 3, + }; + // end-settings-max-connecting + + // start-builder-max-connecting + var builder = new MongoUrlBuilder + { + MaxConnecting = 3, + }; + // end-builder-max-connecting + } + + public void MaxConnectionIdleTime() + { + // start-settings-max-connection-idle-time + var settings = new MongoClientSettings + { + MaxConnectionIdleTime = TimeSpan.FromMinutes(8), + }; + // end-settings-max-connection-idle-time + + // start-builder-max-connection-idle-time + var builder = new MongoUrlBuilder + { + MaxConnectionIdleTime = TimeSpan.FromMinutes(8), + }; + // end-builder-max-connection-idle-time + } + + public void MaxConnectionLifeTime() + { + // start-settings-max-connection-life-time + var settings = new MongoClientSettings + { + MaxConnectionLifeTime = TimeSpan.FromMinutes(40), + }; + // end-settings-max-connection-life-time + + // start-builder-max-connection-life-time + var builder = new MongoUrlBuilder + { + MaxConnectionLifeTime = TimeSpan.FromMinutes(40), + }; + // end-builder-max-connection-life-time + } + + public void MaxConnectionPoolSize() + { + // start-settings-max-connection-pool-size + var settings = new MongoClientSettings + { + MaxConnectionPoolSize = 150, + }; + // end-settings-max-connection-pool-size + + // start-builder-max-connection-pool-size + var builder = new MongoUrlBuilder + { + MaxConnectionPoolSize = 150, + }; + // end-builder-max-connection-pool-size + } + + public void MinConnectionPoolSize() + { + // start-settings-min-connection-pool-size + var settings = new MongoClientSettings + { + MinConnectionPoolSize = 3, + }; + // end-settings-min-connection-pool-size + + // start-builder-min-connection-pool-size + var builder = new MongoUrlBuilder + { + MinConnectionPoolSize = 3, + }; + // end-builder-min-connection-pool-size + } + + public void WaitQueueTimeout() + { + // start-settings-wait-queue-timeout + var settings = new MongoClientSettings + { + WaitQueueTimeout = TimeSpan.FromSeconds(30), + }; + // end-settings-wait-queue-timeout + + // start-builder-wait-queue-timeout + var builder = new MongoUrlBuilder + { + WaitQueueTimeout = TimeSpan.FromSeconds(30), + }; + // end-builder-wait-queue-timeout + } + + public void ReadConcern() + { + // start-settings-read-concern + var settings = new MongoClientSettings + { + ReadConcern = MongoDB.Driver.ReadConcern.Local, + }; + // end-settings-read-concern + } + + public void ReadConcernLevel() + { + // start-builder-read-concern-level + var builder = new MongoUrlBuilder + { + ReadConcernLevel = MongoDB.Driver.ReadConcernLevel.Local, + }; + // end-builder-read-concern-level + } + + public void ReadPreference() + { + // start-settings-read-preference + var settings = new MongoClientSettings + { + ReadPreference = MongoDB.Driver.ReadPreference.PrimaryPreferred, + }; + // end-settings-read-preference + + // start-builder-read-preference + var builder = new MongoUrlBuilder + { + ReadPreference = MongoDB.Driver.ReadPreference.PrimaryPreferred, + }; + // end-builder-read-preference + } + + public void Credential() + { + // start-settings-credential + var settings = new MongoClientSettings + { + Credential = MongoCredential.CreatePlainCredential( + databaseName: "admin", + username: "user", + password: "password" + ) + }; + // end-settings-credential + } + + public void BuilderAuthentication() + { + // start-builder-authentication + var builder = new MongoUrlBuilder + { + AuthenticationMechanism = "GSSAPI", + AuthenticationMechanismProperties = new Dictionary + { + { "SERVICE_NAME", "other" }, + { "CANONICALIZE_HOST_NAME", "true" } + }, + AuthenticationSource = "db" + }; + // end-builder-authentication + } + + public void HeartbeatInterval() + { + // start-settings-heartbeat-interval + var settings = new MongoClientSettings + { + HeartbeatInterval = TimeSpan.FromSeconds(5) + }; + // end-settings-heartbeat-interval + + // start-builder-heartbeat-interval + var builder = new MongoUrlBuilder + { + HeartbeatInterval = TimeSpan.FromSeconds(5) + }; + // end-builder-heartbeat-interval + } + + public void HeartbeatTimeout() + { + // start-settings-heartbeat-timeout + var settings = new MongoClientSettings + { + HeartbeatTimeout = TimeSpan.FromSeconds(5) + }; + // end-settings-heartbeat-timeout + + // start-builder-heartbeat-timeout + var builder = new MongoUrlBuilder + { + HeartbeatTimeout = TimeSpan.FromSeconds(5) + }; + // end-builder-heartbeat-timeout + } + + public void LocalThreshold() + { + // start-settings-local-threshold + var settings = new MongoClientSettings + { + LocalThreshold = TimeSpan.FromSeconds(15) + }; + // end-settings-local-threshold + + // start-builder-local-threshold + var builder = new MongoUrlBuilder + { + LocalThreshold = TimeSpan.FromSeconds(15) + }; + // end-builder-local-threshold + } + + public void ServerSelectionTimeout() + { + // start-settings-server-selection-timeout + var settings = new MongoClientSettings + { + ServerSelectionTimeout = TimeSpan.FromSeconds(30) + }; + // end-settings-server-selection-timeout + + // start-builder-server-selection-timeout + var builder = new MongoUrlBuilder + { + ServerSelectionTimeout = TimeSpan.FromSeconds(30) + }; + // end-builder-server-selection-timeout + } + + public void ApplicationName() + { + // start-settings-application-name + var settings = new MongoClientSettings + { + ApplicationName = "yourAppName", + }; + // end-settings-application-name + + // start-builder-application-name + var builder = new MongoUrlBuilder + { + ApplicationName = "yourAppName", + }; + // end-builder-application-name + } + + public void Ipv6() + { + // start-settings-ipv6 + var settings = new MongoClientSettings + { + IPv6 = true, + }; + // end-settings-ipv6 + + // start-builder-ipv6 + var builder = new MongoUrlBuilder + { + IPv6 = true, + }; + // end-builder-ipv6 + } + + public void LoadBalanced() + { + // start-settings-load-balanced + var settings = new MongoClientSettings + { + LoadBalanced = true, + }; + // end-settings-load-balanced + + // start-builder-load-balanced + var builder = new MongoUrlBuilder + { + LoadBalanced = true, + }; + // end-builder-load-balanced + } + + public void RetryReads() + { + // start-settings-retry-reads + var settings = new MongoClientSettings + { + RetryReads = false, + }; + // end-settings-retry-reads + + // start-builder-retry-reads + var builder = new MongoUrlBuilder + { + RetryReads = false, + }; + // end-builder-retry-reads + } + + public void RetryWrites() + { + // start-settings-retry-writes + var settings = new MongoClientSettings + { + RetryWrites = false, + }; + // end-settings-retry-writes + + // start-builder-retry-writes + var builder = new MongoUrlBuilder + { + RetryWrites = false, + }; + // end-builder-retry-writes + } + + public void Scheme() + { + // start-settings-scheme + var settings = new MongoClientSettings + { + Scheme = ConnectionStringScheme.MongoDBPlusSrv, + }; + // end-settings-scheme + + // start-builder-scheme + var builder = new MongoUrlBuilder + { + Scheme = ConnectionStringScheme.MongoDBPlusSrv, + }; + // end-builder-scheme + } + + public void Server() + { + // start-settings-server + var settings = new MongoClientSettings + { + Server = new MongoServerAddress("localhost", 27017) + }; + // end-settings-server + + // start-builder-server + var builder = new MongoUrlBuilder + { + Server = new MongoServerAddress("localhost", 27017) + }; + // end-builder-server + } + + public void ServerMonitoringMode() + { + // start-settings-server-monitoring-mode + var settings = new MongoClientSettings + { + ServerMonitoringMode = MongoDB.Driver.Core.Servers.ServerMonitoringMode.Stream + }; + // end-settings-server-monitoring-mode + + // start-builder-server-monitoring-mode + var builder = new MongoUrlBuilder + { + ServerMonitoringMode = MongoDB.Driver.Core.Servers.ServerMonitoringMode.Stream + }; + // end-builder-server-monitoring-mode + } + + public void Servers() + { + // start-settings-servers + var settings = new MongoClientSettings + { + Servers = new List() + { + new ("localhost", 27017), + new ("localhost", 27018) + } + }; + // end-settings-servers + + // start-builder-servers + var builder = new MongoUrlBuilder + { + Servers = new List() + { + new ("localhost", 27017), + new ("localhost", 27018) + } + }; + // end-builder-servers + } + + public void SrvMaxHosts() + { + // start-settings-srv-max-hosts + var settings = new MongoClientSettings + { + SrvMaxHosts = 5 + }; + // end-settings-srv-max-hosts + + // start-builder-srv-max-hosts + var builder = new MongoUrlBuilder + { + SrvMaxHosts = 5 + }; + // end-builder-srv-max-hosts + } + + public void Journal() + { + // start-builder-journal + var builder = new MongoUrlBuilder + { + Journal = true + }; + // end-builder-journal + } + + public void TlsDisableCertificateRevocationCheck() + { + // start-builder-tls-disable + var builder = new MongoUrlBuilder + { + TlsDisableCertificateRevocationCheck = true + }; + // end-builder-tls-disable + } + + public void W() + { + // start-builder-w + var builder = new MongoUrlBuilder + { + W = 2 + }; + // end-builder-w + } + + public void WTimeout() + { + // start-builder-w-timeout + var builder = new MongoUrlBuilder + { + WTimeout = TimeSpan.FromSeconds(5) + }; + // end-builder-w-timeout + } + + public void UsernamePassword() + { + // start-builder-username-password + var builder = new MongoUrlBuilder + { + Username = "user", + Password = "password" + }; + // end-builder-username-password + } + + public void FSync() + { + // start-builder-fsync + var builder = new MongoUrlBuilder + { + FSync = true + }; + // end-builder-fsync + } + + public void DatabaseName() + { + // start-builder-database-name + var builder = new MongoUrlBuilder + { + DatabaseName = "test_database" + }; + // end-builder-database-name + } + + public void SrvServiceName() + { + // start-settings-srv-service-name + var settings = new MongoClientSettings + { + SrvServiceName = "yourServiceName" + }; + // end-settings-srv-service-name + + // start-builder-srv-service-name + var builder = new MongoUrlBuilder + { + SrvServiceName = "yourServiceName" + }; + // end-builder-srv-service-name + } + + public void LibraryInfo() + { + // start-settings-library-info + var settings = new MongoClientSettings + { + LibraryInfo = new LibraryInfo("customLibraryName", "1.0.0") + }; + // end-settings-library-info + } + + public void TranslationOptions() + { + // start-settings-translation-options + var settings = new MongoClientSettings + { + TranslationOptions = new ExpressionTranslationOptions() + { + CompatibilityLevel = ServerVersion.Server80, + EnableClientSideProjections = true + } + }; + // end-settings-translation-options + } + + public void LoggingSettings() + { + // start-settings-logging-settings + var settings = new MongoClientSettings + { + LoggingSettings = new LoggingSettings( + LoggerFactory.Create(l => + l.SetMinimumLevel(LogLevel.Debug))) + }; + // end-settings-logging-settings + } + + public void ServerApi() + { + // start-settings-server-api + var settings = new MongoClientSettings + { + ServerApi = new ServerApi( + ServerApiVersion.V1, + strict: true, + deprecationErrors: true), + }; + // end-settings-server-api + } + + public void ReadEncoding() + { + // start-settings-read-encoding + var settings = new MongoClientSettings + { + ReadEncoding = new UTF8Encoding( + encoderShouldEmitUTF8Identifier: false, + throwOnInvalidBytes: true) + }; + // end-settings-read-encoding + } + + public void WriteEncoding() + { + // start-settings-write-encoding + var settings = new MongoClientSettings + { + WriteEncoding = new UTF8Encoding( + encoderShouldEmitUTF8Identifier: false, + throwOnInvalidBytes: true) + }; + // end-settings-write-encoding + } + + public void AutoEncryptionOptions() + { + // start-settings-auto-encryption-options + var settings = new MongoClientSettings + { + AutoEncryptionOptions = new AutoEncryptionOptions( + keyVaultNamespace: new CollectionNamespace( + databaseName: "keyvault", + collectionName: "datakeys"), + kmsProviders: new Dictionary> () + { + { "local", new Dictionary () { { "key", "" } } } + } + ), + }; + // end-settings-auto-encryption-options + } + + public void ClusterConfigurator() + { + // start-settings-cluster-configurator + var settings = new MongoClientSettings + { + ClusterConfigurator = builder => + { + builder + .Subscribe(e => + { + Console.WriteLine($"Cluster opened: Cluster ID = {e.ClusterId}"); + }) + .Subscribe(e => + { + Console.WriteLine($"Cluster description changed: {e.NewDescription}"); + }); + } + }; + // end-settings-cluster-configurator + } + + public void SslSettings() + { + // start-settings-ssl-settings + var settings = new MongoClientSettings(); + settings.SslSettings = new SslSettings() + { + CheckCertificateRevocation = false, + ClientCertificateSelectionCallback = new LocalCertificateSelectionCallback() { ... }, + ClientCertificates = new List() { ... }, + EnabledSslProtocols = SslProtocols.Tls13, + ServerCertificateValidationCallback = new RemoteCertificateValidationCallback() { ... } + }; + // end-settings-ssl-settings + } + + public void IsFrozen() + { + // start-settings-is-frozen + var settings = new MongoClientSettings(); + if (!settings.IsFrozen) + { + settings.RetryReads = false; + } + // end-settings-is-frozen + } + + public void WriteConcern() + { + // start-settings-write-concern + var settings = new MongoClientSettings(); + settings.WriteConcern = MongoDB.Driver.WriteConcern.Acknowledged; + settings.WriteConcern = new WriteConcern( + w: 1, + wTimeout: new TimeSpan(0, 0, 0, 30, 0), + fsync: true, + journal: true + ); + // end-settings-write-concern + } +} \ No newline at end of file diff --git a/source/includes/fundamentals/code-examples/connection/LocalConnectionConfig.cs b/source/includes/fundamentals/code-examples/connection/LocalConnectionConfig.cs deleted file mode 100644 index 01d84c84..00000000 --- a/source/includes/fundamentals/code-examples/connection/LocalConnectionConfig.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Connects to a server by using a URI with configuration options - -// start local connection config -using MongoDB.Driver; - -// Sets the connection URI -const string connectionUri = "mongodb+srv://sample.host:27017/?connectTimeoutMS=60000&tls=true"; - -// Creates a new client and connects to the server -var client = new MongoClient(connectionUri); -// end local connection config \ No newline at end of file diff --git a/source/includes/fundamentals/code-examples/connection/MongoClientSettings.cs b/source/includes/fundamentals/code-examples/connection/MongoClientSettings.cs deleted file mode 100644 index c0009679..00000000 --- a/source/includes/fundamentals/code-examples/connection/MongoClientSettings.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Defines a MongoClientSettings object to pass settings to the client - -// start mongo client settings -using MongoDB.Driver; - -// Creates a MongoClientSettings object -var settings = new MongoClientSettings() -{ - Scheme = ConnectionStringScheme.MongoDB, - Server = new MongoServerAddress("localhost", 27017) -}; - -// Creates a new client and connects to the server -var client = new MongoClient(settings); -// end mongo client settings \ No newline at end of file diff --git a/source/includes/fundamentals/code-examples/connection/MongoClientSettingsConfig.cs b/source/includes/fundamentals/code-examples/connection/MongoClientSettingsConfig.cs deleted file mode 100644 index 04e8bea2..00000000 --- a/source/includes/fundamentals/code-examples/connection/MongoClientSettingsConfig.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Defines a MongoClientSettings object to pass configuration settings to the client - -// start mongo client settings config -//const string connectionUri = "mongodb+srv://sample.host:27017/?connectTimeoutMS=60000&tls=true"; - -// Creates a MongoClientSettings object -var settings = new MongoClientSettings() -{ - Scheme = ConnectionStringScheme.MongoDBPlusSrv, - Server = new MongoServerAddress("sample.host", 27017), - ConnectTimeout = new TimeSpan(0, 0, 60), - UseTls = true -}; - -// Creates a new client and connects to the server -var client = new MongoClient(settings); -// end mongo client settings config \ No newline at end of file diff --git a/source/includes/fundamentals/connection-options/allowInsecureTls.rst b/source/includes/fundamentals/connection-options/allowInsecureTls.rst new file mode 100644 index 00000000..2c942bd2 --- /dev/null +++ b/source/includes/fundamentals/connection-options/allowInsecureTls.rst @@ -0,0 +1,7 @@ +Specifies whether to relax TLS constraints as much as possible. This can include +allowing invalid certificates or hostname mismatches. The default value is ``false``. + +If this property is set to ``true`` and ``SslSettings.CheckCertificateRevocation`` +is set to ``false``, the {+driver-short+} will throw an exception. + +The following code example shows how to set this option to ``true``: \ No newline at end of file diff --git a/source/includes/fundamentals/connection-options/applicationName.rst b/source/includes/fundamentals/connection-options/applicationName.rst new file mode 100644 index 00000000..e2267756 --- /dev/null +++ b/source/includes/fundamentals/connection-options/applicationName.rst @@ -0,0 +1,4 @@ +The app name the driver passes to the server in the client metadata as part of +the connection handshake. The server prints this value to the MongoDB logs once +the connection is established. The value is also recorded in the slow query logs +and profile collections. The default value is ``null``. \ No newline at end of file diff --git a/source/includes/fundamentals/connection-options/compressors.rst b/source/includes/fundamentals/connection-options/compressors.rst new file mode 100644 index 00000000..c02bd7d3 --- /dev/null +++ b/source/includes/fundamentals/connection-options/compressors.rst @@ -0,0 +1,3 @@ +The preferred compression types, in order, for wire-protocol messages sent to +or received from the server. The driver uses the first of these compression types +that the server supports. The default value is ``null``. \ No newline at end of file diff --git a/source/includes/fundamentals/connection-options/connectTimeout.rst b/source/includes/fundamentals/connection-options/connectTimeout.rst new file mode 100644 index 00000000..6282d4fd --- /dev/null +++ b/source/includes/fundamentals/connection-options/connectTimeout.rst @@ -0,0 +1,2 @@ +The length of time the driver tries to establish a single TCP socket connection +to the server before timing out. The default value is 30 seconds. \ No newline at end of file diff --git a/source/includes/fundamentals/connection-options/directConnection.rst b/source/includes/fundamentals/connection-options/directConnection.rst new file mode 100644 index 00000000..bc69995d --- /dev/null +++ b/source/includes/fundamentals/connection-options/directConnection.rst @@ -0,0 +1,8 @@ +Specifies whether to force dispatch **all** operations to the host. +If you specify this option, the driver doesn't accept the +:manual:`DNS seed list connection format. ` +You must use the :manual:`standard connection URI format ` +instead. The default value is ``false``. + +This property must be set to ``false`` if you specify more than one +host name. \ No newline at end of file diff --git a/source/includes/fundamentals/connection-options/heartbeatInterval.rst b/source/includes/fundamentals/connection-options/heartbeatInterval.rst new file mode 100644 index 00000000..be42ae49 --- /dev/null +++ b/source/includes/fundamentals/connection-options/heartbeatInterval.rst @@ -0,0 +1,2 @@ +The interval between regular server-monitoring checks. Must be greater than or +equal to 500 milliseconds. The default value is ``10000`` milliseconds (10 seconds). \ No newline at end of file diff --git a/source/includes/fundamentals/connection-options/heartbeatTimeout.rst b/source/includes/fundamentals/connection-options/heartbeatTimeout.rst new file mode 100644 index 00000000..85424bb0 --- /dev/null +++ b/source/includes/fundamentals/connection-options/heartbeatTimeout.rst @@ -0,0 +1,2 @@ +The length of time a monitoring socket can be idle before timing out. The default value +is the value of the ``ConnectTimeout`` property. \ No newline at end of file diff --git a/source/includes/fundamentals/connection-options/ipv6.rst b/source/includes/fundamentals/connection-options/ipv6.rst new file mode 100644 index 00000000..a23191ed --- /dev/null +++ b/source/includes/fundamentals/connection-options/ipv6.rst @@ -0,0 +1 @@ +Specifies whether the host address is in IPv6 format. The default value is ``false``. \ No newline at end of file diff --git a/source/includes/fundamentals/connection-options/loadBalanced.rst b/source/includes/fundamentals/connection-options/loadBalanced.rst new file mode 100644 index 00000000..cdb40261 --- /dev/null +++ b/source/includes/fundamentals/connection-options/loadBalanced.rst @@ -0,0 +1,9 @@ +Specifies whether the driver is connecting to a load balancer. You can set this +property to ``true`` only if all the following conditions are met: + +- You specify just one host name +- You're not connecting to a replica set +- You're not using the ``SrvMaxHosts`` property +- You're not using the ``DirectConnection`` property + +The default value is ``false``. \ No newline at end of file diff --git a/source/includes/fundamentals/connection-options/localThreshold.rst b/source/includes/fundamentals/connection-options/localThreshold.rst new file mode 100644 index 00000000..811db444 --- /dev/null +++ b/source/includes/fundamentals/connection-options/localThreshold.rst @@ -0,0 +1,3 @@ +The latency window for server eligibility. If a server's round trip takes longer +than the fastest server's round-trip time plus this value, the server isn't +eligible for selection. The default value is 15 milliseconds. \ No newline at end of file diff --git a/source/includes/fundamentals/connection-options/maxConnecting.rst b/source/includes/fundamentals/connection-options/maxConnecting.rst new file mode 100644 index 00000000..b6ac4280 --- /dev/null +++ b/source/includes/fundamentals/connection-options/maxConnecting.rst @@ -0,0 +1,2 @@ +The greatest number of connections a driver's connection pool may be +establishing concurrently. The default value is ``2``. \ No newline at end of file diff --git a/source/includes/fundamentals/connection-options/maxConnectionIdleTime.rst b/source/includes/fundamentals/connection-options/maxConnectionIdleTime.rst new file mode 100644 index 00000000..1bab20a5 --- /dev/null +++ b/source/includes/fundamentals/connection-options/maxConnectionIdleTime.rst @@ -0,0 +1,2 @@ +The length of time a connection can be idle before the driver closes it. The default +value is 10 minutes. \ No newline at end of file diff --git a/source/includes/fundamentals/connection-options/maxConnectionLifetime.rst b/source/includes/fundamentals/connection-options/maxConnectionLifetime.rst new file mode 100644 index 00000000..6eeadfe7 --- /dev/null +++ b/source/includes/fundamentals/connection-options/maxConnectionLifetime.rst @@ -0,0 +1,2 @@ +The length of time a connection can be pooled before expiring. The default value is +30 minutes. \ No newline at end of file diff --git a/source/includes/fundamentals/connection-options/maxConnectionPoolSize.rst b/source/includes/fundamentals/connection-options/maxConnectionPoolSize.rst new file mode 100644 index 00000000..1eeedced --- /dev/null +++ b/source/includes/fundamentals/connection-options/maxConnectionPoolSize.rst @@ -0,0 +1,2 @@ +The greatest number of clients or connections the driver can create in its +connection pool. This count includes connections in use. The default value is ``100``. \ No newline at end of file diff --git a/source/includes/fundamentals/connection-options/minConnectionPoolSize.rst b/source/includes/fundamentals/connection-options/minConnectionPoolSize.rst new file mode 100644 index 00000000..eb3d4a3e --- /dev/null +++ b/source/includes/fundamentals/connection-options/minConnectionPoolSize.rst @@ -0,0 +1,3 @@ +The number of connections the driver creates and keeps in the connection +pool even when no operations are occurring. This count includes connections +in use. The default value is ``0``. \ No newline at end of file diff --git a/source/includes/fundamentals/connection-options/readPreference.rst b/source/includes/fundamentals/connection-options/readPreference.rst new file mode 100644 index 00000000..905d5e66 --- /dev/null +++ b/source/includes/fundamentals/connection-options/readPreference.rst @@ -0,0 +1,6 @@ +The client's default read-preference settings. ``MaxStaleness`` represents the +longest replication lag, in wall-clock time, that a secondary can experience and +still be eligible for server selection. The default value is ``ReadPreference.Primary``. +Specifying ``-1`` means no maximum. +See :manual:`Read Preference ` in the {+mdb-server+} manual +for more information. \ No newline at end of file diff --git a/source/includes/fundamentals/connection-options/replicaSetName.rst b/source/includes/fundamentals/connection-options/replicaSetName.rst new file mode 100644 index 00000000..8c085fc9 --- /dev/null +++ b/source/includes/fundamentals/connection-options/replicaSetName.rst @@ -0,0 +1 @@ +The name of the replica set to connect to. The default value is ``null``. \ No newline at end of file diff --git a/source/includes/fundamentals/connection-options/retryReads.rst b/source/includes/fundamentals/connection-options/retryReads.rst new file mode 100644 index 00000000..2d37750b --- /dev/null +++ b/source/includes/fundamentals/connection-options/retryReads.rst @@ -0,0 +1 @@ +Enables retryable reads. The default value is ``true``. \ No newline at end of file diff --git a/source/includes/fundamentals/connection-options/retryWrites.rst b/source/includes/fundamentals/connection-options/retryWrites.rst new file mode 100644 index 00000000..24c430b7 --- /dev/null +++ b/source/includes/fundamentals/connection-options/retryWrites.rst @@ -0,0 +1 @@ +Enables retryable writes. The default value is ``true``. \ No newline at end of file diff --git a/source/includes/fundamentals/connection-options/scheme.rst b/source/includes/fundamentals/connection-options/scheme.rst new file mode 100644 index 00000000..894343ed --- /dev/null +++ b/source/includes/fundamentals/connection-options/scheme.rst @@ -0,0 +1,10 @@ +Specifies whether to use the standard connection string format (``MongoDB``) +or the DNS seed list format (``MongoDBPlusSrv``). The available values for this +property are defined in the `ConnectionStringScheme <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Core.Configuration.ConnectionStringScheme.html>`__ +enum. The default value is ``ConnectionStringScheme.MongoDB``. +See :manual:`Connection Strings ` in the {+mdb-server+} +manual for more information about connection string formats. + +If the ``DirectConnection`` property is set to ``true`` and you +try to use the DNS seed list format, the {+driver-short+} will throw an +exception. \ No newline at end of file diff --git a/source/includes/fundamentals/connection-options/server.rst b/source/includes/fundamentals/connection-options/server.rst new file mode 100644 index 00000000..c6d294e6 --- /dev/null +++ b/source/includes/fundamentals/connection-options/server.rst @@ -0,0 +1,2 @@ +The host and port number where MongoDB is running. The default value is +``localhost:27017``. \ No newline at end of file diff --git a/source/includes/fundamentals/connection-options/serverMonitoringMode.rst b/source/includes/fundamentals/connection-options/serverMonitoringMode.rst new file mode 100644 index 00000000..cf9f0f7a --- /dev/null +++ b/source/includes/fundamentals/connection-options/serverMonitoringMode.rst @@ -0,0 +1,8 @@ +Specifies the server monitoring protocol to use. The available values for this +property are defined in the `ServerMonitoringMode <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Core.Servers.ServerMonitoringMode.html>`__ +enum. The default value is ``Auto``. + +When this option is set to ``Auto`` the monitoring mode is determined +by the environment in which the driver is running. The driver +uses polling mode in function-as-a-service (FaaS) environments, +such as AWS Lambda, and the streaming mode in other environments. \ No newline at end of file diff --git a/source/includes/fundamentals/connection-options/serverSelectionTimeout.rst b/source/includes/fundamentals/connection-options/serverSelectionTimeout.rst new file mode 100644 index 00000000..7dd4c9ff --- /dev/null +++ b/source/includes/fundamentals/connection-options/serverSelectionTimeout.rst @@ -0,0 +1,2 @@ +The length of time the driver tries to select a server before timing out. The default +value is 30 seconds. \ No newline at end of file diff --git a/source/includes/fundamentals/connection-options/servers.rst b/source/includes/fundamentals/connection-options/servers.rst new file mode 100644 index 00000000..61c3a4d0 --- /dev/null +++ b/source/includes/fundamentals/connection-options/servers.rst @@ -0,0 +1,2 @@ +The cluster members where MongoDB is running. The default value is +``localhost:27017``. \ No newline at end of file diff --git a/source/includes/fundamentals/connection-options/socketTimeout.rst b/source/includes/fundamentals/connection-options/socketTimeout.rst new file mode 100644 index 00000000..56fde85e --- /dev/null +++ b/source/includes/fundamentals/connection-options/socketTimeout.rst @@ -0,0 +1,2 @@ +The length of time the driver tries to send or receive on a socket before +timing out. The default value is set by the operating system. \ No newline at end of file diff --git a/source/includes/fundamentals/connection-options/srvMaxHosts.rst b/source/includes/fundamentals/connection-options/srvMaxHosts.rst new file mode 100644 index 00000000..10cde05f --- /dev/null +++ b/source/includes/fundamentals/connection-options/srvMaxHosts.rst @@ -0,0 +1,7 @@ +The greatest number of SRV results to randomly select when initially populating +the seedlist or, during SRV polling, adding new hosts to the topology. The default +value is ``0``. + +You can use this property only if the connection-string scheme is set +to ``ConnectionStringScheme.MongoDBPlusSrv``. You cannot use it when connecting +to a replica set. \ No newline at end of file diff --git a/source/includes/fundamentals/connection-options/srvServiceName.rst b/source/includes/fundamentals/connection-options/srvServiceName.rst new file mode 100644 index 00000000..eb7cc699 --- /dev/null +++ b/source/includes/fundamentals/connection-options/srvServiceName.rst @@ -0,0 +1,8 @@ +The SRV service name. The driver uses the service name to create the SRV URI, which mathces +the following format: + +.. code-block:: + + _{srvServiceName}._tcp.{hostname}.{domainname} + +The default value is ``"mongodb"``. \ No newline at end of file diff --git a/source/includes/fundamentals/connection-options/useTls.rst b/source/includes/fundamentals/connection-options/useTls.rst new file mode 100644 index 00000000..fe8de021 --- /dev/null +++ b/source/includes/fundamentals/connection-options/useTls.rst @@ -0,0 +1,3 @@ +Specifies whether to require TLS for connections to the server. If you use +a scheme of ``"mongodb+srv"`` or specify other TLS options, +this option defaults to ``true``. Otherwise, it defaults to ``false``. \ No newline at end of file diff --git a/source/includes/fundamentals/connection-options/waitQueueTimeout.rst b/source/includes/fundamentals/connection-options/waitQueueTimeout.rst new file mode 100644 index 00000000..3f48220f --- /dev/null +++ b/source/includes/fundamentals/connection-options/waitQueueTimeout.rst @@ -0,0 +1,2 @@ +The length of time the driver tries to check out a connection from a +server's connection pool before timing out. The default value is two minutes. \ No newline at end of file diff --git a/source/includes/quick-start/query-output.rst b/source/includes/quick-start/query-output.rst index 971b7e10..1f51cc67 100644 --- a/source/includes/quick-start/query-output.rst +++ b/source/includes/quick-start/query-output.rst @@ -1,4 +1,4 @@ -When you run ``Program.cs``, it should output the details of the following movie from +When you run ``Program.cs``, it outputs the details of the following movie from the sample dataset: .. code-block:: json diff --git a/source/indexes.txt b/source/indexes.txt index 57825581..8ee2c1a3 100644 --- a/source/indexes.txt +++ b/source/indexes.txt @@ -185,8 +185,7 @@ Clustered Indexes To create a clustered index, specify the clustered index option with the ``_id`` field as the key and the ``Unique`` property as ``true`` when you create your collection. A collection can only contain a single clustered -index. If you want to create a clustered index, then it must be specified when you create -a collection. +index. To create a clustered index, specify it when you create a collection. The following example creates a clustered index on the ``_id`` field while creating a new ``sample_mflix.reviews`` collection: @@ -301,7 +300,7 @@ The following query uses the text index created in the preceding code snippet: Multiple Fields +++++++++++++++ -A collection can only contain one text index. If you want to create a +A collection can only contain one text index. To create a text index for multiple text fields, you must create a compound index. A text search runs on all the text fields within the compound index. diff --git a/source/security/authentication/kerberos.txt b/source/security/authentication/kerberos.txt index e45af57a..5d166e50 100644 --- a/source/security/authentication/kerberos.txt +++ b/source/security/authentication/kerberos.txt @@ -76,7 +76,7 @@ see the corresponding syntax: - On Windows, the process owner running the application is the same as the user needing authentication. - - On Linux, the user has initialized their keytab via ``kinit username@REALM.COM``. + - On Linux, the user has initialized their keytab by using ``kinit username@REALM.COM``. Additional Properties ~~~~~~~~~~~~~~~~~~~~~ diff --git a/source/security/tls-ssl.txt b/source/security/tls-ssl.txt index 9cda5e47..8fa48dd6 100644 --- a/source/security/tls-ssl.txt +++ b/source/security/tls-ssl.txt @@ -151,7 +151,7 @@ You can allow insecure TLS in two different ways: using a property on a Check Certificate Revocation ---------------------------- -When an X.509 certificate should no longer be trusted--for example, if its private key +When an X.509 certificate is no longer trusted--for example, if its private key has been compromised--the certificate authority will revoke the certificate. By default, the {+driver-short+} doesn't check whether a server's certificate has been @@ -205,7 +205,7 @@ Windows, macOS, and Linux: - :wikipedia:`Online Certificate Status Protocol (OCSP) `, a common mechanism for checking revocation - :wikipedia:`OCSP stapling `, a mechanism in which the server - includes a time-stamped OCSP response to the client along with the certificate + includes a time-stamped OCSP response to the client with the certificate - :wikipedia:`Certificate revocation lists (CRLs), `, an alternative to OCSP diff --git a/source/serialization.txt b/source/serialization.txt index 101c4ac3..1bac49e5 100644 --- a/source/serialization.txt +++ b/source/serialization.txt @@ -61,8 +61,8 @@ you can pass in a delegate of type ``Func``. This delegate accepts an object type and returns a boolean value indicating whether the type is safe for serialization. -In most cases, you should pass in the ``ObjectSerializer.DefaultAllowedTypes()`` -delegate. This method returns true for a number of well-known +In most cases, pass in the ``ObjectSerializer.DefaultAllowedTypes()`` +delegate. This method returns true for several well-known framework types that we have deemed safe. To serialize custom types, create a boolean expression that evaluates to ``true`` for the types you want to include. Then, add this expression to the end of the @@ -89,7 +89,7 @@ as shown in the following example: || type.FullName.StartsWith("<>f__AnonymousType")); BsonSerializer.RegisterSerializer(objectSerializer); -You should create and register your ``ObjectSerializer`` at the start of your program, +Create and register your ``ObjectSerializer`` at the start of your program, before doing anything else. Serializer Registry diff --git a/source/serialization/class-mapping.txt b/source/serialization/class-mapping.txt index db80899a..059051bd 100644 --- a/source/serialization/class-mapping.txt +++ b/source/serialization/class-mapping.txt @@ -21,8 +21,8 @@ Overview -------- In this guide, you can learn how to customize the way the {+driver-long+} -maps BSON documents to and from {+language+} classes. You should read this page -to learn more about the default class mapping behavior, or if you need to +maps BSON documents to and from {+language+} classes. Read this page +to learn more about the default class mapping behavior, or if you must customize the way the driver serializes or deserializes your data. Automatic Class Mapping @@ -35,7 +35,7 @@ the name of the field in the document to the name of the property in the class. .. important:: - The type of the property in your class should match the type of the field in + Match the type of the property in your class to the type of the field in the document. The {+driver-short+} instantiates a serializer based on the type of the property in your class. If the types don't match when the driver attempts to deserialize the data, the serializer throws an exception. @@ -72,7 +72,7 @@ class: .. important:: You must register a class map *before* it's needed in your code. We recommend - registering class maps prior to initializing a connection with MongoDB. + registering class maps before initializing a connection with MongoDB. You can also manually map a subset of class properties, while still allowing the driver to automatically map the remaining properties. To do this, @@ -241,11 +241,11 @@ You can also support extra elements when initializing a class map as follows: Dynamically Serialize Properties ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -You can use a method to determine whether or not to serialize a property. For +You can use a method to determine whether to serialize a property. For the driver to automatically use the method when serializing, you must prefix the method name with ``ShouldSerialize`` followed by the name of the property that the method applies to. When the driver sees a method with this naming -convention, it uses that method to determine whether or not to serialize +convention, it uses that method to determine whether to serialize properties that have the provided property name. The following example creates a method that only serializes the ``Age`` property diff --git a/source/serialization/poco.txt b/source/serialization/poco.txt index 196249ad..4afda549 100644 --- a/source/serialization/poco.txt +++ b/source/serialization/poco.txt @@ -27,8 +27,8 @@ features from any framework-specific base classes or interfaces. We recommend using POCOs in your {+language+} code to adhere to idiomatic driver usage and achieve the best performance. -You should read this guide if you want to learn more about how to use -POCOs with the {+driver-short+} or if you need to adjust the driver's default +Read this guide if you want to learn more about how to use +POCOs with the {+driver-short+} or if you must adjust the driver's default field mapping behavior. Create a POCO @@ -84,8 +84,7 @@ Custom Serialization If the default field mapping behavior does not meet your needs, you can specify custom behavior using serialization-related attributes. These attributes change the way that the driver serializes each property of -your POCO. This section describes some of the common -serialization-related attributes. +your POCO. This section describes some common serialization-related attributes. Serialize Read-Only Properties ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From cd02f508fb763672da5b1d5010e85fa5c37b6e73 Mon Sep 17 00:00:00 2001 From: Rea Rustagi <85902999+rustagir@users.noreply.github.com> Date: Tue, 17 Jun 2025 16:29:01 -0400 Subject: [PATCH 28/35] DOCSP-50749: agg tutorial link (#649) --- source/aggregation.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source/aggregation.txt b/source/aggregation.txt index 037ec1a5..389baedd 100644 --- a/source/aggregation.txt +++ b/source/aggregation.txt @@ -37,6 +37,12 @@ more stages, and this pipeline transforms the documents into an aggregated resul To learn more about the aggregation stages supported by the {+driver-short+}, see :ref:`Aggregation Stages `. +.. sharedinclude:: dbx/agg-tutorials-manual-tip.rst + + .. replacement:: language + + :guilabel:`{+language+}` + Analogy ~~~~~~~ @@ -109,4 +115,4 @@ To view a full list of expression operators, see To learn about explaining MongoDB aggregation operations, see :manual:`Explain Results ` and -:manual:`Query Plans `. \ No newline at end of file +:manual:`Query Plans `. From 3dbe87c6748aac927277495f613632ae51d37bf9 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Tue, 1 Jul 2025 14:43:27 -0500 Subject: [PATCH 29/35] DOCSP-49786 - Meta projection methods (#644) --- source/aggregation.txt | 1 + source/aggregation/linq.txt | 4 +- source/aggregation/stages.txt | 1 - source/atlas-search.txt | 81 +-- source/atlas-vector-search.txt | 87 ++- source/crud/query/project.txt | 543 +++++++++++++----- .../code-examples/projection/MetaExamples.cs | 198 +++++++ .../code-examples/projection/Movie.cs | 30 + .../code-examples/projection/SliceExamples.cs | 67 +++ source/includes/project/atlas-only-note.rst | 3 + source/includes/vector-search-intro.rst | 106 ++++ source/reference/quick-reference.txt | 2 +- source/serialization.txt | 2 +- source/serialization/poco.txt | 2 +- 14 files changed, 903 insertions(+), 224 deletions(-) create mode 100644 source/includes/code-examples/projection/MetaExamples.cs create mode 100644 source/includes/code-examples/projection/Movie.cs create mode 100644 source/includes/code-examples/projection/SliceExamples.cs create mode 100644 source/includes/project/atlas-only-note.rst create mode 100644 source/includes/vector-search-intro.rst diff --git a/source/aggregation.txt b/source/aggregation.txt index 389baedd..5fd99c22 100644 --- a/source/aggregation.txt +++ b/source/aggregation.txt @@ -22,6 +22,7 @@ Aggregation Operations :maxdepth: 1 Pipeline Stages + LINQ Overview -------- diff --git a/source/aggregation/linq.txt b/source/aggregation/linq.txt index 73fc6053..0218fea2 100644 --- a/source/aggregation/linq.txt +++ b/source/aggregation/linq.txt @@ -36,7 +36,7 @@ The {+driver-short+} automatically translates LINQ queries into The examples in this guide use the ``restaurants`` collection in the ``sample_restaurants`` database provided in the :atlas:`Atlas sample datasets `. To learn how to create a free MongoDB Atlas cluster and load the sample datasets, -see the :ref:``. +see :ref:``. The following ``Restaurant``, ``Address`` and ``GradeEntry`` classes model the documents in this collection: @@ -1025,7 +1025,7 @@ aggregation stages: - ``$out`` To learn how to create an aggregation pipeline with the ``$out`` stage by using Builders, see -the :ref:`` section. +:ref:``. Supported Methods ----------------- diff --git a/source/aggregation/stages.txt b/source/aggregation/stages.txt index 6efb03fb..df593041 100644 --- a/source/aggregation/stages.txt +++ b/source/aggregation/stages.txt @@ -1,6 +1,5 @@ .. _csharp-aggregation-stages: .. _csharp-builders-aggregation: -.. _csharp-linq: =========================== Aggregation Pipeline Stages diff --git a/source/atlas-search.txt b/source/atlas-search.txt index c2c946b9..60f09436 100644 --- a/source/atlas-search.txt +++ b/source/atlas-search.txt @@ -38,7 +38,7 @@ The examples in this guide use the following documents in a collection called ``guitars``: .. code-block:: json - + { "_id": 1, "make": "Fender", "description": "Classic guitars known for their versatility.", "establishedYear": 1946, "in_stock": true, "rating": 9 } { "_id": 2, "make": "Gibson", "description": "Classic guitars known for their rich, full tones.", "establishedYear": 1902, "in_stock": true, "rating": 8 } { "_id": 3, "make": "PRS", "description": "High-end guitars known for their quality.", "establishedYear": 1985, "in_stock": true, "rating": 9 } @@ -75,7 +75,7 @@ Create an Atlas Search Index Before you can perform a search on an Atlas collection, you must first create an **Atlas Search index** on the collection. An Atlas Search index is a data structure that -categorizes data in a searchable format. +categorizes data in a searchable format. To learn how to create an Atlas Search Index see the :atlas:`Create an Atlas Search Index ` Atlas guide. @@ -103,7 +103,7 @@ collection using the string "Gib" in the ``make`` field. :dedent: .. note:: - + If the field you are searching on is indexed by a search index, you must pass the index name to the ``Autocomplete`` call. If a search index does not exist, the default index is used. The search returns the following document: @@ -112,7 +112,7 @@ The search returns the following document: { "_id" : 2, "make" : "Gibson", "description" : "Classic guitars known for their rich, full tones.", "establishedYear" : 1902, "in_stock" : true, "rating" : 8 } -To learn more about the ``autocomplete`` operator, see the :atlas:`autocomplete ` +To learn more about the ``autocomplete`` operator, see the :atlas:`autocomplete ` Atlas guide. Compound @@ -142,7 +142,7 @@ The search returns the following documents: { "_id" : 3, "make" : "PRS", "description" : "...", "establishedYear" : 1985, "in_stock" : true, "rating" : 9 } { "_id" : 5, "make" : "Ibanez", "description" : "...", "establishedYear" : 1957, "in_stock" : true, "rating" : 7 } -To learn more about the ``compound`` operator, see the :atlas:`compound ` +To learn more about the ``compound`` operator, see the :atlas:`compound ` Atlas guide. EmbeddedDocument @@ -153,7 +153,7 @@ within a field's array value. .. note:: - To search on embedded documents, you must create an + To search on embedded documents, you must create an ``embeddedDocument`` index on the array field. To learn how to define an ``embeddedDocument`` index, see @@ -218,7 +218,7 @@ The search returns the following documents: { "_id" : 5, "make" : "Ibanez", "description" : "...", "establishedYear" : 1957, "in_stock" : true, "rating" : 7 } -To learn more about the ``equals`` operator, see the :atlas:`equals ` +To learn more about the ``equals`` operator, see the :atlas:`equals ` Atlas guide. Exists @@ -246,8 +246,7 @@ The search returns the following documents: { "_id" : 3, "make" : "PRS", "description" : "...", "establishedYear" : 1985, "in_stock" : true, "rating" : 9 } { "_id" : 5, "make" : "Ibanez", "description" : "...", "establishedYear" : 1957, "in_stock" : true, "rating" : 7 } - -To learn more about the ``exists`` operator, see the :atlas:`exists ` +To learn more about the ``exists`` operator, see the :atlas:`exists ` Atlas guide. GeoShape @@ -266,7 +265,7 @@ Consider some documents in the ``guitars`` collection have added an follows: .. code-block:: json - + { "_id": 1, "make": "Fender", "description": "...", "establishedYear": 1946, "in_stock": true, "in_stock_location": { "type": "Point", "coordinates": [ -73.93615, 40.69791 ]}, "rating": 9 } { "_id": 2, "make": "Gibson", "description": "...", "establishedYear": 1902, "in_stock": true, "in_stock_location": { "type": "Point", "coordinates": [ 47.6062, 122.321 ]}, "rating": 8 } @@ -286,7 +285,7 @@ The search returns the following document: { "_id" : 1, "make" : "Fender", "description" : "...", "establishedYear" : 1946, "in_stock" : true, "in_stock_location" : { "type" : "Point", "coordinates" : ["-73.93615", "40.69791"] }, "rating" : 9 } -To learn more about the ``geoShape`` operator, see the :atlas:`geoShape ` +To learn more about the ``geoShape`` operator, see the :atlas:`geoShape ` Atlas guide. GeoWithin @@ -312,13 +311,13 @@ Consider some documents in the ``guitars`` collection have added an follows: .. code-block:: json - + { "_id": 1, "make": "Fender", "description": "...", "establishedYear": 1946, "in_stock": true, "in_stock_location": { "type": "Point", "coordinates": [ -73.93615, 40.69791 ]}, "rating": 9 } { "_id": 2, "make": "Gibson", "description": "...", "establishedYear": 1902, "in_stock": true, "in_stock_location": { "type": "Point", "coordinates": [ 47.6062, 122.321 ]}, "rating": 8 } The following example searches for all documents in which the coordinates in the ``in_stock_location`` field falls within a specified -polygon: +polygon: .. literalinclude:: /includes/fundamentals/code-examples/atlas-search/AtlasSearchExamples.cs :start-after: // start-geowithin-search @@ -332,7 +331,7 @@ The search returns the following document: { "_id" : 1, "make" : "Fender", "description" : "Classic guitars known for their versatility.", "establishedYear" : 1946, "in_stock" : true, "in_stock_location" : { "type" : "Point", "coordinates" : ["-73.93615", "40.69791"] }, "rating" : 9 } -To learn more about the ``geoWithin`` operator, see the :atlas:`geoWithin ` +To learn more about the ``geoWithin`` operator, see the :atlas:`geoWithin ` Atlas guide. In @@ -381,7 +380,7 @@ The search returns the following documents: { "_id" : 4, "make" : "Kiesel", "description" : "Quality guitars made only for custom orders.", "establishedYear" : 2015, "in_stock" : false, "rating" : null } -To learn more about the ``moreLikeThis`` operator, see the :atlas:`moreLikeThis ` +To learn more about the ``moreLikeThis`` operator, see the :atlas:`moreLikeThis ` Atlas guide. Near @@ -414,7 +413,7 @@ The search returns the following documents: { "_id" : 5, "make" : "Ibanez", "description" : "...", "establishedYear" : 1957, "in_stock" : true, "rating" : 7 } -To learn more about the ``near`` operator, see the :atlas:`near ` +To learn more about the ``near`` operator, see the :atlas:`near ` Atlas guide. Phrase @@ -456,7 +455,7 @@ This search returns the following documents: { "_id" : 4, "make" : "Kiesel", "description" : "Quality guitars made only for custom orders.", "establishedYear" : 2015, "in_stock" : false, "rating" : null } { "_id" : 2, "make" : "Gibson", "description" : "Classic guitars known for their rich, full tones.", "establishedYear" : 1902, "in_stock" : true, "rating" : 8 } -To learn more about the ``phrase`` operator, see the :atlas:`phrase ` +To learn more about the ``phrase`` operator, see the :atlas:`phrase ` Atlas guide. QueryString @@ -466,7 +465,7 @@ Use the ``QueryString()`` method to search for documents using a string with the following operators and delimiters: - ``AND`` -- ``OR`` +- ``OR`` - ``NOT`` - ``()`` @@ -490,7 +489,7 @@ The search returns the following documents: { "_id" : 3, "make" : "PRS", "description" : "High-end guitars known for their quality.", "establishedYear" : 1985, "in_stock" : true, "rating" : 9 } { "_id" : 2, "make" : "Gibson", "description" : "Classic guitars known for their rich, full tones.", "establishedYear" : 1902, "in_stock" : true, "rating" : 8 } -To learn more about the ``queryString`` operator, see the :atlas:`queryString ` +To learn more about the ``queryString`` operator, see the :atlas:`queryString ` Atlas guide. Range @@ -516,7 +515,7 @@ The search returns the following results: { "_id" : 4, "make" : "Kiesel", "description" : "Quality guitars made only for custom orders.", "establishedYear" : 2015, "in_stock" : false, "rating" : null } { "_id" : 6, "make" : "Strandberg", "description" : "Modern guitars known for their headless models.", "establishedYear" : 1982, "in_stock" : false, "rating" : null } -To learn more about the ``range`` operator, see the :atlas:`range ` +To learn more about the ``range`` operator, see the :atlas:`range ` Atlas guide. Regex @@ -558,7 +557,7 @@ The search returns the following results: search results. To learn more, see :atlas:`regex Behavior `. -To learn more about the ``regex`` operator, see the :atlas:`regex ` +To learn more about the ``regex`` operator, see the :atlas:`regex ` Atlas guide. Span @@ -593,7 +592,7 @@ Although the document with ``_id: 3`` contains the strings "guitars" and "quality", they are separated by more than one word, so the search omits this document from the results. -To learn more about the ``span`` operator, see the :atlas:`span ` +To learn more about the ``span`` operator, see the :atlas:`span ` Atlas guide. Text @@ -624,7 +623,7 @@ The search returns the following document: If your search string contains multiple terms, the method also looks for a match for each term in the string separately. -To learn more about the ``text`` operator, see the :atlas:`text ` +To learn more about the ``text`` operator, see the :atlas:`text ` Atlas guide. Wildcard @@ -640,7 +639,7 @@ characters in your search: * - Character - Description - + * - ``?`` - Matches any single character @@ -681,35 +680,5 @@ The search returns the following document: search results. To learn more, see :atlas:`wildcard Behavior `. -To learn more about the ``wildcard`` operator, see the :atlas:`wildcard ` -Atlas guide. - -.. TODO: integrate into existing page - -Sample Class ------------- - -The code examples in this guide demonstrate how you can use builders to -create types to interact with documents in the sample collection ``plants.flowers``. -Documents in this collection are modeled by the following ``Flower`` class: - -.. literalinclude:: /includes/fundamentals/code-examples/builders.cs - :language: csharp - :dedent: - :start-after: start-model - :end-before: end-model - -Each builder class takes a generic type parameter -``TDocument`` which represents the type of document that you are working -with. In this guide, the ``Flower`` class is the document type used in -each builder class example. - -Build an Atlas Search Query ---------------------------- - -The ``Search`` class provides a type-safe interface for creating a -:manual:`$search ` -pipeline stage. - -To learn how to construct search queries with the ``Search`` class, see -:ref:`csharp-atlas-search`. +To learn more about the ``wildcard`` operator, see the :atlas:`wildcard ` +Atlas guide. \ No newline at end of file diff --git a/source/atlas-vector-search.txt b/source/atlas-vector-search.txt index 0e77f7d2..0d9bb208 100644 --- a/source/atlas-vector-search.txt +++ b/source/atlas-vector-search.txt @@ -141,16 +141,13 @@ equal to ``0``, you can deserialize it only to a ``BsonVectorPackedBit``. Vector Search Query Example --------------------------- -You can perform a vector search query by calling the ``VectorSearch()`` method -in an :ref:`aggregation pipeline `. To perform a vector -search on a collection, you must first have a collection with a field that contains +You can perform a vector search query by calling the ``VectorSearch()`` method. +To perform a vector search on a collection, you must first have a collection with a field that contains vector data and a vector search index that covers that field. -.. tip:: - - To learn more about configuring a collection for vector search, see the :atlas:`{+avs+} - ` guide in the MongoDB Atlas - documentation. +To learn more about configuring a collection for vector search, see the :atlas:`{+avs+} +` guide in the MongoDB Atlas +documentation. You can convert ``BinaryVectorFloat32``, ``BinaryVectorInt8``, and ``BinaryVectorPackedBit`` data to the ``BsonBinaryData`` type to use in a vector @@ -172,6 +169,19 @@ to use in a vector search query: :language: csharp :start-after: start-array-query-vector :end-before: end-array-query-vector + +Consider the ``embedded_movies`` collection in the ``sample_mflix`` database. You +can use a ``$vectorSearch`` stage to perform a semantic search on the ``plot_embedding`` +field of the documents in the collection. +The following sections describe different methods for performing Atlas Vector Search operations +on this collection. + +.. tip:: + + To obtain the sample dataset used in the following example, see :ref:`csharp-get-started`. + To create the sample Atlas Vector Search index used in the following example, see + :atlas:`Create an Atlas Vector Search Index ` in the + Atlas manual. Aggregation Pipeline Example ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -184,16 +194,46 @@ contains vector data and a vector search index on the ``PlotEmbedding`` field: #. Specifies a ``VectorSearchOptions`` object that contains the name of the index and the number of nearest neighbors to use during the search #. Creates an aggregation pipeline that uses the ``VectorSearch()`` stage to - perform the vector search query and a ``Project()`` stage to filter the - results + perform the vector search query and a ``Project()`` stage to display only + the ``Title``, ``Plot``, and ``Score`` fields #. Prints the results of the query -.. literalinclude:: /includes/fundamentals/code-examples/atlas-vector-search/VectorSearchQueryExample.cs - :language: csharp - :dedent: - :start-after: start-search-example - :end-before: end-search-example - :emphasize-lines: 11 +.. code-block:: csharp + + // Defines vector embeddings for the string "time travel" + var vector = new[] {-0.0016261312,-0.028070757,-0.011342932,-0.012775794,-0.0027440966,0.008683807,-0.02575152,-0.02020668,-0.010283281,-0.0041719596,0.021392956,0.028657231,-0.006634482,0.007490867,0.018593878,0.0038187427,0.029590257,-0.01451522,0.016061379,0.00008528442,-0.008943722,0.01627464,0.024311995,-0.025911469,0.00022596726,-0.008863748,0.008823762,-0.034921836,0.007910728,-0.01515501,0.035801545,-0.0035688248,-0.020299982,-0.03145631,-0.032256044,-0.028763862,-0.0071576433,-0.012769129,0.012322609,-0.006621153,0.010583182,0.024085402,-0.001623632,0.007864078,-0.021406285,0.002554159,0.012229307,-0.011762793,0.0051682983,0.0048484034,0.018087378,0.024325324,-0.037694257,-0.026537929,-0.008803768,-0.017767483,-0.012642504,-0.0062712682,0.0009771782,-0.010409906,0.017754154,-0.004671795,-0.030469967,0.008477209,-0.005218282,-0.0058480743,-0.020153364,-0.0032805866,0.004248601,0.0051449724,0.006791097,0.007650814,0.003458861,-0.0031223053,-0.01932697,-0.033615597,0.00745088,0.006321252,-0.0038154104,0.014555207,0.027697546,-0.02828402,0.0066711367,0.0077107945,0.01794076,0.011349596,-0.0052715978,0.014755142,-0.019753495,-0.011156326,0.011202978,0.022126047,0.00846388,0.030549942,-0.0041386373,0.018847128,-0.00033655585,0.024925126,-0.003555496,-0.019300312,0.010749794,0.0075308536,-0.018287312,-0.016567878,-0.012869096,-0.015528221,0.0078107617,-0.011156326,0.013522214,-0.020646535,-0.01211601,0.055928253,0.011596181,-0.017247654,0.0005939711,-0.026977783,-0.003942035,-0.009583511,-0.0055248477,-0.028737204,0.023179034,0.003995351,0.0219661,-0.008470545,0.023392297,0.010469886,-0.015874773,0.007890735,-0.009690142,-0.00024970944,0.012775794,0.0114762215,0.013422247,0.010429899,-0.03686786,-0.006717788,-0.027484283,0.011556195,-0.036068123,-0.013915418,-0.0016327957,0.0151016945,-0.020473259,0.004671795,-0.012555866,0.0209531,0.01982014,0.024485271,0.0105431955,-0.005178295,0.033162415,-0.013795458,0.007150979,0.010243294,0.005644808,0.017260984,-0.0045618312,0.0024725192,0.004305249,-0.008197301,0.0014203656,0.0018460588,0.005015015,-0.011142998,0.01439526,0.022965772,0.02552493,0.007757446,-0.0019726837,0.009503538,-0.032042783,0.008403899,-0.04609149,0.013808787,0.011749465,0.036388017,0.016314628,0.021939443,-0.0250051,-0.017354285,-0.012962398,0.00006107364,0.019113706,0.03081652,-0.018114036,-0.0084572155,0.009643491,-0.0034721901,0.0072642746,-0.0090636825,0.01642126,0.013428912,0.027724205,0.0071243206,-0.6858542,-0.031029783,-0.014595194,-0.011449563,0.017514233,0.01743426,0.009950057,0.0029706885,-0.015714826,-0.001806072,0.011856096,0.026444625,-0.0010663156,-0.006474535,0.0016161345,-0.020313311,0.0148351155,-0.0018393943,0.0057347785,0.018300641,-0.018647194,0.03345565,-0.008070676,0.0071443142,0.014301958,0.0044818576,0.003838736,-0.007350913,-0.024525259,-0.001142124,-0.018620536,0.017247654,0.007037683,0.010236629,0.06046009,0.0138887605,-0.012122675,0.037694257,0.0055081863,0.042492677,0.00021784494,-0.011656162,0.010276617,0.022325981,0.005984696,-0.009496873,0.013382261,-0.0010563189,0.0026507939,-0.041639622,0.008637156,0.026471283,-0.008403899,0.024858482,-0.00066686375,-0.0016252982,0.027590916,0.0051449724,0.0058647357,-0.008743787,-0.014968405,0.027724205,-0.011596181,0.0047650975,-0.015381602,0.0043718936,0.002159289,0.035908177,-0.008243952,-0.030443309,0.027564257,0.042625964,-0.0033688906,0.01843393,0.019087048,0.024578573,0.03268257,-0.015608194,-0.014128681,-0.0033538956,-0.0028757197,-0.004121976,-0.032389335,0.0034322033,0.058807302,0.010943064,-0.030523283,0.008903735,0.017500903,0.00871713,-0.0029406983,0.013995391,-0.03132302,-0.019660193,-0.00770413,-0.0038853872,0.0015894766,-0.0015294964,-0.006251275,-0.021099718,-0.010256623,-0.008863748,0.028550599,0.02020668,-0.0012962399,-0.003415542,-0.0022509254,0.0119360695,0.027590916,-0.046971202,-0.0015194997,-0.022405956,0.0016677842,-0.00018535563,-0.015421589,-0.031802863,0.03814744,0.0065411795,0.016567878,-0.015621523,0.022899127,-0.011076353,0.02841731,-0.002679118,-0.002342562,0.015341615,0.01804739,-0.020566562,-0.012989056,-0.002990682,0.01643459,0.00042527664,0.008243952,-0.013715484,-0.004835075,-0.009803439,0.03129636,-0.021432944,0.0012087687,-0.015741484,-0.0052016205,0.00080890034,-0.01755422,0.004811749,-0.017967418,-0.026684547,-0.014128681,0.0041386373,-0.013742141,-0.010056688,-0.013268964,-0.0110630235,-0.028337335,0.015981404,-0.00997005,-0.02424535,-0.013968734,-0.028310679,-0.027750863,-0.020699851,0.02235264,0.001057985,0.00081639783,-0.0099367285,0.013522214,-0.012016043,-0.00086471526,0.013568865,0.0019376953,-0.019020405,0.017460918,-0.023045745,0.008503866,0.0064678704,-0.011509543,0.018727167,-0.003372223,-0.0028690554,-0.0027024434,-0.011902748,-0.012182655,-0.015714826,-0.0098634185,0.00593138,0.018753825,0.0010146659,0.013029044,0.0003521757,-0.017620865,0.04102649,0.00552818,0.024485271,-0.009630162,-0.015608194,0.0006718621,-0.0008418062,0.012395918,0.0057980907,0.016221326,0.010616505,0.004838407,-0.012402583,0.019900113,-0.0034521967,0.000247002,-0.03153628,0.0011038032,-0.020819811,0.016234655,-0.00330058,-0.0032289368,0.00078973995,-0.021952773,-0.022459272,0.03118973,0.03673457,-0.021472929,0.0072109587,-0.015075036,0.004855068,-0.0008151483,0.0069643734,0.010023367,-0.010276617,-0.023019087,0.0068244194,-0.0012520878,-0.0015086699,0.022046074,-0.034148756,-0.0022192693,0.002427534,-0.0027124402,0.0060346797,0.015461575,0.0137554705,0.009230294,-0.009583511,0.032629255,0.015994733,-0.019167023,-0.009203636,0.03393549,-0.017274313,-0.012042701,-0.0009930064,0.026777849,-0.013582194,-0.0027590916,-0.017594207,-0.026804507,-0.0014236979,-0.022032745,0.0091236625,-0.0042419364,-0.00858384,-0.0033905501,-0.020739838,0.016821127,0.022539245,0.015381602,0.015141681,0.028817179,-0.019726837,-0.0051283115,-0.011489551,-0.013208984,-0.0047017853,-0.0072309524,0.01767418,0.0025658219,-0.010323267,0.012609182,-0.028097415,0.026871152,-0.010276617,0.021912785,0.0022542577,0.005124979,-0.0019710176,0.004518512,-0.040360045,0.010969722,-0.0031539614,-0.020366628,-0.025778178,-0.0110030435,-0.016221326,0.0036587953,0.016207997,0.003007343,-0.0032555948,0.0044052163,-0.022046074,-0.0008822095,-0.009363583,0.028230704,-0.024538586,0.0029840174,0.0016044717,-0.014181997,0.031349678,-0.014381931,-0.027750863,0.02613806,0.0004136138,-0.005748107,-0.01868718,-0.0010138329,0.0054348772,0.010703143,-0.003682121,0.0030856507,-0.004275259,-0.010403241,0.021113047,-0.022685863,-0.023032416,0.031429652,0.001792743,-0.005644808,-0.011842767,-0.04078657,-0.0026874484,0.06915057,-0.00056939584,-0.013995391,0.010703143,-0.013728813,-0.022939114,-0.015261642,-0.022485929,0.016807798,0.007964044,0.0144219175,0.016821127,0.0076241563,0.005461535,-0.013248971,0.015301628,0.0085171955,-0.004318578,0.011136333,-0.0059047225,-0.010249958,-0.018207338,0.024645219,0.021752838,0.0007614159,-0.013648839,0.01111634,-0.010503208,-0.0038487327,-0.008203966,-0.00397869,0.0029740208,0.008530525,0.005261601,0.01642126,-0.0038753906,-0.013222313,0.026537929,0.024671877,-0.043505676,0.014195326,0.024778508,0.0056914594,-0.025951454,0.017620865,-0.0021359634,0.008643821,0.021299653,0.0041686273,-0.009017031,0.04044002,0.024378639,-0.027777521,-0.014208655,0.0028623908,0.042119466,0.005801423,-0.028124074,-0.03129636,0.022139376,-0.022179363,-0.04067994,0.013688826,0.013328944,0.0046184794,-0.02828402,-0.0063412455,-0.0046184794,-0.011756129,-0.010383247,-0.0018543894,-0.0018593877,-0.00052024535,0.004815081,0.014781799,0.018007403,0.01306903,-0.020433271,0.009043689,0.033189073,-0.006844413,-0.019766824,-0.018767154,0.00533491,-0.0024575242,0.018727167,0.0058080875,-0.013835444,0.0040719924,0.004881726,0.012029372,0.005664801,0.03193615,0.0058047553,0.002695779,0.009290274,0.02361889,0.017834127,0.0049017193,-0.0036388019,0.010776452,-0.019793482,0.0067777685,-0.014208655,-0.024911797,0.002385881,0.0034988478,0.020899786,-0.0025858153,-0.011849431,0.033189073,-0.021312982,0.024965113,-0.014635181,0.014048708,-0.0035921505,-0.003347231,0.030869836,-0.0017161017,-0.0061346465,0.009203636,-0.025165047,0.0068510775,0.021499587,0.013782129,-0.0024475274,-0.0051149824,-0.024445284,0.006167969,0.0068844,-0.00076183246,0.030150073,-0.0055948244,-0.011162991,-0.02057989,-0.009703471,-0.020646535,0.008004031,0.0066378145,-0.019900113,-0.012169327,-0.01439526,0.0044252095,-0.004018677,0.014621852,-0.025085073,-0.013715484,-0.017980747,0.0071043274,0.011456228,-0.01010334,-0.0035321703,-0.03801415,-0.012036037,-0.0028990454,-0.05419549,-0.024058744,-0.024272008,0.015221654,0.027964126,0.03182952,-0.015354944,0.004855068,0.011522872,0.004771762,0.0027874154,0.023405626,0.0004242353,-0.03132302,0.007057676,0.008763781,-0.0027057757,0.023005757,-0.0071176565,-0.005238275,0.029110415,-0.010989714,0.013728813,-0.009630162,-0.029137073,-0.0049317093,-0.0008630492,-0.015248313,0.0043219104,-0.0055681667,-0.013175662,0.029723546,0.025098402,0.012849103,-0.0009996708,0.03118973,-0.0021709518,0.0260181,-0.020526575,0.028097415,-0.016141351,0.010509873,-0.022965772,0.002865723,0.0020493253,0.0020509914,-0.0041419696,-0.00039695262,0.017287642,0.0038987163,0.014795128,-0.014661839,-0.008950386,0.004431874,-0.009383577,0.0012604183,-0.023019087,0.0029273694,-0.033135757,0.009176978,-0.011023037,-0.002102641,0.02663123,-0.03849399,-0.0044152127,0.0004527676,-0.0026924468,0.02828402,0.017727496,0.035135098,0.02728435,-0.005348239,-0.001467017,-0.019766824,0.014715155,0.011982721,0.0045651635,0.023458943,-0.0010046692,-0.0031373003,-0.0006972704,0.0019043729,-0.018967088,-0.024311995,0.0011546199,0.007977373,-0.004755101,-0.010016702,-0.02780418,-0.004688456,0.013022379,-0.005484861,0.0017227661,-0.015394931,-0.028763862,-0.026684547,0.0030589928,-0.018513903,0.028363993,0.0044818576,-0.009270281,0.038920518,-0.016008062,0.0093902415,0.004815081,-0.021059733,0.01451522,-0.0051583014,0.023765508,-0.017874114,-0.016821127,-0.012522544,-0.0028390652,0.0040886537,0.020259995,-0.031216389,-0.014115352,-0.009176978,0.010303274,0.020313311,0.0064112223,-0.02235264,-0.022872468,0.0052449396,0.0005723116,0.0037321046,0.016807798,-0.018527232,-0.009303603,0.0024858483,-0.0012662497,-0.007110992,0.011976057,-0.007790768,-0.042999174,-0.006727785,-0.011829439,0.007024354,0.005278262,-0.017740825,-0.0041519664,0.0085905045,0.027750863,-0.038387362,0.024391968,0.00087721116,0.010509873,-0.00038508154,-0.006857742,0.0183273,-0.0037054466,0.015461575,0.0017394272,-0.0017944091,0.014181997,-0.0052682655,0.009023695,0.00719763,-0.013522214,0.0034422,0.014941746,-0.0016711164,-0.025298337,-0.017634194,0.0058714002,-0.005321581,0.017834127,0.0110630235,-0.03369557,0.029190388,-0.008943722,0.009363583,-0.0034222065,-0.026111402,-0.007037683,-0.006561173,0.02473852,-0.007084334,-0.010110005,-0.008577175,0.0030439978,-0.022712521,0.0054582027,-0.0012620845,-0.0011954397,-0.015741484,0.0129557345,-0.00042111133,0.00846388,0.008930393,0.016487904,0.010469886,-0.007917393,-0.011762793,-0.0214596,0.000917198,0.021672864,0.010269952,-0.007737452,-0.010243294,-0.0067244526,-0.015488233,-0.021552904,0.017127695,0.011109675,0.038067464,0.00871713,-0.0025591573,0.021312982,-0.006237946,0.034628596,-0.0045251767,0.008357248,0.020686522,0.0010696478,0.0076708077,0.03772091,-0.018700508,-0.0020676525,-0.008923728,-0.023298996,0.018233996,-0.010256623,0.0017860786,0.009796774,-0.00897038,-0.01269582,-0.018527232,0.009190307,-0.02372552,-0.042119466,0.008097334,-0.0066778013,-0.021046404,0.0019593548,0.011083017,-0.0016028056,0.012662497,-0.000059095124,0.0071043274,-0.014675168,0.024831824,-0.053582355,0.038387362,0.0005698124,0.015954746,0.021552904,0.031589597,-0.009230294,-0.0006147976,0.002625802,-0.011749465,-0.034362018,-0.0067844326,-0.018793812,0.011442899,-0.008743787,0.017474247,-0.021619547,0.01831397,-0.009037024,-0.0057247817,-0.02728435,0.010363255,0.034415334,-0.024032086,-0.0020126705,-0.0045518344,-0.019353628,-0.018340627,-0.03129636,-0.0034038792,-0.006321252,-0.0016161345,0.033642255,-0.000056075285,-0.005005019,0.004571828,-0.0024075406,-0.00010215386,0.0098634185,0.1980148,-0.003825407,-0.025191706,0.035161756,0.005358236,0.025111731,0.023485601,0.0023342315,-0.011882754,0.018287312,-0.0068910643,0.003912045,0.009243623,-0.001355387,-0.028603915,-0.012802451,-0.030150073,-0.014795128,-0.028630573,-0.0013487226,0.002667455,0.00985009,-0.0033972147,-0.021486258,0.009503538,-0.017847456,0.013062365,-0.014341944,0.005078328,0.025165047,-0.015594865,-0.025924796,-0.0018177348,0.010996379,-0.02993681,0.007324255,0.014475234,-0.028577257,0.005494857,0.00011725306,-0.013315615,0.015941417,0.009376912,0.0025158382,0.008743787,0.023832154,-0.008084005,-0.014195326,-0.008823762,0.0033455652,-0.032362677,-0.021552904,-0.0056081535,0.023298996,-0.025444955,0.0097301295,0.009736794,0.015274971,-0.0012937407,-0.018087378,-0.0039387033,0.008637156,-0.011189649,-0.00023846315,-0.011582852,0.0066411467,-0.018220667,0.0060846633,0.0376676,-0.002709108,0.0072776037,0.0034188742,-0.010249958,-0.0007747449,-0.00795738,-0.022192692,0.03910712,0.032122757,0.023898797,0.0076241563,-0.007397564,-0.003655463,0.011442899,-0.014115352,-0.00505167,-0.031163072,0.030336678,-0.006857742,-0.022259338,0.004048667,0.02072651,0.0030156737,-0.0042119464,0.00041861215,-0.005731446,0.011103011,0.013822115,0.021512916,0.009216965,-0.006537847,-0.027057758,-0.04054665,0.010403241,-0.0056281467,-0.005701456,-0.002709108,-0.00745088,-0.0024841821,0.009356919,-0.022659205,0.004061996,-0.013175662,0.017074378,-0.006141311,-0.014541878,0.02993681,-0.00028448965,-0.025271678,0.011689484,-0.014528549,0.004398552,-0.017274313,0.0045751603,0.012455898,0.004121976,-0.025458284,-0.006744446,0.011822774,-0.015035049,-0.03257594,0.014675168,-0.0039187097,0.019726837,-0.0047251107,0.0022825818,0.011829439,0.005391558,-0.016781142,-0.0058747325,0.010309938,-0.013049036,0.01186276,-0.0011246296,0.0062112883,0.0028190718,-0.021739509,0.009883412,-0.0073175905,-0.012715813,-0.017181009,-0.016607866,-0.042492677,-0.0014478565,-0.01794076,0.012302616,-0.015194997,-0.04433207,-0.020606548,0.009696807,0.010303274,-0.01694109,-0.004018677,0.019353628,-0.001991011,0.000058938927,0.010536531,-0.17274313,0.010143327,0.014235313,-0.024152048,0.025684876,-0.0012504216,0.036601283,-0.003698782,0.0007310093,0.004165295,-0.0029157067,0.017101036,-0.046891227,-0.017460918,0.022965772,0.020233337,-0.024072073,0.017220996,0.009370248,0.0010363255,0.0194336,-0.019606877,0.01818068,-0.020819811,0.007410893,0.0019326969,0.017887443,0.006651143,0.00067394477,-0.011889419,-0.025058415,-0.008543854,0.021579562,0.0047484366,0.014062037,0.0075508473,-0.009510202,-0.009143656,0.0046817916,0.013982063,-0.0027990784,0.011782787,0.014541878,-0.015701497,-0.029350337,0.021979429,0.01332228,-0.026244693,-0.0123492675,-0.003895384,0.0071576433,-0.035454992,-0.00046984528,0.0033522295,0.039347045,0.0005119148,0.00476843,-0.012995721,0.0024042083,-0.006931051,-0.014461905,-0.0127558,0.0034555288,-0.0074842023,-0.030256703,-0.007057676,-0.00807734,0.007804097,-0.006957709,0.017181009,-0.034575284,-0.008603834,-0.005008351,-0.015834786,0.02943031,0.016861115,-0.0050849924,0.014235313,0.0051449724,0.0025924798,-0.0025741523,0.04289254,-0.002104307,0.012969063,-0.008310596,0.00423194,0.0074975314,0.0018810473,-0.014248641,-0.024725191,0.0151016945,-0.017527562,0.0018727167,0.0002830318,0.015168339,0.0144219175,-0.004048667,-0.004358565,0.011836103,-0.010343261,-0.005911387,0.0022825818,0.0073175905,0.00403867,0.013188991,0.03334902,0.006111321,0.008597169,0.030123414,-0.015474904,0.0017877447,-0.024551915,0.013155668,0.023525586,-0.0255116,0.017220996,0.004358565,-0.00934359,0.0099967085,0.011162991,0.03092315,-0.021046404,-0.015514892,0.0011946067,-0.01816735,0.010876419,-0.10124666,-0.03550831,0.0056348112,0.013942076,0.005951374,0.020419942,-0.006857742,-0.020873128,-0.021259667,0.0137554705,0.0057880944,-0.029163731,-0.018767154,-0.021392956,0.030896494,-0.005494857,-0.0027307675,-0.006801094,-0.014821786,0.021392956,-0.0018110704,-0.0018843795,-0.012362596,-0.0072176233,-0.017194338,-0.018713837,-0.024272008,0.03801415,0.00015880188,0.0044951867,-0.028630573,-0.0014070367,-0.00916365,-0.026537929,-0.009576847,-0.013995391,-0.0077107945,0.0050016865,0.00578143,-0.04467862,0.008363913,0.010136662,-0.0006268769,-0.006591163,0.015341615,-0.027377652,-0.00093136,0.029243704,-0.020886457,-0.01041657,-0.02424535,0.005291591,-0.02980352,-0.009190307,0.019460259,-0.0041286405,0.004801752,0.0011787785,-0.001257086,-0.011216307,-0.013395589,0.00088137644,-0.0051616337,0.03876057,-0.0033455652,0.00075850025,-0.006951045,-0.0062112883,0.018140694,-0.006351242,-0.008263946,0.018154023,-0.012189319,0.0075508473,-0.044358727,-0.0040153447,0.0093302615,-0.010636497,0.032789204,-0.005264933,-0.014235313,-0.018393943,0.007297597,-0.016114693,0.015021721,0.020033404,0.0137688,0.0011046362,0.010616505,-0.0039453674,0.012109346,0.021099718,-0.0072842683,-0.019153694,-0.003768759,0.039320387,-0.006747778,-0.0016852784,0.018154023,0.0010963057,-0.015035049,-0.021033075,-0.04345236,0.017287642,0.016341286,-0.008610498,0.00236922,0.009290274,0.028950468,-0.014475234,-0.0035654926,0.015434918,-0.03372223,0.004501851,-0.012929076,-0.008483873,-0.0044685286,-0.0102233,0.01615468,0.0022792495,0.010876419,-0.0059647025,0.01895376,-0.0069976957,-0.0042952523,0.017207667,-0.00036133936,0.0085905045,0.008084005,0.03129636,-0.016994404,-0.014915089,0.020100048,-0.012009379,-0.006684466,0.01306903,0.00015765642,-0.00530492,0.0005277429,0.015421589,0.015528221,0.032202728,-0.003485519,-0.0014286962,0.033908837,0.001367883,0.010509873,0.025271678,-0.020993087,0.019846799,0.006897729,-0.010216636,-0.00725761,0.01818068,-0.028443968,-0.011242964,-0.014435247,-0.013688826,0.006101324,-0.0022509254,0.013848773,-0.0019077052,0.017181009,0.03422873,0.005324913,-0.0035188415,0.014128681,-0.004898387,0.005038341,0.0012320944,-0.005561502,-0.017847456,0.0008538855,-0.0047884234,0.011849431,0.015421589,-0.013942076,0.0029790192,-0.013702155,0.0001199605,-0.024431955,0.019926772,0.022179363,-0.016487904,-0.03964028,0.0050849924,0.017487574,0.022792496,0.0012504216,0.004048667,-0.00997005,0.0076041627,-0.014328616,-0.020259995,0.0005598157,-0.010469886,0.0016852784,0.01716768,-0.008990373,-0.001987679,0.026417969,0.023792166,0.0046917885,-0.0071909656,-0.00032051947,-0.023259008,-0.009170313,0.02071318,-0.03156294,-0.030869836,-0.006324584,0.013795458,-0.00047151142,0.016874444,0.00947688,0.00985009,-0.029883493,0.024205362,-0.013522214,-0.015075036,-0.030603256,0.029270362,0.010503208,0.021539574,0.01743426,-0.023898797,0.022019416,-0.0068777353,0.027857494,-0.021259667,0.0025758184,0.006197959,0.006447877,-0.00025200035,-0.004941706,-0.021246338,-0.005504854,-0.008390571,-0.0097301295,0.027244363,-0.04446536,0.05216949,0.010243294,-0.016008062,0.0122493,-0.0199401,0.009077012,0.019753495,0.006431216,-0.037960835,-0.027377652,0.016381273,-0.0038620618,0.022512587,-0.010996379,-0.0015211658,-0.0102233,0.007071005,0.008230623,-0.009490209,-0.010083347,0.024431955,0.002427534,0.02828402,0.0035721571,-0.022192692,-0.011882754,0.010056688,0.0011904413,-0.01426197,-0.017500903,-0.00010985966,0.005591492,-0.0077707744,-0.012049366,0.011869425,0.00858384,-0.024698535,-0.030283362,0.020140035,0.011949399,-0.013968734,0.042732596,-0.011649498,-0.011982721,-0.016967745,-0.0060913274,-0.007130985,-0.013109017,-0.009710136}; + + // Specifies that the vector search will consider the 150 nearest neighbors + // in the specified index + var options = new VectorSearchOptions() + { + IndexName = "vector_index", + NumberOfCandidates = 150 + }; + + // Builds aggregation pipeline and specifies that the $vectorSearch stage + // returns 10 results + var pipeline = new EmptyPipelineDefinition() + .VectorSearch(m => m.PlotEmbedding, vector, 10, options) + .Project(Builders.Projection + .Include(m => m.Title) + .Include(m => m.Plot) + .MetaVectorSearchScore(m => m.Score); + +The results of the preceding example contain the following documents: + +.. code-block:: json + + { "_id" : { "$oid" : "573a13a0f29313caabd04a4f" }, "plot" : "A reporter, learning of time travelers visiting 20th century disasters, tries to change the history they know by averting upcoming disasters.", "title" : "Thrill Seekers", "score" : 0.926971435546875 } + { "_id" : { "$oid" : "573a13d8f29313caabda6557" }, "plot" : "At the age of 21, Tim discovers he can travel in time and change what happens and has happened in his own life. His decision to make his world a better place by getting a girlfriend turns out not to be as easy as you might think.", "title" : "About Time", "score" : 0. 9267120361328125 } + { "_id" : { "$oid" : "573a1399f29313caabceec0e" }, "plot" : "An officer for a security agency that regulates time travel, must fend for his life against a shady politician who has a tie to his past.", "title" : "Timecop", "score" : 0.9235687255859375 } + { "_id" : { "$oid" : "573a13a5f29313caabd13b4b" }, "plot" : "Hoping to alter the events of the past, a 19th century inventor instead travels 800,000 years into the future, where he finds humankind divided into two warring races.", "title" : "The Time Machine", "score" : 0.9228668212890625 } + { "_id" : { "$oid" : "573a13aef29313caabd2e2d7" }, "plot" : "After using his mother's newly built time machine, Dolf gets stuck involuntary in the year 1212. He ends up in a children's crusade where he confronts his new friends with modern techniques...", "title" : "Crusade in Jeans", "score" : 0.9228515625 } + { "_id" : { "$oid" : "573a1399f29313caabcee36f" }, "plot" : "A time-travel experiment in which a robot probe is sent from the year 2073 to the year 1973 goes terribly wrong thrusting one of the project scientists, a man named Nicholas Sinclair into a...", "title" : "A.P.E.X.", "score" : 0.9199066162109375 } + { "_id" : { "$oid" : "573a13c6f29313caabd715d3" }, "plot" : "Agent J travels in time to M.I.B.'s early days in 1969 to stop an alien from assassinating his friend Agent K and changing history.", "title" : "Men in Black 3", "score" : 0.919403076171875 } + { "_id" : { "$oid" : "573a13d4f29313caabd98c13" }, "plot" : "Bound by a shared destiny, a teen bursting with scientific curiosity and a former boy-genius inventor embark on a mission to unearth the secrets of a place somewhere in time and space that exists in their collective memory.", "title" : "Tomorrowland", "score" : 0.9191131591796875 } + { "_id" : { "$oid" : "573a13b6f29313caabd477fa" }, "plot" : "With the help of his uncle, a man travels to the future to try and bring his girlfriend back to life.", "title" : "Love Story 2050", "score" : 0. 917755126953125 } + { "_id" : { "$oid" : "573a13b3f29313caabd3ebd4" }, "plot" : "A romantic drama about a Chicago librarian with a gene that causes him to involuntarily time travel, and the complications it creates for his marriage.", "title" : "The Time Traveler's Wife", "score" : 0.9172210693359375 } LINQ Example ~~~~~~~~~~~~ @@ -208,19 +248,6 @@ the LINQ syntax instead of the aggregation pipeline syntax: :dedent: :emphasize-lines: 2 -Builders Example -~~~~~~~~~~~~~~~~ - -The following code sample performs the same vector search query as the preceding example, -but uses builder classes to construct the aggregation pipeline stages: - -.. literalinclude:: /includes/fundamentals/code-examples/atlas-vector-search/VectorSearchQueryExample.cs - :language: csharp - :start-after: start-builders-example - :end-before: end-builders-example - :dedent: - :emphasize-lines: 2 - Additional Information ---------------------- @@ -244,4 +271,4 @@ guide, see the following API Documentation: <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollectionExtensions.Aggregate.html>`__ - `MongoQueryable.VectorSearch() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Linq.MongoQueryable.VectorSearch.html>`__ - `PipelineStageDefinitionBuilder.VectorSearch() - <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.PipelineStageDefinitionBuilder.VectorSearch.html>`__ \ No newline at end of file + <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.PipelineStageDefinitionBuilder.VectorSearch.html>`__ diff --git a/source/crud/query/project.txt b/source/crud/query/project.txt index cd24ad2d..72f1ca2b 100644 --- a/source/crud/query/project.txt +++ b/source/crud/query/project.txt @@ -13,7 +13,7 @@ Specify Fields To Return .. facet:: :name: genre :values: reference - + .. meta:: :keywords: read, filter, project, select @@ -27,205 +27,484 @@ which fields MongoDB returns from a query. Sample Data ~~~~~~~~~~~ -The examples in this guide use the ``sample_restaurants.restaurants`` collection +The examples on this page use the ``sample_mflix.movies`` 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:``. -Projection Types ----------------- +The following class represents the documents in the ``sample_mflix.movies`` collection: + +.. literalinclude:: /includes/code-examples/projection/Movie.cs + :language: csharp + +.. note:: ConventionPack for Pascal Case + + The properties in the preceding class are named in Pascal case, but the + field names in the MongoDB collection use camel case. To account for this difference, + you can use the following code to register a ``ConventionPack`` when your + application starts: + + .. code-block:: csharp + + var camelCaseConvention = new ConventionPack { new CamelCaseElementNameConvention() }; + ConventionRegistry.Register("CamelCase", camelCaseConvention, type => true); + +.. _csharp-projection-methods: + +Create a Projection +------------------- + +To create a projection, perform the following steps: + +1. Use the ``Builders.Projection`` static property to create a + ``ProjectionDefinitionBuilder`` object, where ``TDocument`` represents the + C# class that the collection's documents map to. The ``ProjectionDefinitionBuilder`` class + provides a type-safe interface for defining a projection. + +#. Chain projection methods from the ``ProjectionDefinitionBuilder`` + object to specify which fields to include or exclude from the returned documents. + +#. Store the resulting ``ProjectionDefinition`` object in a variable. + +#. Pass the variable to the ``Project()`` method after performing the find or aggregation + operation. + +The following sections describe the methods that you can chain from your +``ProjectionDefinitionBuilder`` object. + +Field Projection Methods +------------------------ + +The following methods let you specify which fields to include or exclude from the returned +documents. + +ElemMatch +~~~~~~~~~ + +The ``ElemMatch()`` method limits the contents of an array field from the query results to +contain only the first element matching a specified condition. This is equivalent to projecting +an array element by using the ``$elemMatch`` operator in the {+query-api+}. + +For a code example that uses the ``ElemMatch()`` method, see +:manual:`$elemMatch ` +in the {+mdb-server+} manual. + +Expression +~~~~~~~~~~ + +The ``Expression()`` method lets you specify the structure of the returned documents +by using a lambda expression. This is equivalent to specifying the structure of the +returned documents in the ``$project`` aggregation stage in the {+query-api+}. + +For a code example that uses the ``Expression()`` method, see +:manual:`$project ` in the {+mdb-server+} manual. + +.. note:: ``Id`` Field Exclusion + + When you use a lambda expression to create a projection, the output + automatically excludes the ``Id`` field unless you explicitly include + it. + +Exclude +~~~~~~~ + +The ``Exclude()`` method lets you specify a field to exclude from the returned documents. +This is equivalent to excluding a field in the ``$project`` aggregation stage in the +{+query-api+}. You cannot combine inclusion and exclusion statements in a single +projection unless you are excluding the ``_id`` field. + +For a code example that uses the ``Exclude()`` method, see +:manual:`$project ` in the {+mdb-server+} manual. + +.. note:: Explicitly Exclude ``_id`` Field + + Returned documents include the ``_id`` field unless you explicitly exclude it. The + only exception to this is when you use the ``Expression()`` method to create a + projection. + +Include +~~~~~~~ + +The ``Include()`` method lets you specify a field to include in the returned documents. +This is equivalent to including a field in the ``$project`` aggregation stage in the +{+query-api+}. + +For a code example that uses the ``Include()`` method, see +:manual:`$project ` in the {+mdb-server+} manual. + +Slice +~~~~~ -You can use a projection to specify which fields to include in a return -document, or to specify which fields to exclude. +The ``Slice()`` method specifies the number of elements of a list or array to return in the query +result field. This is equivalent to using the ``$slice`` operator in the {+query-api+}. -When specifying certain fields to include in a projection, all other fields are implicitly -excluded (except the ``_id`` field, which is included by default). You cannot combine -inclusion and exclusion statements in a single projection, unless you are excluding the -``_id`` field. +The following code example uses the ``Slice()`` method to return the first three elements +of the ``Cast`` list in the returned document's ``cast`` array: -To remove the ``_id`` field from the returned document, you must -:ref:`explicitly exclude it `. +.. io-code-block:: + + .. input:: /includes/code-examples/projection/SliceExamples.cs + :language: csharp + :dedent: 8 + :start-after: // start first three + :end-before: // end first three + + .. output:: + :visible: false + :language: json + + { + "_id": { + "$oid": "573a1398f29313caabceb500" + }, + "title": "Back to the Future Part II", + "cast": [ + "Michael J. Fox", + "Christopher Lloyd", + "Lea Thompson" + ] + } + +To return elements from the end of a collection, pass a negative integer to the ``Slice()`` +method. The following code example returns the last three elements of the ``Cast`` list in +the returned document's ``cast`` array: -Specify Fields to Include -~~~~~~~~~~~~~~~~~~~~~~~~~ +.. io-code-block:: -To specify the fields to include from the result, chain the ``Project()`` method -to the ``Find()`` method. When calling the ``Project()`` method, you must pass in the -projection definition as a parameter. You can construct a projection definition by using -the ``Builders.Projection.Include()`` method and passing in the field name to include -as a parameter. This method can be chained to include multiple fields in the projection. + .. input:: /includes/code-examples/projection/SliceExamples.cs + :language: csharp + :dedent: 8 + :start-after: // start last three + :end-before: // end last three -The following example uses the ``Find()`` method to find all restaurants in which the ``name`` -field value is ``"Emerald Pub"``. Then, the code calls the ``Project()`` -method to instruct the find operation to include the ``name`` and ``cuisine`` fields -in the result: + .. output:: + :visible: false + :language: json + + { + "_id": { + "$oid": "573a1398f29313caabceb500" + }, + "title": "Back to the Future Part II", + "cast": [ + "Lea Thompson", + "Thomas F. Wilson" + ] + } + +To skip a specified number of elements in a collection, pass the number of elements to skip +as the first parameter and the number of elements to return as the second +parameter. The following code example skips the first element in the +``Cast`` list and returns the next three elements in the ``cast`` array: .. io-code-block:: - :copyable: true - .. input:: /includes/fundamentals/code-examples/Project.cs - :start-after: start-project-include - :end-before: end-project-include + .. input:: /includes/code-examples/projection/SliceExamples.cs :language: csharp - :dedent: + :dedent: 8 + :start-after: // start skip first limit three + :end-before: // end skip first limit three .. output:: :visible: false + :language: json - { "_id" : ObjectId("..."), "cuisine" : "American", "name" : "Emerald Pub" } - { "_id" : ObjectId("..."), "cuisine" : "American", "name" : "Emerald Pub" } + { + "_id": { + "$oid": "573a1398f29313caabceb500" + }, + "title": "Back to the Future Part II", + "cast": [ + "Christopher Lloyd", + "Lea Thompson", + "Thomas F. Wilson" + ] + } -.. _csharp-project-exclude-id: +To learn more about the ``$slice`` operator, see +:manual:`$slice ` in the {+mdb-server+} manual. -Exclude the ``_id`` Field -~~~~~~~~~~~~~~~~~~~~~~~~~ +Metadata Projection Methods +--------------------------- -When specifying fields to include, you can also exclude the ``_id`` field from -the returned document. +The following methods let you specify which metadata fields to include or exclude +from the returned documents. Metadata fields are hidden by default. -The following example runs the same query as the preceding example, but -excludes the ``_id`` field from the projection: +Meta +~~~~ + +The ``Meta()`` method lets you specify a metadata field to include in the returned +documents. This is equivalent to including a metadata field by using the +:manual:`$meta ` operator in the {+query-api+}. + +The following code example adds the ``textScore`` metadata field to the returned +documents as a field named ``score``: .. io-code-block:: - :copyable: true - .. input:: /includes/fundamentals/code-examples/Project.cs - :start-after: start-project-include-without-id - :end-before: end-project-include-without-id + .. input:: /includes/code-examples/projection/MetaExamples.cs :language: csharp - :dedent: + :dedent: 8 + :start-after: // start meta + :end-before: // end meta .. output:: :visible: false + :language: json + + { + "_id": { + "$oid": "..." + }, + "plot": "...", + "title": "...", + "score": "..." + } - { "cuisine" : "American", "name" : "Emerald Pub" } - { "cuisine" : "American", "name" : "Emerald Pub" } +MetaSearchHighlights +~~~~~~~~~~~~~~~~~~~~ -Specify Fields to Exclude -~~~~~~~~~~~~~~~~~~~~~~~~~ +.. include:: /includes/project/atlas-only-note.rst -To specify the fields to exclude from the result, chain the ``Project()`` method -to the ``Find()`` method. You can exclude fields in your projection by using -the ``Builders.Projection.Exclude()`` method and passing in the field name to exclude -as a parameter. This method can be chained to exclude multiple fields in the projection. +The ``MetaSearchHighlights()`` includes search highlights +in the returned documents. This is equivalent to projecting search highlights +by using a ``{ "$meta": "searchHighlights" }`` object in the {+query-api+}. +To retrieve search highlights, you must create a ``SearchHighlightOptions`` object that +specifies the search field, and then pass this object to the ``Search()`` method. -The following example uses the ``Find()`` method to find all restaurants in which the ``name`` -field value is ``"Emerald Pub"``. It then uses a projection to exclude the ``cuisine`` -field from the returned documents: +The following code example retrieves search highlights for the ``plot`` field, then +includes these highlights in a property named ``Highlights`` in the returned documents: .. io-code-block:: - :copyable: true - .. input:: /includes/fundamentals/code-examples/Project.cs - :start-after: start-project-exclude - :end-before: end-project-exclude + .. input:: /includes/code-examples/projection/MetaExamples.cs :language: csharp - :dedent: + :dedent: 8 + :start-after: // start metaSearchHighlights + :end-before: // end metaSearchHighlights .. output:: :visible: false + :language: json + + { + "_id": { + "$oid": "573a13def29313caabdb5661" + }, + "plot": "She Can See Her Future, But Can't Escape Her Past.", + "title": "West", + "highlights": [ + { + "score": 1.286744475364685, + "path": "plot", + "texts": [ + { + "value": "She Can See Her ", + "type": "text" + }, + { + "value": "Future", + "type": "hit" + }, + { + "value": ", But Can't Escape Her Past.", + "type": "text" + } + ] + } + ] + } + +To learn more about search highlights, see +:atlas:`Highlight Search Terms in Results ` +in the Atlas documentation. + +MetaSearchScore +~~~~~~~~~~~~~~~ + +.. include:: /includes/project/atlas-only-note.rst + +The ``MetaSearchScore()`` method includes search scores in the returned +documents. This is equivalent to projecting search scores +by using a ``{ "$meta": "searchScore" }`` object in the {+query-api+}. + +The following code example projects each document's search score in a field named +``score``: - { "_id" : ObjectId("..."), "address" : { "building" : "308", "coord" : [-74.008493599999994, 40.725807199999998], "street" : "Spring Street", "zipcode" : "10013" }, "borough" : "Manhattan", "grades" : [{ "date" : ISODate("2014-02-24T00:00:00Z"), "grade" : "A", "score" : 5 }, { "date" : ISODate("2013-08-26T00:00:00Z"), "grade" : "A", "score" : 13 }, { "date" : ISODate("2013-03-04T00:00:00Z"), "grade" : "A", "score" : 12 }, { "date" : ISODate("2012-06-25T00:00:00Z"), "grade" : "A", "score" : 10 }, { "date" : ISODate("2011-12-23T00:00:00Z"), "grade" : "A", "score" : 10 }, { "date" : ISODate("2011-07-26T00:00:00Z"), "grade" : "C", "score" : 32 }], "name" : "Emerald Pub", "restaurant_id" : "40367329" } - { "_id" : ObjectId("..."), "address" : { "building" : "18301", "coord" : [-73.791184999999999, 40.740119999999997], "street" : "Horace Harding Expressway", "zipcode" : "11365" }, "borough" : "Queens", "grades" : [{ "date" : ISODate("2014-05-07T00:00:00Z"), "grade" : "A", "score" : 12 }, { "date" : ISODate("2013-04-30T00:00:00Z"), "grade" : "A", "score" : 9 }, { "date" : ISODate("2012-03-01T00:00:00Z"), "grade" : "A", "score" : 13 }], "name" : "Emerald Pub", "restaurant_id" : "40668598" } +.. io-code-block:: -Additional Information ----------------------- + .. input:: /includes/code-examples/projection/MetaExamples.cs + :language: csharp + :dedent: 8 + :start-after: // start metaSearchScore + :end-before: // end metaSearchScore -To learn more about projections, see the :manual:`Project Fields guide -` in the {+mdb-server+} manual. + .. output:: + :visible: false + :language: json -API Documentation -~~~~~~~~~~~~~~~~~ + { + "_id": { + "$oid": "573a13def29313caabdb5661" + }, + "plot": "She Can See Her Future, But Can't Escape Her Past.", + "title": "West", + "score": 2.8259084224700928 + } -To learn more about any of the functions or types discussed in this -guide, see the following API Documentation: +To learn more about search scores, see +:atlas:`Score the Documents in the Returned Documents `. -- `Find() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollectionExtensions.Find.html>`_ -- `Projection <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Builders-1.Projection.html>`_ -- `Include() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ProjectionDefinitionBuilder-1.Include.html>`_ -- `Exclude() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ProjectionDefinitionBuilder-1.Exclude.html>`_ +MetaSearchScoreDetails +~~~~~~~~~~~~~~~~~~~~~~ -.. TODO: integrate into existing page +.. include:: /includes/project/atlas-only-note.rst -Sample Class ------------- +The ``MetaSearchScoreDetails()`` includes details about the search scores +in the returned documents. This is equivalent to projecting search score details +by using a ``{ "$meta": "searchScoreDetails" }`` object in the {+query-api+}. -The code examples in this guide demonstrate how you can use builders to -create types to interact with documents in the sample collection ``plants.flowers``. -Documents in this collection are modeled by the following ``Flower`` class: +To retrieve score details, create a ``SearchOptions`` object with its +``ScoreDetails`` property set to ``true``, and then pass this object to the ``Search()`` method. +The following code example shows this process by projecting each document's search score +details in a field named ``searchScoreDetails``: -.. literalinclude:: /includes/fundamentals/code-examples/builders.cs - :language: csharp - :dedent: - :start-after: start-model - :end-before: end-model +.. io-code-block:: -Each builder class takes a generic type parameter -``TDocument`` which represents the type of document that you are working -with. In this guide, the ``Flower`` class is the document type used in -each builder class example. + .. input:: /includes/code-examples/projection/MetaExamples.cs + :language: csharp + :dedent: 8 + :start-after: // start metaSearchScoreDetails + :end-before: // end metaSearchScoreDetails -.. _csharp-builders-projection: + .. output:: + :visible: false + :language: json + + { + "_id": { + "$oid": "573a13def29313caabdb5661" + }, + ... + "scoreDetails": { + "value": 2.8259084224700928, + "description": "$type:string/plot:future [BM25Similarity], result of:", + "details": [ + { + "value": 2.8259084224700928, + "description": "score(freq=1.0), computed as boost * idf * tf from:", + "details": [ + ... + } + +To learn more about search score details, see +:atlas:`Return the Score Details ` +in the Atlas documentation. + +MetaSearchSequenceToken +~~~~~~~~~~~~~~~~~~~~~~~ + +.. include:: /includes/project/atlas-only-note.rst + +The ``MetaSearchSequenceToken()`` method includes a token in the returned documents +that represents a point in the search sequence. This is equivalent to projecting the search +sequence token by using a ``{ "$meta": "searchSequenceToken" }`` object in the +{+query-api+}. You can use this token to perform additional searches before or after the +specified point. + +The following code example projects each document's search sequence token in a property +named ``PaginationToken``: -Create a Projection -------------------- +.. io-code-block:: + + .. input:: /includes/code-examples/projection/MetaExamples.cs + :language: csharp + :dedent: 8 + :start-after: // start metaSearchSequenceToken + :end-before: // end metaSearchSequenceToken -The ``ProjectionDefinitionBuilder`` class provides a type-safe interface for -defining a projection. Suppose you want to create a projection on the -``Name`` and ``Price`` fields, but exclude the ``Id`` field. + .. output:: + :visible: false + :language: json -Use builders to create the projection definition with the typed variant: + { + "_id": { + "$oid": "573a13def29313caabdb5661" + }, + "plot": "She Can See Her Future, But Can't Escape Her Past.", + "title": "West", + "paginationToken": "CIeaARWv2zRAIg5aDFc6E97ykxPKq9tWYQ==" + } -.. code-block:: csharp - :copyable: true +To learn more about search sequence tokens, see +:atlas:`Paginate Search Results ` - var builder = Builders.Projection; - var projection = builder.Include(f => f.Name).Include(f => f.Price).Exclude(f => f.Id); +MetaTextScore +~~~~~~~~~~~~~ -You can also use string-based field names to define the projection: +The ``MetaTextScore()`` method includes the ``$text`` search scores in the returned documents. +This is equivalent to projecting the text search score by using a +``{ "$meta": "textScore" }`` object in the {+query-api+}. -.. code-block:: csharp - :copyable: true +For a code example that uses the ``MetaTextScore()`` method, see +:manual:`$meta ` +in the {+mdb-server+} manual. - var builder = Builders.Projection; - var projection = builder.Include("Name").Include("Price").Exclude("Id"); +MetaVectorSearchScore +~~~~~~~~~~~~~~~~~~~~~ -Finally, you can use the ``Expression()`` method to define the -projection: +.. note:: Atlas Vector Search Only -.. code-block:: csharp - :copyable: true + This method is available only when projecting the results of an Atlas Vector Search. - var builder = Builders.Projection; - var projection = builder.Expression(f => new { Name = f.Name, Price = f.Price }); +The ``MetaVectorSearchScore()`` method includes the Atlas Vector Search scores in the +returned documents. This is equivalent to projecting the Vector Search score by using a +``{ "$meta": "vectorSearchScore" }`` object in the {+query-api+}. -This definition has a return type of ``ProjectionDefinition`` whereas the others return a -``ProjectionDefinition``. +For a code example that uses the ``MetaVectorSearchScore()`` method, see +:ref:`Atlas Vector Search `. -Lambda Expressions -~~~~~~~~~~~~~~~~~~ +To learn more about Atlas Vector Search scores, see +:atlas:`Score the Documents in the Returned Documents ` +in the Atlas documentation. -The driver supports using lambda expressions to render projections. When -you define a ``Find()`` projection with the ``Expression()`` method to -create a lambda expression, the driver inspects the expression -to determine which fields are referenced and automatically constructs a -server-side projection to return only those fields. +SearchMeta +~~~~~~~~~~ -You can also use lambda expressions to create new fields by performing -operations on values in your documents. The following example shows how -you can use a lambda expression to project a new ``Profit`` field -using the ``Price`` and ``Stock`` fields: +.. include:: /includes/project/atlas-only-note.rst -.. code-block:: csharp - :copyable: true +The ``SearchMeta()`` method includes a metadata results document. The structure of this +document depends on the type of the results. This is equivalent to projecting the +metadata results document by using the ``$searchMeta`` aggregation stage or the +``$$SEARCH_META`` aggregation variable in the {+query-api+}. - var builder = Builders.Projection; - var projection = builder.Expression(f => new { Profit = f.Price * f.Stock }); +For a code example that uses the ``SearchMeta()`` method, see +:atlas:`How to Use Facets with Atlas Search ` +in the Atlas documentation. -.. note:: ``Id`` Field Exclusion +To learn more about ``$searchMeta`` and ``$$SEARCH_META``, see the following Atlas +documentation: - When you create a projection using a lambda expression, the output - automatically excludes the ``Id`` field unless you explicitly include - is as a projection field. +- :atlas:`$searchMeta ` +- :atlas:`$search with $$SEARCH_META ` -- `ProjectionDefinitionBuilder <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ProjectionDefinitionBuilder-1.html>`__ \ No newline at end of file +API Documentation +----------------- + +To learn more about any of the methods or types discussed in this +guide, see the following API documentation: + +- `Projection <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Builders-1.Projection.html>`_ +- `ProjectionDefinitionBuilder <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ProjectionDefinitionBuilder-1.html>`__ +- `ElemMatch() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ProjectionDefinitionBuilder-1.ElemMatch.html>`__ +- `Exclude() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ProjectionDefinitionBuilder-1.Exclude.html>`__ +- `Expression() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ProjectionDefinitionBuilder-1.Expression.html>`__ +- `Include() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ProjectionDefinitionBuilder-1.Include.html>`__ +- `Meta() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ProjectionDefinitionBuilder-1.Meta.html>`__ +- `MetaSearchHighlights <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ProjectionDefinitionBuilder-1.MetaSearchHighlights.html>`__ +- `MetaSearchScore() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ProjectionDefinitionBuilder-1.MetaSearchScore.html>`__ +- `MetaSearchScoreDetails() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ProjectionDefinitionBuilder-1.MetaSearchScoreDetails.html>`__ +- `MetaSearchSequenceToken() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ProjectionDefinitionBuilder-1.MetaSearchSequenceToken.html>`__ +- `MetaTextScore() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ProjectionDefinitionBuilder-1.MetaTextScore.html>`__ +- `MetaVectorSearchScore() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ProjectionDefinitionBuilder-1.MetaVectorSearchScore.html>`__ +- `SearchMeta() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ProjectionDefinitionBuilder-1.SearchMeta.html>`__ +- `Slice() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ProjectionDefinitionBuilder-1.Slice.html>`__ \ No newline at end of file diff --git a/source/includes/code-examples/projection/MetaExamples.cs b/source/includes/code-examples/projection/MetaExamples.cs new file mode 100644 index 00000000..12253454 --- /dev/null +++ b/source/includes/code-examples/projection/MetaExamples.cs @@ -0,0 +1,198 @@ +using MongoDB.Bson; +using MongoDB.Driver; +using MongoDB.Driver.Search; + +namespace Projection; + +public class MetaExamples +{ + static string _uri = ""; + + static IMongoCollection movieCollection = new MongoClient(_uri) + .GetDatabase("sample_mflix") + .GetCollection("movies"); + + static IMongoCollection embeddedMovieCollection = new MongoClient(_uri) + .GetDatabase("sample_mflix") + .GetCollection("embedded_movies"); + + public static List MetaTextScoreExample() + { + // start metaTextScore + var filter = Builders.Filter.Text("future"); + var projection = Builders.Projection + .Include(m => m.Title) + .Include(m => m.Plot) + .MetaTextScore("score"); + + var results = movieCollection.Find(filter) + .Project(projection) + .Limit(1) + .ToList(); + // end metaTextScore + + return results; + } + + public static List MetaExample() + { + // start meta + var filter = Builders.Filter.Text("future"); + var projection = Builders.Projection + .Include(m => m.Title) + .Include(m => m.Plot) + .Meta(field: "score", metaFieldName: "textScore"); + + var results = movieCollection.Find(filter) + .Project(projection) + .Limit(1) + .ToList(); + // end meta + + return results; + } + + public static List MetaScoreExample() + { + // start metaScore + var filter = Builders.Search.Text(m => m.Title, "future"); + var projection = Builders.Projection + .Include(m => m.Title) + .Include(m => m.Plot) + .MetaScore(m => m.ScoreDetails); + + var results = movieCollection + .Aggregate() + .Search(filter) + .Project(projection) + .Limit(1) + .ToList(); + // end metaScore + + return results; + } + + public static List MetaScoreDetailsExample() + { + // start metaScoreDetails + var filter = Builders.Filter.Text("future"); + var projection = Builders.Projection + .Include(m => m.Title) + .Include(m => m.Plot) + .MetaScoreDetails(m => m.ScoreDetails); + + var results = movieCollection.Find(filter) + .Project(projection) + .Limit(1) + .ToList(); + // end metaScoreDetails + + return results; + } + + public static List MetaSearchHighlightsExample() + { + // start metaSearchHighlights + var filter = Builders.Search.Text(path: m => m.Plot, query: "future"); + var projection = Builders.Projection + .Include(m => m.Title) + .Include(m => m.Plot) + .MetaSearchHighlights(m => m.Highlights); + + var results = movieCollection + .Aggregate() + .Search(filter, new SearchHighlightOptions (m => m.Plot)) + .Project(projection) + .Limit(1) + .ToList(); + // end metaSearchHighlights + + return results; + } + + public static List MetaSearchScoreExample() + { + // start metaSearchScore + var filter = Builders.Search.Text(m => m.Plot, "future"); + var projection = Builders.Projection + .Include(m => m.Title) + .Include(m => m.Plot) + .MetaSearchScore(m => m.Score); + + var results = movieCollection + .Aggregate() + .Search(filter) + .Project(projection) + .Limit(1) + .ToList(); + // end metaSearchScore + + return results; + } + + public static List MetaSearchScoreDetailsExample() + { + // start metaSearchScoreDetails + var filter = Builders.Search.Text(m => m.Plot, "future"); + var projection = Builders.Projection + .Include(m => m.Title) + .Include(m => m.Plot) + .MetaSearchScore(m => m.Score) + .MetaSearchScoreDetails(m => m.SearchScoreDetails); + + var results = movieCollection + .Aggregate() + .Search(filter, new SearchOptions() { ScoreDetails = true}) + .Project(projection) + .Limit(1) + .ToList(); + // end metaSearchScoreDetails + + return results; + } + + public static List MetaSearchSequenceTokenExample() + { + // start metaSearchSequenceToken + var filter = Builders.Search.Text(m => m.Plot, "future"); + var projection = Builders.Projection + .Include(m => m.Title) + .Include(m => m.Plot) + .MetaSearchSequenceToken(m => m.PaginationToken); + + var results = movieCollection + .Aggregate() + .Search(filter) + .Limit(1) + .Project(projection) + .ToList(); + // end metaSearchSequenceToken + + return results; + } + + public static List MetaVectorSearchScoreExample() + { + // start metaVectorSearchScore + QueryVector vector = new[] { -0.0016261312, -0.028070757, -0.011342932, -0.012775794, -0.0027440966, 0.008683807, -0.02575152, -0.02020668, -0.010283281, -0.0041719596, 0.021392956, 0.028657231, -0.006634482, 0.007490867, 0.018593878, 0.0038187427, 0.029590257, -0.01451522, 0.016061379, 0.00008528442, -0.008943722, 0.01627464, 0.024311995, -0.025911469, 0.00022596726, -0.008863748, 0.008823762, -0.034921836, 0.007910728, -0.01515501, 0.035801545, -0.0035688248, -0.020299982, -0.03145631, -0.032256044, -0.028763862, -0.0071576433, -0.012769129, 0.012322609, -0.006621153, 0.010583182, 0.024085402, -0.001623632, 0.007864078, -0.021406285, 0.002554159, 0.012229307, -0.011762793, 0.0051682983, 0.0048484034, 0.018087378, 0.024325324, -0.037694257, -0.026537929, -0.008803768, -0.017767483, -0.012642504, -0.0062712682, 0.0009771782, -0.010409906, 0.017754154, -0.004671795, -0.030469967, 0.008477209, -0.005218282, -0.0058480743, -0.020153364, -0.0032805866, 0.004248601, 0.0051449724, 0.006791097, 0.007650814, 0.003458861, -0.0031223053, -0.01932697, -0.033615597, 0.00745088, 0.006321252, -0.0038154104, 0.014555207, 0.027697546, -0.02828402, 0.0066711367, 0.0077107945, 0.01794076, 0.011349596, -0.0052715978, 0.014755142, -0.019753495, -0.011156326, 0.011202978, 0.022126047, 0.00846388, 0.030549942, -0.0041386373, 0.018847128, -0.00033655585, 0.024925126, -0.003555496, -0.019300312, 0.010749794, 0.0075308536, -0.018287312, -0.016567878, -0.012869096, -0.015528221, 0.0078107617, -0.011156326, 0.013522214, -0.020646535, -0.01211601, 0.055928253, 0.011596181, -0.017247654, 0.0005939711, -0.026977783, -0.003942035, -0.009583511, -0.0055248477, -0.028737204, 0.023179034, 0.003995351, 0.0219661, -0.008470545, 0.023392297, 0.010469886, -0.015874773, 0.007890735, -0.009690142, -0.00024970944, 0.012775794, 0.0114762215, 0.013422247, 0.010429899, -0.03686786, -0.006717788, -0.027484283, 0.011556195, -0.036068123, -0.013915418, -0.0016327957, 0.0151016945, -0.020473259, 0.004671795, -0.012555866, 0.0209531, 0.01982014, 0.024485271, 0.0105431955, -0.005178295, 0.033162415, -0.013795458, 0.007150979, 0.010243294, 0.005644808, 0.017260984, -0.0045618312, 0.0024725192, 0.004305249, -0.008197301, 0.0014203656, 0.0018460588, 0.005015015, -0.011142998, 0.01439526, 0.022965772, 0.02552493, 0.007757446, -0.0019726837, 0.009503538, -0.032042783, 0.008403899, -0.04609149, 0.013808787, 0.011749465, 0.036388017, 0.016314628, 0.021939443, -0.0250051, -0.017354285, -0.012962398, 0.00006107364, 0.019113706, 0.03081652, -0.018114036, -0.0084572155, 0.009643491, -0.0034721901, 0.0072642746, -0.0090636825, 0.01642126, 0.013428912, 0.027724205, 0.0071243206, -0.6858542, -0.031029783, -0.014595194, -0.011449563, 0.017514233, 0.01743426, 0.009950057, 0.0029706885, -0.015714826, -0.001806072, 0.011856096, 0.026444625, -0.0010663156, -0.006474535, 0.0016161345, -0.020313311, 0.0148351155, -0.0018393943, 0.0057347785, 0.018300641, -0.018647194, 0.03345565, -0.008070676, 0.0071443142, 0.014301958, 0.0044818576, 0.003838736, -0.007350913, -0.024525259, -0.001142124, -0.018620536, 0.017247654, 0.007037683, 0.010236629, 0.06046009, 0.0138887605, -0.012122675, 0.037694257, 0.0055081863, 0.042492677, 0.00021784494, -0.011656162, 0.010276617, 0.022325981, 0.005984696, -0.009496873, 0.013382261, -0.0010563189, 0.0026507939, -0.041639622, 0.008637156, 0.026471283, -0.008403899, 0.024858482, -0.00066686375, -0.0016252982, 0.027590916, 0.0051449724, 0.0058647357, -0.008743787, -0.014968405, 0.027724205, -0.011596181, 0.0047650975, -0.015381602, 0.0043718936, 0.002159289, 0.035908177, -0.008243952, -0.030443309, 0.027564257, 0.042625964, -0.0033688906, 0.01843393, 0.019087048, 0.024578573, 0.03268257, -0.015608194, -0.014128681, -0.0033538956, -0.0028757197, -0.004121976, -0.032389335, 0.0034322033, 0.058807302, 0.010943064, -0.030523283, 0.008903735, 0.017500903, 0.00871713, -0.0029406983, 0.013995391, -0.03132302, -0.019660193, -0.00770413, -0.0038853872, 0.0015894766, -0.0015294964, -0.006251275, -0.021099718, -0.010256623, -0.008863748, 0.028550599, 0.02020668, -0.0012962399, -0.003415542, -0.0022509254, 0.0119360695, 0.027590916, -0.046971202, -0.0015194997, -0.022405956, 0.0016677842, -0.00018535563, -0.015421589, -0.031802863, 0.03814744, 0.0065411795, 0.016567878, -0.015621523, 0.022899127, -0.011076353, 0.02841731, -0.002679118, -0.002342562, 0.015341615, 0.01804739, -0.020566562, -0.012989056, -0.002990682, 0.01643459, 0.00042527664, 0.008243952, -0.013715484, -0.004835075, -0.009803439, 0.03129636, -0.021432944, 0.0012087687, -0.015741484, -0.0052016205, 0.00080890034, -0.01755422, 0.004811749, -0.017967418, -0.026684547, -0.014128681, 0.0041386373, -0.013742141, -0.010056688, -0.013268964, -0.0110630235, -0.028337335, 0.015981404, -0.00997005, -0.02424535, -0.013968734, -0.028310679, -0.027750863, -0.020699851, 0.02235264, 0.001057985, 0.00081639783, -0.0099367285, 0.013522214, -0.012016043, -0.00086471526, 0.013568865, 0.0019376953, -0.019020405, 0.017460918, -0.023045745, 0.008503866, 0.0064678704, -0.011509543, 0.018727167, -0.003372223, -0.0028690554, -0.0027024434, -0.011902748, -0.012182655, -0.015714826, -0.0098634185, 0.00593138, 0.018753825, 0.0010146659, 0.013029044, 0.0003521757, -0.017620865, 0.04102649, 0.00552818, 0.024485271, -0.009630162, -0.015608194, 0.0006718621, -0.0008418062, 0.012395918, 0.0057980907, 0.016221326, 0.010616505, 0.004838407, -0.012402583, 0.019900113, -0.0034521967, 0.000247002, -0.03153628, 0.0011038032, -0.020819811, 0.016234655, -0.00330058, -0.0032289368, 0.00078973995, -0.021952773, -0.022459272, 0.03118973, 0.03673457, -0.021472929, 0.0072109587, -0.015075036, 0.004855068, -0.0008151483, 0.0069643734, 0.010023367, -0.010276617, -0.023019087, 0.0068244194, -0.0012520878, -0.0015086699, 0.022046074, -0.034148756, -0.0022192693, 0.002427534, -0.0027124402, 0.0060346797, 0.015461575, 0.0137554705, 0.009230294, -0.009583511, 0.032629255, 0.015994733, -0.019167023, -0.009203636, 0.03393549, -0.017274313, -0.012042701, -0.0009930064, 0.026777849, -0.013582194, -0.0027590916, -0.017594207, -0.026804507, -0.0014236979, -0.022032745, 0.0091236625, -0.0042419364, -0.00858384, -0.0033905501, -0.020739838, 0.016821127, 0.022539245, 0.015381602, 0.015141681, 0.028817179, -0.019726837, -0.0051283115, -0.011489551, -0.013208984, -0.0047017853, -0.0072309524, 0.01767418, 0.0025658219, -0.010323267, 0.012609182, -0.028097415, 0.026871152, -0.010276617, 0.021912785, 0.0022542577, 0.005124979, -0.0019710176, 0.004518512, -0.040360045, 0.010969722, -0.0031539614, -0.020366628, -0.025778178, -0.0110030435, -0.016221326, 0.0036587953, 0.016207997, 0.003007343, -0.0032555948, 0.0044052163, -0.022046074, -0.0008822095, -0.009363583, 0.028230704, -0.024538586, 0.0029840174, 0.0016044717, -0.014181997, 0.031349678, -0.014381931, -0.027750863, 0.02613806, 0.0004136138, -0.005748107, -0.01868718, -0.0010138329, 0.0054348772, 0.010703143, -0.003682121, 0.0030856507, -0.004275259, -0.010403241, 0.021113047, -0.022685863, -0.023032416, 0.031429652, 0.001792743, -0.005644808, -0.011842767, -0.04078657, -0.0026874484, 0.06915057, -0.00056939584, -0.013995391, 0.010703143, -0.013728813, -0.022939114, -0.015261642, -0.022485929, 0.016807798, 0.007964044, 0.0144219175, 0.016821127, 0.0076241563, 0.005461535, -0.013248971, 0.015301628, 0.0085171955, -0.004318578, 0.011136333, -0.0059047225, -0.010249958, -0.018207338, 0.024645219, 0.021752838, 0.0007614159, -0.013648839, 0.01111634, -0.010503208, -0.0038487327, -0.008203966, -0.00397869, 0.0029740208, 0.008530525, 0.005261601, 0.01642126, -0.0038753906, -0.013222313, 0.026537929, 0.024671877, -0.043505676, 0.014195326, 0.024778508, 0.0056914594, -0.025951454, 0.017620865, -0.0021359634, 0.008643821, 0.021299653, 0.0041686273, -0.009017031, 0.04044002, 0.024378639, -0.027777521, -0.014208655, 0.0028623908, 0.042119466, 0.005801423, -0.028124074, -0.03129636, 0.022139376, -0.022179363, -0.04067994, 0.013688826, 0.013328944, 0.0046184794, -0.02828402, -0.0063412455, -0.0046184794, -0.011756129, -0.010383247, -0.0018543894, -0.0018593877, -0.00052024535, 0.004815081, 0.014781799, 0.018007403, 0.01306903, -0.020433271, 0.009043689, 0.033189073, -0.006844413, -0.019766824, -0.018767154, 0.00533491, -0.0024575242, 0.018727167, 0.0058080875, -0.013835444, 0.0040719924, 0.004881726, 0.012029372, 0.005664801, 0.03193615, 0.0058047553, 0.002695779, 0.009290274, 0.02361889, 0.017834127, 0.0049017193, -0.0036388019, 0.010776452, -0.019793482, 0.0067777685, -0.014208655, -0.024911797, 0.002385881, 0.0034988478, 0.020899786, -0.0025858153, -0.011849431, 0.033189073, -0.021312982, 0.024965113, -0.014635181, 0.014048708, -0.0035921505, -0.003347231, 0.030869836, -0.0017161017, -0.0061346465, 0.009203636, -0.025165047, 0.0068510775, 0.021499587, 0.013782129, -0.0024475274, -0.0051149824, -0.024445284, 0.006167969, 0.0068844, -0.00076183246, 0.030150073, -0.0055948244, -0.011162991, -0.02057989, -0.009703471, -0.020646535, 0.008004031, 0.0066378145, -0.019900113, -0.012169327, -0.01439526, 0.0044252095, -0.004018677, 0.014621852, -0.025085073, -0.013715484, -0.017980747, 0.0071043274, 0.011456228, -0.01010334, -0.0035321703, -0.03801415, -0.012036037, -0.0028990454, -0.05419549, -0.024058744, -0.024272008, 0.015221654, 0.027964126, 0.03182952, -0.015354944, 0.004855068, 0.011522872, 0.004771762, 0.0027874154, 0.023405626, 0.0004242353, -0.03132302, 0.007057676, 0.008763781, -0.0027057757, 0.023005757, -0.0071176565, -0.005238275, 0.029110415, -0.010989714, 0.013728813, -0.009630162, -0.029137073, -0.0049317093, -0.0008630492, -0.015248313, 0.0043219104, -0.0055681667, -0.013175662, 0.029723546, 0.025098402, 0.012849103, -0.0009996708, 0.03118973, -0.0021709518, 0.0260181, -0.020526575, 0.028097415, -0.016141351, 0.010509873, -0.022965772, 0.002865723, 0.0020493253, 0.0020509914, -0.0041419696, -0.00039695262, 0.017287642, 0.0038987163, 0.014795128, -0.014661839, -0.008950386, 0.004431874, -0.009383577, 0.0012604183, -0.023019087, 0.0029273694, -0.033135757, 0.009176978, -0.011023037, -0.002102641, 0.02663123, -0.03849399, -0.0044152127, 0.0004527676, -0.0026924468, 0.02828402, 0.017727496, 0.035135098, 0.02728435, -0.005348239, -0.001467017, -0.019766824, 0.014715155, 0.011982721, 0.0045651635, 0.023458943, -0.0010046692, -0.0031373003, -0.0006972704, 0.0019043729, -0.018967088, -0.024311995, 0.0011546199, 0.007977373, -0.004755101, -0.010016702, -0.02780418, -0.004688456, 0.013022379, -0.005484861, 0.0017227661, -0.015394931, -0.028763862, -0.026684547, 0.0030589928, -0.018513903, 0.028363993, 0.0044818576, -0.009270281, 0.038920518, -0.016008062, 0.0093902415, 0.004815081, -0.021059733, 0.01451522, -0.0051583014, 0.023765508, -0.017874114, -0.016821127, -0.012522544, -0.0028390652, 0.0040886537, 0.020259995, -0.031216389, -0.014115352, -0.009176978, 0.010303274, 0.020313311, 0.0064112223, -0.02235264, -0.022872468, 0.0052449396, 0.0005723116, 0.0037321046, 0.016807798, -0.018527232, -0.009303603, 0.0024858483, -0.0012662497, -0.007110992, 0.011976057, -0.007790768, -0.042999174, -0.006727785, -0.011829439, 0.007024354, 0.005278262, -0.017740825, -0.0041519664, 0.0085905045, 0.027750863, -0.038387362, 0.024391968, 0.00087721116, 0.010509873, -0.00038508154, -0.006857742, 0.0183273, -0.0037054466, 0.015461575, 0.0017394272, -0.0017944091, 0.014181997, -0.0052682655, 0.009023695, 0.00719763, -0.013522214, 0.0034422, 0.014941746, -0.0016711164, -0.025298337, -0.017634194, 0.0058714002, -0.005321581, 0.017834127, 0.0110630235, -0.03369557, 0.029190388, -0.008943722, 0.009363583, -0.0034222065, -0.026111402, -0.007037683, -0.006561173, 0.02473852, -0.007084334, -0.010110005, -0.008577175, 0.0030439978, -0.022712521, 0.0054582027, -0.0012620845, -0.0011954397, -0.015741484, 0.0129557345, -0.00042111133, 0.00846388, 0.008930393, 0.016487904, 0.010469886, -0.007917393, -0.011762793, -0.0214596, 0.000917198, 0.021672864, 0.010269952, -0.007737452, -0.010243294, -0.0067244526, -0.015488233, -0.021552904, 0.017127695, 0.011109675, 0.038067464, 0.00871713, -0.0025591573, 0.021312982, -0.006237946, 0.034628596, -0.0045251767, 0.008357248, 0.020686522, 0.0010696478, 0.0076708077, 0.03772091, -0.018700508, -0.0020676525, -0.008923728, -0.023298996, 0.018233996, -0.010256623, 0.0017860786, 0.009796774, -0.00897038, -0.01269582, -0.018527232, 0.009190307, -0.02372552, -0.042119466, 0.008097334, -0.0066778013, -0.021046404, 0.0019593548, 0.011083017, -0.0016028056, 0.012662497, -0.000059095124, 0.0071043274, -0.014675168, 0.024831824, -0.053582355, 0.038387362, 0.0005698124, 0.015954746, 0.021552904, 0.031589597, -0.009230294, -0.0006147976, 0.002625802, -0.011749465, -0.034362018, -0.0067844326, -0.018793812, 0.011442899, -0.008743787, 0.017474247, -0.021619547, 0.01831397, -0.009037024, -0.0057247817, -0.02728435, 0.010363255, 0.034415334, -0.024032086, -0.0020126705, -0.0045518344, -0.019353628, -0.018340627, -0.03129636, -0.0034038792, -0.006321252, -0.0016161345, 0.033642255, -0.000056075285, -0.005005019, 0.004571828, -0.0024075406, -0.00010215386, 0.0098634185, 0.1980148, -0.003825407, -0.025191706, 0.035161756, 0.005358236, 0.025111731, 0.023485601, 0.0023342315, -0.011882754, 0.018287312, -0.0068910643, 0.003912045, 0.009243623, -0.001355387, -0.028603915, -0.012802451, -0.030150073, -0.014795128, -0.028630573, -0.0013487226, 0.002667455, 0.00985009, -0.0033972147, -0.021486258, 0.009503538, -0.017847456, 0.013062365, -0.014341944, 0.005078328, 0.025165047, -0.015594865, -0.025924796, -0.0018177348, 0.010996379, -0.02993681, 0.007324255, 0.014475234, -0.028577257, 0.005494857, 0.00011725306, -0.013315615, 0.015941417, 0.009376912, 0.0025158382, 0.008743787, 0.023832154, -0.008084005, -0.014195326, -0.008823762, 0.0033455652, -0.032362677, -0.021552904, -0.0056081535, 0.023298996, -0.025444955, 0.0097301295, 0.009736794, 0.015274971, -0.0012937407, -0.018087378, -0.0039387033, 0.008637156, -0.011189649, -0.00023846315, -0.011582852, 0.0066411467, -0.018220667, 0.0060846633, 0.0376676, -0.002709108, 0.0072776037, 0.0034188742, -0.010249958, -0.0007747449, -0.00795738, -0.022192692, 0.03910712, 0.032122757, 0.023898797, 0.0076241563, -0.007397564, -0.003655463, 0.011442899, -0.014115352, -0.00505167, -0.031163072, 0.030336678, -0.006857742, -0.022259338, 0.004048667, 0.02072651, 0.0030156737, -0.0042119464, 0.00041861215, -0.005731446, 0.011103011, 0.013822115, 0.021512916, 0.009216965, -0.006537847, -0.027057758, -0.04054665, 0.010403241, -0.0056281467, -0.005701456, -0.002709108, -0.00745088, -0.0024841821, 0.009356919, -0.022659205, 0.004061996, -0.013175662, 0.017074378, -0.006141311, -0.014541878, 0.02993681, -0.00028448965, -0.025271678, 0.011689484, -0.014528549, 0.004398552, -0.017274313, 0.0045751603, 0.012455898, 0.004121976, -0.025458284, -0.006744446, 0.011822774, -0.015035049, -0.03257594, 0.014675168, -0.0039187097, 0.019726837, -0.0047251107, 0.0022825818, 0.011829439, 0.005391558, -0.016781142, -0.0058747325, 0.010309938, -0.013049036, 0.01186276, -0.0011246296, 0.0062112883, 0.0028190718, -0.021739509, 0.009883412, -0.0073175905, -0.012715813, -0.017181009, -0.016607866, -0.042492677, -0.0014478565, -0.01794076, 0.012302616, -0.015194997, -0.04433207, -0.020606548, 0.009696807, 0.010303274, -0.01694109, -0.004018677, 0.019353628, -0.001991011, 0.000058938927, 0.010536531, -0.17274313, 0.010143327, 0.014235313, -0.024152048, 0.025684876, -0.0012504216, 0.036601283, -0.003698782, 0.0007310093, 0.004165295, -0.0029157067, 0.017101036, -0.046891227, -0.017460918, 0.022965772, 0.020233337, -0.024072073, 0.017220996, 0.009370248, 0.0010363255, 0.0194336, -0.019606877, 0.01818068, -0.020819811, 0.007410893, 0.0019326969, 0.017887443, 0.006651143, 0.00067394477, -0.011889419, -0.025058415, -0.008543854, 0.021579562, 0.0047484366, 0.014062037, 0.0075508473, -0.009510202, -0.009143656, 0.0046817916, 0.013982063, -0.0027990784, 0.011782787, 0.014541878, -0.015701497, -0.029350337, 0.021979429, 0.01332228, -0.026244693, -0.0123492675, -0.003895384, 0.0071576433, -0.035454992, -0.00046984528, 0.0033522295, 0.039347045, 0.0005119148, 0.00476843, -0.012995721, 0.0024042083, -0.006931051, -0.014461905, -0.0127558, 0.0034555288, -0.0074842023, -0.030256703, -0.007057676, -0.00807734, 0.007804097, -0.006957709, 0.017181009, -0.034575284, -0.008603834, -0.005008351, -0.015834786, 0.02943031, 0.016861115, -0.0050849924, 0.014235313, 0.0051449724, 0.0025924798, -0.0025741523, 0.04289254, -0.002104307, 0.012969063, -0.008310596, 0.00423194, 0.0074975314, 0.0018810473, -0.014248641, -0.024725191, 0.0151016945, -0.017527562, 0.0018727167, 0.0002830318, 0.015168339, 0.0144219175, -0.004048667, -0.004358565, 0.011836103, -0.010343261, -0.005911387, 0.0022825818, 0.0073175905, 0.00403867, 0.013188991, 0.03334902, 0.006111321, 0.008597169, 0.030123414, -0.015474904, 0.0017877447, -0.024551915, 0.013155668, 0.023525586, -0.0255116, 0.017220996, 0.004358565, -0.00934359, 0.0099967085, 0.011162991, 0.03092315, -0.021046404, -0.015514892, 0.0011946067, -0.01816735, 0.010876419, -0.10124666, -0.03550831, 0.0056348112, 0.013942076, 0.005951374, 0.020419942, -0.006857742, -0.020873128, -0.021259667, 0.0137554705, 0.0057880944, -0.029163731, -0.018767154, -0.021392956, 0.030896494, -0.005494857, -0.0027307675, -0.006801094, -0.014821786, 0.021392956, -0.0018110704, -0.0018843795, -0.012362596, -0.0072176233, -0.017194338, -0.018713837, -0.024272008, 0.03801415, 0.00015880188, 0.0044951867, -0.028630573, -0.0014070367, -0.00916365, -0.026537929, -0.009576847, -0.013995391, -0.0077107945, 0.0050016865, 0.00578143, -0.04467862, 0.008363913, 0.010136662, -0.0006268769, -0.006591163, 0.015341615, -0.027377652, -0.00093136, 0.029243704, -0.020886457, -0.01041657, -0.02424535, 0.005291591, -0.02980352, -0.009190307, 0.019460259, -0.0041286405, 0.004801752, 0.0011787785, -0.001257086, -0.011216307, -0.013395589, 0.00088137644, -0.0051616337, 0.03876057, -0.0033455652, 0.00075850025, -0.006951045, -0.0062112883, 0.018140694, -0.006351242, -0.008263946, 0.018154023, -0.012189319, 0.0075508473, -0.044358727, -0.0040153447, 0.0093302615, -0.010636497, 0.032789204, -0.005264933, -0.014235313, -0.018393943, 0.007297597, -0.016114693, 0.015021721, 0.020033404, 0.0137688, 0.0011046362, 0.010616505, -0.0039453674, 0.012109346, 0.021099718, -0.0072842683, -0.019153694, -0.003768759, 0.039320387, -0.006747778, -0.0016852784, 0.018154023, 0.0010963057, -0.015035049, -0.021033075, -0.04345236, 0.017287642, 0.016341286, -0.008610498, 0.00236922, 0.009290274, 0.028950468, -0.014475234, -0.0035654926, 0.015434918, -0.03372223, 0.004501851, -0.012929076, -0.008483873, -0.0044685286, -0.0102233, 0.01615468, 0.0022792495, 0.010876419, -0.0059647025, 0.01895376, -0.0069976957, -0.0042952523, 0.017207667, -0.00036133936, 0.0085905045, 0.008084005, 0.03129636, -0.016994404, -0.014915089, 0.020100048, -0.012009379, -0.006684466, 0.01306903, 0.00015765642, -0.00530492, 0.0005277429, 0.015421589, 0.015528221, 0.032202728, -0.003485519, -0.0014286962, 0.033908837, 0.001367883, 0.010509873, 0.025271678, -0.020993087, 0.019846799, 0.006897729, -0.010216636, -0.00725761, 0.01818068, -0.028443968, -0.011242964, -0.014435247, -0.013688826, 0.006101324, -0.0022509254, 0.013848773, -0.0019077052, 0.017181009, 0.03422873, 0.005324913, -0.0035188415, 0.014128681, -0.004898387, 0.005038341, 0.0012320944, -0.005561502, -0.017847456, 0.0008538855, -0.0047884234, 0.011849431, 0.015421589, -0.013942076, 0.0029790192, -0.013702155, 0.0001199605, -0.024431955, 0.019926772, 0.022179363, -0.016487904, -0.03964028, 0.0050849924, 0.017487574, 0.022792496, 0.0012504216, 0.004048667, -0.00997005, 0.0076041627, -0.014328616, -0.020259995, 0.0005598157, -0.010469886, 0.0016852784, 0.01716768, -0.008990373, -0.001987679, 0.026417969, 0.023792166, 0.0046917885, -0.0071909656, -0.00032051947, -0.023259008, -0.009170313, 0.02071318, -0.03156294, -0.030869836, -0.006324584, 0.013795458, -0.00047151142, 0.016874444, 0.00947688, 0.00985009, -0.029883493, 0.024205362, -0.013522214, -0.015075036, -0.030603256, 0.029270362, 0.010503208, 0.021539574, 0.01743426, -0.023898797, 0.022019416, -0.0068777353, 0.027857494, -0.021259667, 0.0025758184, 0.006197959, 0.006447877, -0.00025200035, -0.004941706, -0.021246338, -0.005504854, -0.008390571, -0.0097301295, 0.027244363, -0.04446536, 0.05216949, 0.010243294, -0.016008062, 0.0122493, -0.0199401, 0.009077012, 0.019753495, 0.006431216, -0.037960835, -0.027377652, 0.016381273, -0.0038620618, 0.022512587, -0.010996379, -0.0015211658, -0.0102233, 0.007071005, 0.008230623, -0.009490209, -0.010083347, 0.024431955, 0.002427534, 0.02828402, 0.0035721571, -0.022192692, -0.011882754, 0.010056688, 0.0011904413, -0.01426197, -0.017500903, -0.00010985966, 0.005591492, -0.0077707744, -0.012049366, 0.011869425, 0.00858384, -0.024698535, -0.030283362, 0.020140035, 0.011949399, -0.013968734, 0.042732596, -0.011649498, -0.011982721, -0.016967745, -0.0060913274, -0.007130985, -0.013109017, -0.009710136 }; + + var options = new VectorSearchOptions() + { + IndexName = "vector_index", + NumberOfCandidates = 150 + }; + + // run query + var results = embeddedMovieCollection + .Aggregate() + .VectorSearch(movie => movie.PlotEmbedding, vector, 10, options) + .Project(Builders.Projection + .Include(movie => movie.Title) + .Include(movie => movie.Plot) + .MetaVectorSearchScore(m => m.Score)) + .ToList(); + // end metaVectorSearchScore + + return results; + } +} \ No newline at end of file diff --git a/source/includes/code-examples/projection/Movie.cs b/source/includes/code-examples/projection/Movie.cs new file mode 100644 index 00000000..8cc8046f --- /dev/null +++ b/source/includes/code-examples/projection/Movie.cs @@ -0,0 +1,30 @@ +public class Movie +{ + public ObjectId Id { get; set; } + + public string Title { get; set; } + + public List Genres { get; set; } + + public string Type { get; set; } + + public string Plot { get; set; } + + public List Highlights { get; set; } + + public string Score { get; set; } + + [BsonElement("scoreDetails")] + public SearchScoreDetails ScoreDetails { get; set; } + + [BsonElement("searchScoreDetails")] + public SearchScoreDetails SearchScoreDetails { get; set; } + + [BsonElement("paginationToken")] + public string PaginationToken { get; set; } + + public List Cast { get; set; } + + [BsonElement("plot_embedding")] + public float[] PlotEmbedding { get; set; } +} \ No newline at end of file diff --git a/source/includes/code-examples/projection/SliceExamples.cs b/source/includes/code-examples/projection/SliceExamples.cs new file mode 100644 index 00000000..b190a5a9 --- /dev/null +++ b/source/includes/code-examples/projection/SliceExamples.cs @@ -0,0 +1,67 @@ +using MongoDB.Bson; +using MongoDB.Driver; + +namespace Projection; + +public class SliceExamples +{ + static string _uri = ""; + + static IMongoCollection movieCollection = new MongoClient(_uri) + .GetDatabase("sample_mflix") + .GetCollection("movies"); + + public static List FirstThreeExample() + { + // start first three + var filter = Builders.Filter.Text("future"); + var projection = Builders + .Projection + .Slice(m => m.Cast, 3) + .Include(m => m.Cast); + + var results = movieCollection.Find(filter) + .Project(projection) + .Limit(1) + .ToList(); + // end first three + + return results; + } + + public static List LastThreeExample() + { + // start last three + var filter = Builders.Filter.Text("future"); + var projection = Builders + .Projection + .Slice(m => m.Cast, -3) + .Include(m => m.Title); + + var results = movieCollection.Find(filter) + .Project(projection) + .Limit(1) + .ToList(); + // end last three + + return results; + } + + public static List SkipFirstLimitThreeExample() + { + // start skip first limit three + var filter = Builders.Filter.Text("future"); + var projection = Builders + .Projection + .Slice(m => m.Cast, 1, 3) + .Include(m => m.Title); + + var results = movieCollection.Find(filter) + .Project(projection) + .Limit(1) + .ToList(); + // end skip first limit three + + return results; + } +} \ No newline at end of file diff --git a/source/includes/project/atlas-only-note.rst b/source/includes/project/atlas-only-note.rst new file mode 100644 index 00000000..c44681f7 --- /dev/null +++ b/source/includes/project/atlas-only-note.rst @@ -0,0 +1,3 @@ +.. note:: Atlas Search Only + + This method is available only when projecting the results of an Atlas Search. \ No newline at end of file diff --git a/source/includes/vector-search-intro.rst b/source/includes/vector-search-intro.rst new file mode 100644 index 00000000..c380225d --- /dev/null +++ b/source/includes/vector-search-intro.rst @@ -0,0 +1,106 @@ +The ``$vectorSearch`` aggregation stage performs an *approximate nearest neighbor* search +on a vector in the specified field. Your collection *must* have a +defined Atlas Vector Search index before you can perform a vector search on your data. + +.. tip:: + + To obtain the sample dataset used in the following example, see :ref:`csharp-get-started`. + To create the sample Atlas Vector Search index used in the following example, see + :atlas:`Create an Atlas Vector Search Index ` in the + Atlas manual. + +To create a ``$vectorSearch`` pipeline stage, call the ``VectorSearch()`` method on a +``PipelineStageDefinitionBuilder`` object. The ``VectorSearch()`` method accepts the +following parameters: + +.. list-table:: + :header-rows: 1 + :widths: 20 80 + + * - Parameter + - Description + + * - ``field`` + - The field to perform the vector search on. + + **Data type**: ``Expression>`` + + * - ``queryVector`` + - The encoded vector that will be matched with values from the database. + Although the data type of this parameter is ``QueryVector``, you can also pass an + array of ``float`` values. + + **Data type**: `QueryVector <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.QueryVector.html>`__ + + * - ``limit`` + - The maximum number of documents to return. + + **Data type**: {+int-data-type+} + + * - ``options`` + - Configuration options for the vector search operation. + + **Data type**: `VectorSearchOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.VectorSearchOptions-1.html>`__ + +You can use the ``options`` parameter to configure your vector search operation. The +``VectorSearchOptions`` class contains the following properties: + +.. list-table:: + :header-rows: 1 + :widths: 30 70 + + * - Property + - Description + + * - ``Exact`` + - Whether the vector search uses the exact nearest neighbor (ENN) algorithm. + If this property is set to ``false``, the vector search uses the approximate nearest + neighbor (ANN) algorithm. If this property is set to ``true``, the + ``NumberOfCandidates`` property must be ``null``. + + | **Data type**: {+bool-data-type+} + | **Default**: ``false`` + + * - ``Filter`` + - Additional search criteria that the found documents must match. + + | **Data Type:** `FilterDefinition <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.FilterDefinition-1.html>`__ + | **Default**: ``null`` + + * - ``IndexName`` + - The index to perform the vector search on. + + | **Data type**: {+string-data-type+} + | **Default**: ``null`` + + * - ``NumberOfCandidates`` + - The number of neighbors to search in the index. + + | **Data type**: ``int?`` + | **Default**: ``null`` + +Consider the ``embedded_movies`` collection in the ``sample_mflix`` database. +The following ``EmbeddedMovie`` class represents a document in this database: + +.. code-block:: csharp + + public class EmbeddedMovie + { + [BsonElement("title")] + public string Title { get; set; } + + [BsonElement("plot_embedding")] + public double[] Embedding { get; set; } + + [BsonElement("score")] + public double Score { get; set; } + } + +You can use a ``$vectorSearch`` stage to perform a semantic search on the ``plot_embedding`` +field of the documents in the collection. +The following example shows how to use |mechanism| to generate an aggregation pipeline to +perform the following operations: + +- Perform a vector search on the Atlas Vector Search index of the ``plot_embedding`` + field by using vector embeddings for the string ``"time travel"`` +- Fetch the ``Title`` and ``Plot`` fields from documents found in the vector search \ No newline at end of file diff --git a/source/reference/quick-reference.txt b/source/reference/quick-reference.txt index 3e81573a..60cea226 100644 --- a/source/reference/quick-reference.txt +++ b/source/reference/quick-reference.txt @@ -528,7 +528,7 @@ their related reference and API documentation. * - | **Project Document Fields When Retrieving Them** | | `API Documentation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ProjectionDefinitionBuilder-1.html>`__ - | :ref:`Fundamentals ` + | :ref:`Fundamentals ` - .. io-code-block:: :copyable: true diff --git a/source/serialization.txt b/source/serialization.txt index 1bac49e5..a20bd58e 100644 --- a/source/serialization.txt +++ b/source/serialization.txt @@ -21,7 +21,7 @@ Serialization :caption: Custom Types Class Mapping - POCOs + POCOs Polymorphic Objects GUIDs diff --git a/source/serialization/poco.txt b/source/serialization/poco.txt index 4afda549..11fdd63d 100644 --- a/source/serialization/poco.txt +++ b/source/serialization/poco.txt @@ -674,7 +674,7 @@ serialization-related attributes: - ``[BsonDateTimeOptions(DateOnly = true)]``, which specifies that the ``DateTime`` property represents only a date value, with no associated time -.. literalinclude:: ../../includes/fundamentals/code-examples/Clothing.cs +.. literalinclude:: /includes/fundamentals/code-examples/Clothing.cs :start-after: start-model :end-before: end-model :language: csharp From 87b56427b6e3dfa223e5d3d57ada17a694f6805c Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Tue, 1 Jul 2025 14:52:41 -0500 Subject: [PATCH 30/35] DOCSP-45382 - Specify Documents (#622) --- config/redirects | 3 +- source/crud/query.txt | 2 +- ...ts-to-return.txt => specify-documents.txt} | 28 ++----------------- 3 files changed, 6 insertions(+), 27 deletions(-) rename source/crud/query/{specify-documents-to-return.txt => specify-documents.txt} (89%) diff --git a/config/redirects b/config/redirects index 1e61969b..372a6b3e 100644 --- a/config/redirects +++ b/config/redirects @@ -94,4 +94,5 @@ raw: ${prefix}/master -> ${base}/upcoming/ [*-master]: ${prefix}/${version}/fundamentals/authentication/oidc/ -> ${base}/${version}/security/authentication/oidc/ [*-master]: ${prefix}/${version}/fundamentals/authentication/scram/ -> ${base}/${version}/security/authentication/scram/ [*-master]: ${prefix}/${version}/fundamentals/authentication/x509/ -> ${base}/${version}/security/authentication/x509/ -[*-master]: ${prefix}/${version}/crud/query/specify-query/ -> ${base}/${version}/crud/query/query-filter/ \ No newline at end of file +[*-master]: ${prefix}/${version}/crud/query/specify-documents-to-return/ -> ${base}/${version}/crud/query/specify-documents/ +[*-master]: ${prefix}/${version}/crud/query/specify-query/ -> ${base}/${version}/crud/query/query-filter/ diff --git a/source/crud/query.txt b/source/crud/query.txt index e5f07bf7..a5f9c99f 100644 --- a/source/crud/query.txt +++ b/source/crud/query.txt @@ -14,7 +14,7 @@ Read Operations Specify a Query Find Documents - Specify Documents to Return + Specify Documents to Return Specify Fields to Return Count Documents Distinct Field Values diff --git a/source/crud/query/specify-documents-to-return.txt b/source/crud/query/specify-documents.txt similarity index 89% rename from source/crud/query/specify-documents-to-return.txt rename to source/crud/query/specify-documents.txt index 54a3b1c7..6c6a8412 100644 --- a/source/crud/query/specify-documents-to-return.txt +++ b/source/crud/query/specify-documents.txt @@ -13,7 +13,7 @@ Specify Documents to Return .. facet:: :name: genre :values: reference - + .. meta:: :keywords: read, paginate, pagination, order, code example @@ -181,7 +181,7 @@ skipping the first ``10`` documents: .. output:: :visible: false - + Acqua Acqua Restaurant Acqua Santa @@ -217,26 +217,4 @@ guide, see the following API documentation: - `IFindFluent <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IFindFluent-2.html>`_ - `Limit() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IFindFluent-2.Limit.html>`_ - `Sort() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IFindFluent-2.Sort.html>`_ -- `Skip() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IFindFluent-2.Skip.html>`_ - -.. TODO: integrate into existing page - -Sample Class ------------- - -The code examples in this guide demonstrate how you can use builders to -create types to interact with documents in the sample collection ``plants.flowers``. -Documents in this collection are modeled by the following ``Flower`` class: - -.. literalinclude:: /includes/fundamentals/code-examples/builders.cs - :language: csharp - :dedent: - :start-after: start-model - :end-before: end-model - -Each builder class takes a generic type parameter -``TDocument`` which represents the type of document that you are working -with. In this guide, the ``Flower`` class is the document type used in -each builder class example. - -- `SortDefinitionBuilder <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.SortDefinitionBuilder-1.html>`__ \ No newline at end of file +- `Skip() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IFindFluent-2.Skip.html>`_ \ No newline at end of file From f38793623775b3ad42872e6da65d2e6359c6afeb Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Mon, 7 Jul 2025 15:50:59 -0500 Subject: [PATCH 31/35] DOCSP-49647 - Clean up (#653) --- source/connect/connection-options/csot.txt | 0 source/crud/update-many.txt | 50 +--------------------- source/crud/update-one.txt | 50 +--------------------- source/serialization.txt | 2 - 4 files changed, 2 insertions(+), 100 deletions(-) delete mode 100644 source/connect/connection-options/csot.txt diff --git a/source/connect/connection-options/csot.txt b/source/connect/connection-options/csot.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/source/crud/update-many.txt b/source/crud/update-many.txt index d4db84ef..84d8a2f7 100644 --- a/source/crud/update-many.txt +++ b/source/crud/update-many.txt @@ -124,52 +124,4 @@ Update Many :copyable: true :dedent: :start-after: // start-pipeline-async - :end-before: // end-pipeline-async - -.. TODO: integrate into existing page - -Sample Class ------------- - -The code examples in this guide demonstrate how you can use builders to -create types to interact with documents in the sample collection ``plants.flowers``. -Documents in this collection are modeled by the following ``Flower`` class: - -.. literalinclude:: /includes/fundamentals/code-examples/builders.cs - :language: csharp - :dedent: - :start-after: start-model - :end-before: end-model - -Each builder class takes a generic type parameter -``TDocument`` which represents the type of document that you are working -with. In this guide, the ``Flower`` class is the document type used in -each builder class example. - -Define an Update ----------------- - -The ``UpdateDefinitionBuilder`` class provides a type-safe interface for -building up an update specification. Suppose you want to create an -update specification with the following criteria: - -- Create the new field ``SunRequirement`` -- Multiply the ``Price`` field value by 0.9 - -Use builders to create the update specification with the typed variant: - -.. code-block:: csharp - :copyable: true - - var builder = Builders.Update; - var update = builder.Set(f => f.SunRequirement, "Full sun").Mul(f => f.Price, 0.9); - -Alternatively, you can use string-based field names to define the update: - -.. code-block:: csharp - :copyable: true - - var builder = Builders.Update; - var update = builder.Set("SunRequirement", "Full sun").Mul("Price", 0.9); - -- `UpdateDefinitionBuilder <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateDefinitionBuilder-1.html>`__ \ No newline at end of file + :end-before: // end-pipeline-async \ No newline at end of file diff --git a/source/crud/update-one.txt b/source/crud/update-one.txt index 5bdd1db7..0359fbf9 100644 --- a/source/crud/update-one.txt +++ b/source/crud/update-one.txt @@ -112,52 +112,4 @@ Update One :copyable: true :dedent: :start-after: // start-pipeline-async - :end-before: // end-pipeline-async - -.. TODO: integrate into existing page - -Sample Class ------------- - -The code examples in this guide demonstrate how you can use builders to -create types to interact with documents in the sample collection ``plants.flowers``. -Documents in this collection are modeled by the following ``Flower`` class: - -.. literalinclude:: /includes/fundamentals/code-examples/builders.cs - :language: csharp - :dedent: - :start-after: start-model - :end-before: end-model - -Each builder class takes a generic type parameter -``TDocument`` which represents the type of document that you are working -with. In this guide, the ``Flower`` class is the document type used in -each builder class example. - -Define an Update ----------------- - -The ``UpdateDefinitionBuilder`` class provides a type-safe interface for -building up an update specification. Suppose you want to create an -update specification with the following criteria: - -- Create the new field ``SunRequirement`` -- Multiply the ``Price`` field value by 0.9 - -Use builders to create the update specification with the typed variant: - -.. code-block:: csharp - :copyable: true - - var builder = Builders.Update; - var update = builder.Set(f => f.SunRequirement, "Full sun").Mul(f => f.Price, 0.9); - -Alternatively, you can use string-based field names to define the update: - -.. code-block:: csharp - :copyable: true - - var builder = Builders.Update; - var update = builder.Set("SunRequirement", "Full sun").Mul("Price", 0.9); - -- `UpdateDefinitionBuilder <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.UpdateDefinitionBuilder-1.html>`__ \ No newline at end of file + :end-before: // end-pipeline-async \ No newline at end of file diff --git a/source/serialization.txt b/source/serialization.txt index a20bd58e..fd1bc74a 100644 --- a/source/serialization.txt +++ b/source/serialization.txt @@ -48,8 +48,6 @@ primitive types, collection types, and custom classes. For a full list of available serializers, see the `Serializers namespace API documentation <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.Serialization.Serializers.html>`__. -.. TODO: Revisit this page - .. _csharp-faq-object-serializer: ObjectSerializer From c7efc91dbbada96f6a4a814f4e683320c726a969 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Tue, 8 Jul 2025 10:19:34 -0500 Subject: [PATCH 32/35] fix broken links --- snooty.toml | 1 + source/connect/connection-options.txt | 1 - source/crud.txt | 2 +- source/crud/bulk-write.txt | 7 +++++++ source/crud/restful-api-tutorial.txt | 2 +- source/indexes.txt | 6 ++++++ source/reference/release-notes.txt | 3 +-- 7 files changed, 17 insertions(+), 5 deletions(-) diff --git a/snooty.toml b/snooty.toml index f1dc46ad..f847b8c6 100644 --- a/snooty.toml +++ b/snooty.toml @@ -5,6 +5,7 @@ toc_landing_pages = [ "/aggregation", "/aggregation/stages", "/serialization", + "/indexes", ] name = "csharp" title = "C#/.NET Driver" diff --git a/source/connect/connection-options.txt b/source/connect/connection-options.txt index 08ea8962..2eedf30e 100644 --- a/source/connect/connection-options.txt +++ b/source/connect/connection-options.txt @@ -24,7 +24,6 @@ Specify Connection Options Compress Network Traffic Customize Server Selection Stable API - Limit Server Execution Time Connection Pools Connect from AWS Lambda diff --git a/source/crud.txt b/source/crud.txt index da3a490a..6dfe9f55 100644 --- a/source/crud.txt +++ b/source/crud.txt @@ -22,4 +22,4 @@ CRUD Operations Store Large Files Configure CRUD Operations Geospatial Queries - Tutorial: Create a RESTful API + Tutorial: Create a RESTful API \ No newline at end of file diff --git a/source/crud/bulk-write.txt b/source/crud/bulk-write.txt index 7ccc5e4c..ff3fc766 100644 --- a/source/crud/bulk-write.txt +++ b/source/crud/bulk-write.txt @@ -908,6 +908,13 @@ A ``ClientBulkWriteException`` object contains the following properties: | | **Data Type:** `Exception `__ +.. _csharp-bulk-write-collation: + +Collation +--------- + +.. include:: /includes/collation.rst + Additional Information ---------------------- diff --git a/source/crud/restful-api-tutorial.txt b/source/crud/restful-api-tutorial.txt index 33520910..a0aad48c 100644 --- a/source/crud/restful-api-tutorial.txt +++ b/source/crud/restful-api-tutorial.txt @@ -372,6 +372,6 @@ To learn more about the operations discussed in this tutorial, see the following guides: - :ref:`csharp-insert-guide` -- :ref:`csharp-retrieve` +- :ref:`csharp-find` - :ref:`csharp-update-one` - :ref:`csharp-delete-guide` diff --git a/source/indexes.txt b/source/indexes.txt index 122cbfea..07f4420a 100644 --- a/source/indexes.txt +++ b/source/indexes.txt @@ -18,6 +18,12 @@ Create and Manage Indexes :depth: 2 :class: singlecol +.. toctree:: + :titlesonly: + :maxdepth: 1 + + Atlas Vector and Vector Search Indexes + Overview -------- diff --git a/source/reference/release-notes.txt b/source/reference/release-notes.txt index bbd96da2..c8e42642 100644 --- a/source/reference/release-notes.txt +++ b/source/reference/release-notes.txt @@ -133,8 +133,7 @@ The 3.3 driver release includes the following new features: - Adds support for :manual:`$elemMatch ` queries directly against values by providing an overload of the ``ElemMatch()`` method that takes only a filter parameter. To learn - more, see the :ref:`csharp-builders-array-operators` section of the - Builders guide. + more, see :ref:`csharp-update-one-arrays` and :ref:`csharp-update-many-arrays`. - Adds support for using the ``OfType()`` method and ``is`` operator to check the type of a scalar discriminator. From 25814a278dd7189957c07343074b176919ce6f94 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Tue, 8 Jul 2025 10:30:53 -0500 Subject: [PATCH 33/35] autobuilder From 1c42449ce69cd01971a25c18062540dc9ba95e5f Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Tue, 8 Jul 2025 11:37:14 -0500 Subject: [PATCH 34/35] remove dupe constant --- snooty.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/snooty.toml b/snooty.toml index f847b8c6..dd4bad46 100644 --- a/snooty.toml +++ b/snooty.toml @@ -45,6 +45,5 @@ int-data-type = "``integer``" not-available = "N/A" analyzer = "MongoDB C# Analyzer" analyzer-short = "C# Analyzer" -analyzer-short = "C# Analyzer" query-api = "MongoDB Query API" avs = "Atlas Vector Search" From cc255d49a41145c08de4388284bdbfd208ccdc35 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Tue, 8 Jul 2025 11:37:15 -0500 Subject: [PATCH 35/35] autobuilder