Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use filter statement to retrieve documents in MongoDB in .NET Core

2025-02-22 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/02 Report--

It is believed that many inexperienced people are at a loss about how to use filter statement to retrieve documents in .NET Core. Therefore, this paper summarizes the causes and solutions of the problem. Through this article, I hope you can solve this problem.

Any document belongs to a collection, so all CRUD operations are done within the scope of a single collection. To retrieve documents from a collection, you can use methods such as Find, FindSync, and FindAsync.

FindSync&FindAsync

Both FindSync and FindAsync have two overloads with three parameters. FindSync is similar to FindAsync, except that FindSync is synchronized and blocks until its call is complete. FindSync returns IAsyncCursor, while FindAsync returns a task of IAsyncCursor.

What is IAsyncCursor?

MongoDB returns query results in batches, and the batch size does not exceed the maximum size of the BSON document. Starting with version 3.2, the maximum size of an BSON document is 16 MB. The maximum document size helps ensure that a single document does not use too much RAM or bandwidth during transmission. This constraint also applies when adding documents to the collection, but MongoDB has made GridFS API a requirement in order to store larger documents. For most queries, the first batch will return 101 documents or just more than 1MB, and the subsequent batch will be 4MB. We can override the default batch size in the driver by setting the BatchSize property of FindOptions, which is passed to any find method as the second parameter. So basically, cursors are pointers to the query result set.

By default, the server automatically closes the cursor after 10 minutes of inactivity or after the client runs out of cursors. To override this behavior, you can specify that the value of the NoCursorTimeout property of the FindOptions class used in the query is set to false. However, if you do this, you should manually close the cursor or exhaust the cursor.

The IAsyncCursor in the driver represents an asynchronous cursor. To access the document, we need to manually iterate through the cursor.

Retrieve files

Let's build our first Read query, which returns all the data in books in our database. Update the MainAsync method as follows:

Static async Task Main (string [] args)

{

Await TestFindAsync ()

Console.ReadLine ()

}

Static async Task TestFindAsync ()

{

Var connectionString = "mongodb://localhost:27017"

Var client = new MongoClient (connectionString)

Var database = client.GetDatabase ("bookstore")

Var collection = database.GetCollection ("books")

Using IAsyncCursor cursor = await collection.FindAsync (new BsonDocument ())

While (await cursor.MoveNextAsync ())

{

IEnumerable batch = cursor.Current

Foreach (BsonDocument document in batch)

{

Console.WriteLine (document)

Console.WriteLine ()

}

}

}

