-
Notifications
You must be signed in to change notification settings - Fork 26
DOCSP-45007: Distinct #292
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 2 commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,251 @@ | ||
| .. _csharp-distinct: | ||
|
|
||
| ============================== | ||
| Retrieve Distinct Field Values | ||
| ============================== | ||
|
|
||
| .. contents:: On this page | ||
| :local: | ||
| :backlinks: none | ||
| :depth: 2 | ||
| :class: singlecol | ||
|
|
||
| .. facet:: | ||
| :name: genre | ||
| :values: reference | ||
|
|
||
| .. meta:: | ||
| :keywords: read, unique, code example | ||
|
|
||
| Overview | ||
| -------- | ||
|
|
||
| In this guide, you can learn how to use the {+driver-short+} to retrieve the | ||
| distinct values of a specified field across a collection. | ||
|
|
||
| Within a collection, different documents might contain different values for a | ||
| single field. For example, one document in a ``restaurants`` collection has a | ||
| ``borough`` value of ``"Manhattan"``, and another has a ``borough`` value of | ||
| ``"Queens"``. By using the {+driver-short+}, you can retrieve all the unique values | ||
| that a field contains across multiple documents in a collection. | ||
|
|
||
| Sample Data | ||
| ~~~~~~~~~~~ | ||
|
|
||
| The examples in this guide use the ``sample_restaurants.restaurants`` collection | ||
| from the :atlas:`Atlas sample datasets </sample-data>`. To learn how to create a | ||
| free MongoDB Atlas cluster and load the sample datasets, see the :ref:`<csharp-quickstart>`. | ||
|
|
||
| Retrieve Distinct Values | ||
| ------------------------ | ||
|
|
||
| To retrieve the distinct values for a specified field, call the ``Distinct()`` or | ||
| ``DistinctAsync()`` method of an ``IMongoCollection<TDocument>`` instance and pass the name | ||
| of the field you want to find distinct values for. | ||
|
|
||
| Retrieve Values Across a Collection | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| The following example retrieves the distinct values of the ``borough`` field in | ||
| the ``restaurants`` collection. Select the :guilabel:`Asynchronous` or :guilabel:`Synchronous` | ||
| tab to see the corresponding code. | ||
|
|
||
| .. tabs:: | ||
|
|
||
| .. tab:: Asynchronous | ||
| :tabid: distinct-async | ||
|
|
||
| .. io-code-block:: | ||
| :copyable: | ||
|
|
||
| .. input:: /includes/fundamentals/code-examples/Distinct.cs | ||
| :start-after: start-distinct-async | ||
| :end-before: end-distinct-async | ||
| :language: csharp | ||
| :dedent: | ||
|
|
||
| .. output:: | ||
| :visible: false | ||
|
|
||
| Bronx | ||
| Brooklyn | ||
| Manhattan | ||
| Missing | ||
| Queens | ||
| Staten Island | ||
|
|
||
| .. tab:: Synchronous | ||
| :tabid: distinct-sync | ||
|
|
||
| .. io-code-block:: | ||
| :copyable: | ||
|
|
||
| .. input:: /includes/fundamentals/code-examples/Distinct.cs | ||
| :start-after: start-distinct | ||
| :end-before: end-distinct | ||
| :language: csharp | ||
| :dedent: | ||
|
|
||
| .. output:: | ||
| :visible: false | ||
|
|
||
| Bronx | ||
| Brooklyn | ||
| Manhattan | ||
| Missing | ||
| Queens | ||
| Staten Island | ||
|
|
||
| The operation returns a cursor that you can iterate through to access each distinct ``borough`` | ||
| field value. Although several documents have the same value in the ``borough`` field, each value appears | ||
| in the results only once. | ||
|
|
||
| Retrieve Values Across Specified Documents | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| You can provide a **query filter** to the ``Distinct()`` and ``DistinctAsync()`` methods | ||
| to find distinct field values within a subset of documents in a collection. A query filter | ||
| is an expression that specifies search criteria used to match documents in an operation. | ||
| For more information about creating a query filter, see the :ref:`csharp-specify-query` guide. | ||
|
|
||
| The following example retrieves the distinct values of the ``borough`` field for | ||
| all documents that have a ``cuisine`` field value of ``"Italian"``. Select the | ||
| :guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the corresponding code. | ||
|
|
||
| .. tabs:: | ||
|
|
||
| .. tab:: Asynchronous | ||
| :tabid: distinct-async | ||
|
|
||
| .. io-code-block:: | ||
| :copyable: | ||
|
|
||
| .. input:: /includes/fundamentals/code-examples/Distinct.cs | ||
| :start-after: start-distinct-with-query-async | ||
| :end-before: end-distinct-with-query-async | ||
| :language: csharp | ||
| :dedent: | ||
|
|
||
| .. output:: | ||
| :visible: false | ||
|
|
||
| Bronx | ||
| Brooklyn | ||
| Manhattan | ||
| Queens | ||
| Staten Island | ||
|
|
||
| .. tab:: Synchronous | ||
| :tabid: distinct-sync | ||
|
|
||
| .. io-code-block:: | ||
| :copyable: | ||
|
|
||
| .. input:: /includes/fundamentals/code-examples/Distinct.cs | ||
| :start-after: start-distinct-with-query | ||
| :end-before: end-distinct-with-query | ||
| :language: csharp | ||
| :dedent: | ||
|
|
||
| .. output:: | ||
| :visible: false | ||
|
|
||
| Bronx | ||
| Brooklyn | ||
| Manhattan | ||
| Queens | ||
| Staten Island | ||
|
|
||
| Modify Distinct Behavior | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| You can modify the behavior of the ``Distinct()`` and ``DistinctAsync()`` methods by | ||
| providing a ``DistinctOptions`` instance as an optional parameter. The following table | ||
| describes the properties you can set on a ``DistinctOptions`` instance: | ||
|
|
||
| .. list-table:: | ||
| :widths: 30 70 | ||
| :header-rows: 1 | ||
|
|
||
| * - Method | ||
| - Description | ||
|
|
||
| * - ``Collation`` | ||
| - | Sets the collation to use for the operation. | ||
| | **Data type**: `Collation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.DistinctOptions.Collation.html>`__ | ||
|
|
||
| * - ``MaxTime`` | ||
| - | Sets the maximum amount of time that the operation can run. | ||
| | **Data type**: ``TimeSpan`` | ||
|
|
||
| * - ``Comment`` | ||
| - | Attaches a comment to the operation. | ||
| | **Data type**: `BsonValue <{+new-api-root+}/MongoDB.Bson/MongoDB.Bson.BsonValue.html>`__ or ``string`` | ||
|
|
||
| The following example retrieves the distinct values of the ``name`` field for | ||
| all documents that have a ``borough`` field value of ``"Bronx"`` and a | ||
| ``cuisine`` field value of ``"Pizza"``. Then, it adds a comment to the operation by | ||
| providing a ``DistinctOptions`` instance to the ``Distinct()`` method. | ||
|
|
||
| Select the :guilabel:`Asynchronous` or :guilabel:`Synchronous` tab to see the | ||
| corresponding code. | ||
|
|
||
| .. tabs:: | ||
|
|
||
| .. tab:: Asynchronous | ||
| :tabid: distinct-async | ||
|
|
||
| .. io-code-block:: | ||
| :copyable: | ||
|
|
||
| .. input:: /includes/fundamentals/code-examples/Distinct.cs | ||
| :start-after: start-distinct-with-comment-async | ||
| :end-before: end-distinct-with-comment-async | ||
| :language: csharp | ||
| :dedent: | ||
|
|
||
| .. output:: | ||
| :visible: false | ||
|
|
||
| $1.25 Pizza | ||
| 18 East Gunhill Pizza | ||
| 2 Bros | ||
| Aenos Pizza | ||
| Alitalia Pizza Restaurant | ||
| Amici Pizza And Pasta | ||
| Angie'S Cafe Pizza | ||
| ... | ||
|
|
||
| .. tab:: Synchronous | ||
| :tabid: distinct-sync | ||
|
|
||
| .. io-code-block:: | ||
| :copyable: | ||
|
|
||
| .. input:: /includes/fundamentals/code-examples/Distinct.cs | ||
| :start-after: start-distinct-with-comment | ||
| :end-before: end-distinct-with-comment | ||
| :language: csharp | ||
| :dedent: | ||
|
|
||
| .. output:: | ||
| :visible: false | ||
|
|
||
| $1.25 Pizza | ||
| 18 East Gunhill Pizza | ||
| 2 Bros | ||
| Aenos Pizza | ||
| Alitalia Pizza Restaurant | ||
| Amici Pizza And Pasta | ||
| Angie'S Cafe Pizza | ||
| ... | ||
|
|
||
| API Documentation | ||
| ----------------- | ||
|
|
||
| To learn more about any of the methods or types discussed in this | ||
| guide, see the following API documentation: | ||
|
|
||
| - `Distinct() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.Distinct.html>`__ | ||
| - `DistinctAsync() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollection-1.DistinctAsync.html>`__ | ||
| - `DistinctOptions <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.DistinctOptions.html>`__ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,105 @@ | ||
| using MongoDB.Bson; | ||
| using MongoDB.Bson.Serialization.Attributes; | ||
| using MongoDB.Bson.Serialization.Conventions; | ||
| using MongoDB.Driver; | ||
|
|
||
| public class LimitSortSkip | ||
| { | ||
| // Replace with your connection string | ||
| private const string MongoConnectionString = "<connection string URI>>"; | ||
|
|
||
| public static void Main(string[] args) | ||
| { | ||
| var mongoClient = new MongoClient(MongoConnectionString); | ||
| var database = mongoClient.GetDatabase("sample_restaurants"); | ||
| var collection = database.GetCollection<Restaurant>("restaurants"); | ||
|
|
||
| { | ||
| // start-distinct | ||
| var results = collection.Distinct<string>("borough", new BsonDocument()).ToList(); | ||
| foreach (var result in results) | ||
| { | ||
| Console.WriteLine(result); | ||
| } | ||
| // end-distinct | ||
| } | ||
|
|
||
| { | ||
| // start-distinct-with-query | ||
| var filter = Builders<Restaurant>.Filter.Eq("cuisine", "Italian"); | ||
| var results = collection.Distinct<string>("borough", filter).ToList(); | ||
| foreach (var result in results) | ||
| { | ||
| Console.WriteLine(result); | ||
| } | ||
| // end-distinct-with-query | ||
| } | ||
|
|
||
| { | ||
| // start-distinct-with-comment | ||
| var cuisineFilter = Builders<Restaurant>.Filter.Eq("cuisine", "Pizza"); | ||
| var boroughFilter = Builders<Restaurant>.Filter.Eq("borough", "Bronx"); | ||
| var filter = Builders<Restaurant>.Filter.And(cuisineFilter, boroughFilter); | ||
|
|
||
| var options = new DistinctOptions { | ||
| Comment = "Find all Italian restaurants in the Bronx" | ||
| }; | ||
|
|
||
| var results = collection.Distinct<string>("name", filter).ToList(); | ||
| foreach (var result in results) | ||
| { | ||
| Console.WriteLine(result); | ||
| } | ||
| // end-distinct-with-comment | ||
| } | ||
|
|
||
| } | ||
|
|
||
| private static async void DistinctAsync (IMongoCollection<Restaurant> collection) | ||
| { | ||
| // start-distinct-async | ||
| var results = await collection.DistinctAsync<string>("borough", new BsonDocument()); | ||
| await results.ForEachAsync(result => Console.WriteLine(result)); | ||
| // end-distinct-async | ||
| } | ||
|
|
||
| private static async void DistinctWithQueryAsync (IMongoCollection<Restaurant> collection) | ||
| { | ||
| // start-distinct-with-query-async | ||
| var filter = Builders<Restaurant>.Filter.Eq("cuisine", "Italian"); | ||
| var results = await collection.DistinctAsync<string>("borough", filter); | ||
| await results.ForEachAsync(result => Console.WriteLine(result)); | ||
| // end-distinct-with-query-async | ||
| } | ||
|
|
||
| private static async void DistinctWithCommentAsync (IMongoCollection<Restaurant> collection) | ||
| { | ||
| // start-distinct-with-comment-async | ||
| var cuisineFilter = Builders<Restaurant>.Filter.Eq("cuisine", "Pizza"); | ||
| var boroughFilter = Builders<Restaurant>.Filter.Eq("borough", "Bronx"); | ||
| var filter = Builders<Restaurant>.Filter.And(cuisineFilter, boroughFilter); | ||
|
|
||
| var options = new DistinctOptions { | ||
| Comment = "Find all Italian restaurants in the Bronx" | ||
| }; | ||
|
|
||
| var results = await collection.DistinctAsync<string>("name", filter, options); | ||
| await results.ForEachAsync(result => Console.WriteLine(result)); | ||
| // end-distinct-with-comment-async | ||
| } | ||
| } | ||
|
|
||
| // start-restaurant-class | ||
| public class Restaurant { | ||
| public ObjectId? Id { get; set; } | ||
|
|
||
| [BsonElement("name")] | ||
| public string? Name { get; set; } | ||
|
|
||
| [BsonElement("cuisine")] | ||
| public string? Cuisine { get; set; } | ||
|
|
||
| [BsonElement("borough")] | ||
| public string? Borough { get; set; } | ||
| } | ||
| // end-restaurant-class | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not clear to the reader what
new BsonDocument()is doing here.I had to reverse engineer what it was: a
filterthat matches all documents.As alternative to
new BsonDocument()might beBuilders<Restaurant>.Filters.EmptyThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might also be worth showing the type safe version:
collection.Distinct(x => x.Borough, x => true)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made tweaks for the next version!