The first overload of any find method takes three parameters: FilterDefinition (the filter used to define the query), an optional FindOptions (used to specify options for the query (such as cursor timeout, batch size, and so on), and an optional cancellationToken.

In the above code, we specify an empty filter definition by passing an empty BsonDocument to the method. Another way to write is to use FilterDefinition.Empty to represent an empty filter. With an empty filter, we basically tell it to return all the documents in our collection. Then we iterate through the cursors to get the documents in batches (MoveNextAsync in the while loop), call cursor.Current to get the documents in the current batch, and then print them out.

Running the above code should provide us with all the documents already in the collection

{"_ id": ObjectId ("5f33630f9e7b20e7e29208f3"), "bookname": ".net core3.1 with mongodb", "description": "this is a tutorial on developing with mongodb in .net core3.1", "tags": [".net core", "mongodb"], "remark": "C # is the best language in the world", "publishyear": 2020}

{"_ id": ObjectId ("5f3367482d2d59d358e1219b"), "bookname": ".net core3.1 with mongodb1", "description": "this is a tutorial on developing with mongodb in .net core3.1 1", "tags": [".net core", "mongodb"], "remark": "C # is the best language in the world", "publishyear": 2020}

{"_ id": ObjectId ("5f3367482d2d59d358e1219c"), "bookname": ".net core3.1 with mongodb2", "description": "this is a tutorial on developing with mongodb in .net core3.1 2", "tags": [".net core", "mongodb"], "remark": "C # is the best language in the world", "publishyear": 2020}

{"_ id": ObjectId ("5f3367482d2d59d358e1219d"), "bookname": ".net core3.1 with mongodb2", "description": "this is a tutorial on developing with mongodb in .net core3.1 2", "tags": [".net core", "mongodb"], "remark": "C # is the best language in the world", "publishyear": 2020}

{"_ id": ObjectId ("5f33850d467bf3877966f1ea"), "BookName": ".net core3.1 with mongodb21", "Description": "this is a tutorial on developing with mongodb in .net core3.1 21", "Tags": [".net core", "mongodb"], "Remark": "C # is the best language in the world", "PublishYear": 2020}

{"_ id": ObjectId ("5f33850d467bf3877966f1eb"), "BookName": ".net core3.1 with mongodb22", "Description": "this is a tutorial on developing with mongodb in .net core3.1 22", "Tags": [".net core", "mongodb"], "Remark": "C # is the best language in the world", "PublishYear": 2020}

{"_ id": ObjectId ("5f33850d467bf3877966f1ec"), "BookName": ".net core3.1 with mongodb23", "Description": "this is a tutorial on developing with mongodb in .net core3.1 23", "Tags": [".net core", "mongodb"], "Remark": "C # is the best language in the world", "PublishYear": 2020}

We can see that the returned data is basically the same as the document we added in the previous article, except for an extra _ id attribute, all collections have a unique primary index on this field, and if you do not provide a primary index when you create the document, MongoDB will provide a primary index by default. Its type is ObjectId, which is defined in the Bson specification.

To demonstrate FindOptions, I'll add an option to limit the batch size to 2, which will display the batches we looped through the console. Update the code with the following

Static async Task Main (string [] args)

{

Await TestFindAsync ()

Console.ReadLine ()

}

Static async Task TestFindAsync ()

{

Var connectionString = "mongodb://localhost:27017"

Var client = new MongoClient (connectionString)

Var database = client.GetDatabase ("bookstore")

Var collection = database.GetCollection ("books")

FilterDefinition filter = FilterDefinition.Empty

FindOptions options = new FindOptions {

BatchSize = 2

NoCursorTimeout = false

}

Using IAsyncCursor cursor = await collection.FindAsync (filter,options)

Var batch = 0

While (await cursor.MoveNextAsync ())

{

Batch++

Console.WriteLine ($"Batch: {batch}")

IEnumerable documents = cursor.Current

Foreach (BsonDocument document in documents)

{

Console.WriteLine (document)

Console.WriteLine ()

}

}

Console.WriteLine ($"Total Batch: {batch}")

}

And run it to get the following results:

Batch: 1

{"_ id": ObjectId ("5f33630f9e7b20e7e29208f3"), "bookname": ".net core3.1 with mongodb", "description": "this is a tutorial on developing with mongodb in .net core3.1", "tags": [".net core", "mongodb"], "remark": "C # is the best language in the world", "publishyear": 2020}

{"_ id": ObjectId ("5f3367482d2d59d358e1219b"), "bookname": ".net core3.1 with mongodb1", "description": "this is a tutorial on developing with mongodb in .net core3.1 1", "tags": [".net core", "mongodb"], "remark": "C # is the best language in the world", "publishyear": 2020}

Batch: 2

{"_ id": ObjectId ("5f3367482d2d59d358e1219c"), "bookname": ".net core3.1 with mongodb2", "description": "this is a tutorial on developing with mongodb in .net core3.1 2", "tags": [".net core", "mongodb"], "remark": "C # is the best language in the world", "publishyear": 2020}

{"_ id": ObjectId ("5f3367482d2d59d358e1219d"), "bookname": ".net core3.1 with mongodb2", "description": "this is a tutorial on developing with mongodb in .net core3.1 2", "tags": [".net core", "mongodb"], "remark": "C # is the best language in the world", "publishyear": 2020}

Batch: 3

{"_ id": ObjectId ("5f33850d467bf3877966f1ea"), "BookName": ".net core3.1 with mongodb21", "Description": "this is a tutorial on developing with mongodb in .net core3.1 21", "Tags": [".net core", "mongodb"], "Remark": "C # is the best language in the world", "PublishYear": 2020}

{"_ id": ObjectId ("5f33850d467bf3877966f1eb"), "BookName": ".net core3.1 with mongodb22", "Description": "this is a tutorial on developing with mongodb in .net core3.1 22", "Tags": [".net core", "mongodb"], "Remark": "C # is the best language in the world", "PublishYear": 2020}

Batch: 4

{"_ id": ObjectId ("5f33850d467bf3877966f1ec"), "BookName": ".net core3.1 with mongodb23", "Description": "this is a tutorial on developing with mongodb in .net core3.1 23", "Tags": [".net core", "mongodb"], "Remark": "C # is the best language in the world", "PublishYear": 2020}

Total Batch: 4

We can also write this code in a more concise way by calling ToListAsync or ForEachAsync to get all the documents from the cursor and put them in memory. There are extension methods on IAsyncCursor to do this. Here is some code:

Collection.FindSync (filter) .ToList ()

Await collection.FindSync (filter) .ToListAsync ()

Await collection.FindSync (filter) .ForEachAsync (doc = > Console.WriteLine ())

Collection.FindSync (filter) .FirstOrDefault ()

Collection.FindSync (filter) .FirstOrDefault ()

Await collection.FindSync (filter) .FirstOrDefaultAsync ()

From a code point of view, this looks concise and short, but what it does is force all documents to be kept in memory. In some cases, this may not be ideal, and cursors are useful when the query results are large, and we can move the cursor by calling MoveNextAsync or MoveNext.

Find

This method is similar to its counterpart, but it returns the IFindFluent interface. This is a smooth interface that provides us with some simple syntax: Count,Skip, Sort, and Limit (more on this in the next article). We can also return a cursor from IFindFluent (by calling ToCursor or ToCursorAsync or a list (by calling ToList or ToListAsync). With the following code, we can use the Find method to get all the documents and print them to the console

Await collection.Find (FilterDefinition.Empty)

.ForEachAsync (doc = > Console.WriteLine (doc))

Result

{"_ id": ObjectId ("5f33630f9e7b20e7e29208f3"), "bookname": ".net core3.1 with mongodb", "description": "this is a tutorial on developing with mongodb in .net core3.1", "tags": [".net core", "mongodb"], "remark": "C # is the best language in the world", "publishyear": 2020}

{"_ id": ObjectId ("5f3367482d2d59d358e1219b"), "bookname": ".net core3.1 with mongodb1", "description": "this is a tutorial on developing with mongodb in .net core3.1 1", "tags": [".net core", "mongodb"], "remark": "C # is the best language in the world", "publishyear": 2020}

{"_ id": ObjectId ("5f3367482d2d59d358e1219c"), "bookname": ".net core3.1 with mongodb2", "description": "this is a tutorial on developing with mongodb in .net core3.1 2", "tags": [".net core", "mongodb"], "remark": "C # is the best language in the world", "publishyear": 2020}

{"_ id": ObjectId ("5f3367482d2d59d358e1219d"), "bookname": ".net core3.1 with mongodb2", "description": "this is a tutorial on developing with mongodb in .net core3.1 2", "tags": [".net core", "mongodb"], "remark": "C # is the best language in the world", "publishyear": 2020}

{"_ id": ObjectId ("5f33850d467bf3877966f1ea"), "BookName": ".net core3.1 with mongodb21", "Description": "this is a tutorial on developing with mongodb in .net core3.1 21", "Tags": [".net core", "mongodb"], "Remark": "C # is the best language in the world", "PublishYear": 2020}

{"_ id": ObjectId ("5f33850d467bf3877966f1eb"), "BookName": ".net core3.1 with mongodb22", "Description": "this is a tutorial on developing with mongodb in .net core3.1 22", "Tags": [".net core", "mongodb"], "Remark": "C # is the best language in the world", "PublishYear": 2020}

{"_ id": ObjectId ("5f33850d467bf3877966f1ec"), "BookName": ".net core3.1 with mongodb23", "Description": "this is a tutorial on developing with mongodb in .net core3.1 23", "Tags": [".net core", "mongodb"], "Remark": "C # is the best language in the world", "PublishYear": 2020}

Find a specific file

In most cases, instead of retrieving all documents, we specify a filter that returns documents that match a particular filter. Now let's look at the way to specify a filter for the query.

Use BsonDocument or String

We can define BsonDocument as a filter, and the query will find a document that matches the fields defined in the document. Add the following code to your method and run it to retrieve the book description called "this is a tutorial on developing with mongodb in. Net core3.1"

Var filter = new BsonDocument ("description", "this is a tutorial on developing with mongodb in. Net core3.1")

Await collection.Find (filter) .ForEachAsync (doc = > Console.WriteLine (doc))

This returns only one document that meets the criteria

Var filter = new BsonDocument ("description", "this is a tutorial on developing with mongodb in. Net core3.1")

Await collection.Find (filter) .ForEachAsync (doc = > Console.WriteLine (doc))

You might be a little confused because these methods accept FilterDefinition, but we gave it a BsonDocument, and there was nothing wrong with it. This happens because it is implicitly converted, and we can also convert it through strings. To use a string, we need to define a valid JSON string to specify the filter. We can do the same with the string using the following code, and still get the same result:

Var filter= "{description:' this is a tutorial on developing with mongodb in. Net core3.1 1'}"

Await collection.Find (filter) .ForEachAsync (doc = > Console.WriteLine (doc))

We can also specify comparison or logical operators. For example, look for books published in 2020. We can build the query as follows:

Var filter = new BsonDocument ("publishyear", new BsonDocument ("$eq", 2020))

Or use a string

Var filter = "{Age: {'$eq': 23}}"

What we do is add an identifier to the operator, which in our case is $eq.

Use FilterDefinitionBuilder

You can use FilterDefinitionBuilder, which is the builder of FilterDefinition. It provides a set of methods to build queries, and Lt, as one of them, specifies a less than comparison. Therefore, we can use FilterDefinitionBuilder to define the filter, as follows:

Var filter = new FilterDefinitionBuilder () .Lt ("publishyear", 2020)

Or use an overloaded method that accepts LINQ expressions:

Var filter = new FilterDefinitionBuilder () .Lt (book = > book.PublishYear, 2020)

In addition, you can use the static Builders class to build filter definitions, which also have static helper methods for building other content, such as projection definitions, sorting definitions, and other methods.

Var filter = Builders.Filter.Lt ("publishyear", 2020)

Var filter = Builders.Filter.Lt (book = > book.PublishYear, 2020)

The driver also overloads three operators for the filter definition. This and (&), or (|) and not (!) Operation. For example, if we want to get the year of publication 2020 and describe it as a book about developing tutorial 1 with mongodb in. Net core3.1, we can use the builder help method and the & overload operator as follows

Var builder = Builders.Filter

Var filter = builder.Eq ("publishyear", 2020) & builder.Eq ("description", "`This is a tutorial on developing with mongodb in. Net core3.1 1")

Linq expression

What we didn't discuss in the last part is the overloading of these methods, which take LINQ expressions, and when we have a strongly typed object, we can use LINQ expressions to build a filter query. Suppose we want the publication year to be 2020 and the description information is that this is a book about developing tutorial 1 using mongodb in. Net core3.1 to print them. We use the following code:

Var collection = database.GetCollection ("books")

Await collection.Find (book = > book.PublishYear = = 2020 & & book.Description = = "this is a tutorial on developing with mongodb in .net core3.1 1") .ForEachAsync (doc = > Console.WriteLine (doc))

We change the collection type to Book and run the following code, and we get an error on the console:

The error description shows that _ id does not match any type of field or property. This is because the Book object cannot map any properties of the _ id field from the database to the student type. This is added automatically when we create the document. Let's add the ID property of type Bson to the Book class.

Internal class Book

{

Public ObjectId Id {get; set;}

Public string BookName {get; set;}

Public string Description {get; set;}

Public IEnumerable Tags {get; set;}

Public string Remark {get; set;}

Public int PublishYear {get; set;}

}

And run it and found it to be normal. Of course, you can also avoid this problem by setting IgnoreExtraElement to true.

It just worked. So most of the time, you will want to use expression tree syntax to build your query. Other methods can be used in cases where more granularity is needed.

After reading the above, have you learned how to retrieve documents using filter statements in MongoDB in .NET Core? If you want to learn more skills or want to know more about it, you are welcome to follow the industry information channel, thank you for reading!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report