在.NETCore中使用MongoDB中如何使用Filter語句檢索文檔

在.NET Core中使用MongoDB中如何使用Filter語句檢索文檔,相信很多沒有經(jīng)驗(yàn)的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個(gè)問題。

成都創(chuàng)新互聯(lián)專注服務(wù)器托管服務(wù)十載,提供服務(wù)器租用、虛擬空間、申請域名、云服務(wù)器、云主機(jī)租用、成都IDC機(jī)房托管、建站等服務(wù)

任何文檔都屬于集合,因此所有CRUD操作都是在單個(gè)集合范圍中完成的。若要從集合中檢索文檔,可以使用FindFindSync,和FindAsync等方法。

 

FindSync&FindAsync

FindSyncFindAsync兩者都有兩個(gè)帶有三個(gè)參數(shù)的重載。FindSyncFindAsync很相似,只是FindSync是同步的,并阻塞直到它的調(diào)用完成。FindSync返回IAsyncCursor ,而FindAsync返回一個(gè)IAsyncCursor的任務(wù).

 

什么是IAsyncCursor

MongoDB以批形式返回查詢結(jié)果,批處理大小不會超過BSON文檔的最大大小。從版本3.2開始,BSON文檔的最大大小為16 MB。最大文檔大小有助于確保單個(gè)文檔在傳輸過程中不能使用過多的RAM或過多的帶寬。此約束在將文檔添加到集合時(shí)也適用,但是為了存儲更大的文檔,MongoDB已經(jīng)將GridFS API作為一項(xiàng)規(guī)定。對于大多數(shù)查詢,第一批將返回101個(gè)文檔或剛好超過1MB的文檔,隨后的批處理將為4MB。我們可以在驅(qū)動程序中通過設(shè)置FindOptions 的BatchSize 屬性來覆蓋默認(rèn)的批大小,該屬性作為第二個(gè)參數(shù)傳遞給任何find方法。所以基本上,游標(biāo)是指向查詢結(jié)果集的指針。

默認(rèn)情況下,服務(wù)器將在不活動10分鐘后或客戶端耗盡游標(biāo)后自動關(guān)閉游標(biāo)。若要重寫此行為,可以指定在查詢中使用FindOptions類的NoCursorTimeout屬性值設(shè)置為false。但是,如果你這樣做您應(yīng)該手動關(guān)閉游標(biāo)或耗盡游標(biāo)。

驅(qū)動程序中的這個(gè)IAsyncCursor表示異步游標(biāo)。要訪問文檔,我們需要手動迭代游標(biāo)。

 

檢索文件

讓我們構(gòu)建我們的第一個(gè)Read查詢,這個(gè)查詢返回我們數(shù)據(jù)庫中books中的所有數(shù)據(jù)。更新MainAsync方法如下:

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<BsonDocument>("books");
           using IAsyncCursor<BsonDocument> cursor = await collection.FindAsync(new BsonDocument());
           while (await cursor.MoveNextAsync())
           {
               IEnumerable<BsonDocument> batch = cursor.Current;
               foreach (BsonDocument document in batch)
               {
                   Console.WriteLine(document);
                   Console.WriteLine();
               }
           }
       }
 

任何find方法的第一個(gè)重載都有3個(gè)參數(shù):FilterDefinition (用于定義查詢的篩選器)、一個(gè)可選的FindOptions(用于指定查詢的選項(xiàng)(例如游標(biāo)超時(shí)、批處理大小等)和一個(gè)可選的cancellationToken

在上面的代碼中,我們通過向方法傳遞一個(gè)空的BsonDocument來指定一個(gè)空的過濾器定義。另一種編寫方法是使用FilterDefinition<BsonDocument>.Empty來表示一個(gè)空的過濾器。有了空過濾器,我們基本上是告訴它返回給我們集合中的所有文檔。然后,我們迭代游標(biāo)以成批獲取文檔(while循環(huán)中的MoveNextAsync),并調(diào)用cursor.Current獲取當(dāng)前批中的文檔,然后將其打印出來。

運(yùn)行上面的代碼應(yīng)該可以為我們提供該集合中已有的所有文檔

{ "_id" : ObjectId("5f33630f9e7b20e7e29208f3"), "bookname" : ".net core3.1 with mongodb", "description" : "這是一本關(guān)于 在.net core3.1中使用mongodb進(jìn)行開發(fā)的教程", "tags" : [".net core", "mongodb"], "remark" : "C#是世界上最好的語言", "publishyear" : 2020 }

{ "_id" : ObjectId("5f3367482d2d59d358e1219b"), "bookname" : ".net core3.1 with mongodb1", "description" : "這是一本關(guān)于在.net core3.1中使用mongodb進(jìn)行開發(fā)的教程1", "tags" : [".net core", "mongodb"], "remark" : "C#是世界上最好的語言", "publishyear" : 2020 }

{ "_id" : ObjectId("5f3367482d2d59d358e1219c"), "bookname" : ".net core3.1 with mongodb2", "description" : "這是一本關(guān)于在.net core3.1中使用mongodb進(jìn)行開發(fā)的教程2", "tags" : [".net core", "mongodb"], "remark" : "C#是世界上最好的語言", "publishyear" : 2020 }

{ "_id" : ObjectId("5f3367482d2d59d358e1219d"), "bookname" : ".net core3.1 with mongodb2", "description" : "這是一本關(guān)于在.net core3.1中使用mongodb進(jìn)行開發(fā)的教程2", "tags" : [".net core", "mongodb"], "remark" : "C#是世界上最好的語言", "publishyear" : 2020 }

{ "_id" : ObjectId("5f33850d467bf3877966f1ea"), "BookName" : ".net core3.1 with mongodb21", "Description" : "這是一本關(guān) 于在.net core3.1中使用mongodb進(jìn)行開發(fā)的教程21", "Tags" : [".net core", "mongodb"], "Remark" : "C#是世界上最好的語言", "PublishYear" : 2020 }

{ "_id" : ObjectId("5f33850d467bf3877966f1eb"), "BookName" : ".net core3.1 with mongodb22", "Description" : "這是一本關(guān) 于在.net core3.1中使用mongodb進(jìn)行開發(fā)的教程22", "Tags" : [".net core", "mongodb"], "Remark" : "C#是世界上最好的語言", "PublishYear" : 2020 }

{ "_id" : ObjectId("5f33850d467bf3877966f1ec"), "BookName" : ".net core3.1 with mongodb23", "Description" : "這是一本關(guān) 于在.net core3.1中使用mongodb進(jìn)行開發(fā)的教程23", "Tags" : [".net core", "mongodb"], "Remark" : "C#是世界上最好的語言", "PublishYear" : 2020 }
 

我們可以看到返回的數(shù)據(jù)跟我們在上一篇文章中添加的文檔基本一樣,除了多了一個(gè)_id屬性,所有集合在這個(gè)字段上都有一個(gè)唯一的主索引,如果您在創(chuàng)建文檔時(shí)沒有提供主索引,那么MongoDB會默認(rèn)提供一個(gè)主索引。它的類型是ObjectId,這是在Bson規(guī)范中定義。

為了演示FindOptions,我將添加一個(gè)將批大小限制為2的選項(xiàng),該選項(xiàng)將顯示我們在控制臺中循環(huán)的批。使用以下內(nèi)容更新代碼

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<BsonDocument>("books");
           FilterDefinition<BsonDocument> filter = FilterDefinition<BsonDocument>.Empty;
           FindOptions<BsonDocument> options = new FindOptions<BsonDocument> {
               BatchSize = 2,
               NoCursorTimeout = false
           };
           using IAsyncCursor<BsonDocument> cursor = await collection.FindAsync(filter,options);
           var batch = 0;
           while (await cursor.MoveNextAsync())
           {
               batch++;
               Console.WriteLine($"Batch: {batch}");
               IEnumerable<BsonDocument> documents = cursor.Current;
               foreach (BsonDocument document in documents)
               {
                   Console.WriteLine(document);
                   Console.WriteLine();
               }
           }
           Console.WriteLine($"Total Batch: { batch}");
       }
 

并運(yùn)行它以獲得以下結(jié)果:

Batch: 1
{ "_id" : ObjectId("5f33630f9e7b20e7e29208f3"), "bookname" : ".net core3.1 with mongodb", "description" : "這是一本關(guān)于 在.net core3.1中使用mongodb進(jìn)行開發(fā)的教程", "tags" : [".net core", "mongodb"], "remark" : "C#是世界上最好的語言", "publishyear" : 2020 }

{ "_id" : ObjectId("5f3367482d2d59d358e1219b"), "bookname" : ".net core3.1 with mongodb1", "description" : "這是一本關(guān)于在.net core3.1中使用mongodb進(jìn)行開發(fā)的教程1", "tags" : [".net core", "mongodb"], "remark" : "C#是世界上最好的語言", "publishyear" : 2020 }

Batch: 2
{ "_id" : ObjectId("5f3367482d2d59d358e1219c"), "bookname" : ".net core3.1 with mongodb2", "description" : "這是一本關(guān)于在.net core3.1中使用mongodb進(jìn)行開發(fā)的教程2", "tags" : [".net core", "mongodb"], "remark" : "C#是世界上最好的語言", "publishyear" : 2020 }

{ "_id" : ObjectId("5f3367482d2d59d358e1219d"), "bookname" : ".net core3.1 with mongodb2", "description" : "這是一本關(guān)于在.net core3.1中使用mongodb進(jìn)行開發(fā)的教程2", "tags" : [".net core", "mongodb"], "remark" : "C#是世界上最好的語言", "publishyear" : 2020 }

Batch: 3
{ "_id" : ObjectId("5f33850d467bf3877966f1ea"), "BookName" : ".net core3.1 with mongodb21", "Description" : "這是一本關(guān) 于在.net core3.1中使用mongodb進(jìn)行開發(fā)的教程21", "Tags" : [".net core", "mongodb"], "Remark" : "C#是世界上最好的語言", "PublishYear" : 2020 }

{ "_id" : ObjectId("5f33850d467bf3877966f1eb"), "BookName" : ".net core3.1 with mongodb22", "Description" : "這是一本關(guān) 于在.net core3.1中使用mongodb進(jìn)行開發(fā)的教程22", "Tags" : [".net core", "mongodb"], "Remark" : "C#是世界上最好的語言", "PublishYear" : 2020 }

Batch: 4
{ "_id" : ObjectId("5f33850d467bf3877966f1ec"), "BookName" : ".net core3.1 with mongodb23", "Description" : "這是一本關(guān) 于在.net core3.1中使用mongodb進(jìn)行開發(fā)的教程23", "Tags" : [".net core", "mongodb"], "Remark" : "C#是世界上最好的語言", "PublishYear" : 2020 }

Total Batch: 4
 

我們還可以通過調(diào)用ToListAsyncForEachAsync從光標(biāo)中獲取所有文檔并將它們放入內(nèi)存中,從而以更簡潔的方式編寫此代碼。在IAsyncCursor上有擴(kuò)展方法可以這么做。下面是一些代碼:

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();
 

從代碼角度看,這看起來既簡潔又簡短,但它所做的是強(qiáng)制所有文檔都保存在內(nèi)存中。在某些情況下,這可能不太理想,當(dāng)查詢結(jié)果很大時(shí),游標(biāo)很有用,我們可以通過調(diào)用MoveNextAsyncMoveNext來移動光標(biāo)。

 

Find

此方法與其對應(yīng)方法相似,但它返回IFindFluent接口。這是一個(gè)流暢的接口,它為我們提供了一些簡單的語法:Count,Skip ,Sort,和Limit(關(guān)于這些,下篇文章中會有更多的介紹)。從IFindFluent中我們也可以返回一個(gè)游標(biāo)(通過調(diào)用ToCursorToCursorAsync或一個(gè)列表(通過調(diào)用ToListToListAsync)。通過下面的代碼,我們可以使用Find方法獲取所有文檔并將它們打印到控制臺

await collection.Find(FilterDefinition<BsonDocument>.Empty)
       .ForEachAsync(doc => Console.WriteLine(doc));
 

結(jié)果

{ "_id" : ObjectId("5f33630f9e7b20e7e29208f3"), "bookname" : ".net core3.1 with mongodb", "description" : "這是一本關(guān)于 在.net core3.1中使用mongodb進(jìn)行開發(fā)的教程", "tags" : [".net core", "mongodb"], "remark" : "C#是世界上最好的語言", "publishyear" : 2020 }
{ "_id" : ObjectId("5f3367482d2d59d358e1219b"), "bookname" : ".net core3.1 with mongodb1", "description" : "這是一本關(guān)于在.net core3.1中使用mongodb進(jìn)行開發(fā)的教程1", "tags" : [".net core", "mongodb"], "remark" : "C#是世界上最好的語言", "publishyear" : 2020 }
{ "_id" : ObjectId("5f3367482d2d59d358e1219c"), "bookname" : ".net core3.1 with mongodb2", "description" : "這是一本關(guān)于在.net core3.1中使用mongodb進(jìn)行開發(fā)的教程2", "tags" : [".net core", "mongodb"], "remark" : "C#是世界上最好的語言", "publishyear" : 2020 }
{ "_id" : ObjectId("5f3367482d2d59d358e1219d"), "bookname" : ".net core3.1 with mongodb2", "description" : "這是一本關(guān)于在.net core3.1中使用mongodb進(jìn)行開發(fā)的教程2", "tags" : [".net core", "mongodb"], "remark" : "C#是世界上最好的語言", "publishyear" : 2020 }
{ "_id" : ObjectId("5f33850d467bf3877966f1ea"), "BookName" : ".net core3.1 with mongodb21", "Description" : "這是一本關(guān) 于在.net core3.1中使用mongodb進(jìn)行開發(fā)的教程21", "Tags" : [".net core", "mongodb"], "Remark" : "C#是世界上最好的語言", "PublishYear" : 2020 }
{ "_id" : ObjectId("5f33850d467bf3877966f1eb"), "BookName" : ".net core3.1 with mongodb22", "Description" : "這是一本關(guān) 于在.net core3.1中使用mongodb進(jìn)行開發(fā)的教程22", "Tags" : [".net core", "mongodb"], "Remark" : "C#是世界上最好的語言", "PublishYear" : 2020 }
{ "_id" : ObjectId("5f33850d467bf3877966f1ec"), "BookName" : ".net core3.1 with mongodb23", "Description" : "這是一本關(guān) 于在.net core3.1中使用mongodb進(jìn)行開發(fā)的教程23", "Tags" : [".net core", "mongodb"], "Remark" : "C#是世界上最好的語言", "PublishYear" : 2020 }
   

查找特定的文件

大多數(shù)情況下,我們不想檢索所有文檔,而是指定一個(gè)篩選器,它返回與特定篩選器匹配的文檔?,F(xiàn)在讓我們看看為查詢指定篩選器的方法。

 

使用BsonDocumentString

我們可以將BsonDocument定義為一個(gè)過濾器,查詢將找到與文檔中定義的字段相匹配的文檔。將以下代碼添加到您的方法中,并運(yùn)行它以檢索description為“這是一本關(guān)于在.net core3.1中使用mongodb進(jìn)行開發(fā)的教程1”的書籍

var filter = new BsonDocument("description", "這是一本關(guān)于在.net core3.1中使用mongodb進(jìn)行開發(fā)的教程1");
           await collection.Find(filter).ForEachAsync(doc => Console.WriteLine(doc));
 

這樣只返回符合條件的一個(gè)文檔

var filter = new BsonDocument("description", "這是一本關(guān)于在.net core3.1中使用mongodb進(jìn)行開發(fā)的教程1");
           await collection.Find(filter).ForEachAsync(doc => Console.WriteLine(doc));
 

您可能會有些困惑,因?yàn)檫@些方法接受FilterDefinition,但是我們給了它一個(gè)BsonDocument,它沒有出異常。之所以會發(fā)生這種情況,是因?yàn)樗浑[式轉(zhuǎn)換,而且我們也可以通過字符串進(jìn)行轉(zhuǎn)換。要使用字符串,我們需要定義一個(gè)有效的JSON字符串來指定過濾器。我們可以使用下面的代碼對字符串執(zhí)行上述相同的操作,仍然會得到相同的結(jié)果:

var filter= "{description:'這是一本關(guān)于在.net core3.1中使用mongodb進(jìn)行開發(fā)的教程1'}";
           await collection.Find(filter).ForEachAsync(doc => Console.WriteLine(doc));
 

我們也可以指定比較或邏輯運(yùn)算符。例如,查找2020年出版的書。我們可以如下所示構(gòu)建查詢:

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

或者使用字符串

var filter = "{ Age: {'$eq': 23}}";
 

我們所做的是為操作符添加一個(gè)標(biāo)識符,在我們的例子中是$eq。

 

使用FilterDefinitionBuilder

您可以使用FilterDefinitionBuilder,它是FilterDefinition的構(gòu)建器。它提供了一套方法來構(gòu)建查詢,而Lt作為其中之一,指定了小于比較。因此,我們可以使用FilterDefinitionBuilder定義過濾器,如下所示:

var filter = new FilterDefinitionBuilder<BsonDocument>().Lt("publishyear", 2020);
 

或者使用接受LINQ表達(dá)式的重載方法:

var filter = new FilterDefinitionBuilder<Book>().Lt( book => book.PublishYear, 2020);
 

此外,您還可以使用靜態(tài)Builders類來構(gòu)建過濾器定義,該類還具有用于構(gòu)建其他內(nèi)容的靜態(tài)幫助方法,如投影定義、排序定義和其他一些方法。

var filter = Builders<BsonDocument>.Filter.Lt("publishyear", 2020);
var filter = Builders<Book>.Filter.Lt(book => book.PublishYear, 2020);
 

驅(qū)動程序還為過濾器定義重載了3個(gè)操作符。這個(gè)and (&)or (|)not (!)操作。例如,我們希望得到出版年份是2020年且描述信息為這是一本關(guān)于在.net core3.1中使用mongodb進(jìn)行開發(fā)的教程1的書籍信息,我們可以使用構(gòu)建器幫助方法和&重載操作符如下

var builder = Builders<BsonDocument>.Filter;
var filter = builder.Eq("publishyear", 2020) & builder.Eq("description", "`這是一本關(guān)于在.net core3.1中使用mongodb進(jìn)行開發(fā)的教程1");
   

Linq表達(dá) 式

最后一部分我們沒有討論的是這些方法的重載,這些方法采用LINQ表達(dá)式,當(dāng)我們有一個(gè)強(qiáng)類型對象時(shí),我們可以使用LINQ表達(dá)式構(gòu)建一個(gè)過濾器查詢。假設(shè)我們想讓出版年份為2020,描述信息為這是一本關(guān)于在.net core3.1中使用mongodb進(jìn)行開發(fā)的教程1的書籍信息打印出他們。我們使用以下代碼:

  var collection = database.GetCollection<Book>("books");
           await collection.Find(book => book.PublishYear == 2020 && book.Description == "這是一本關(guān)于在.net core3.1中使用mongodb進(jìn)行開發(fā)的教程1").ForEachAsync(doc => Console.WriteLine(doc));
 

我們將集合類型更改為Book并運(yùn)行以下代碼,我們將在控制臺上得到一個(gè)錯(cuò)誤:

錯(cuò)誤描述顯示_id不匹配任何類型的字段或?qū)傩?。這是因?yàn)锽ook對象無法映射_id字段從數(shù)據(jù)庫到“學(xué)生”類型的任何屬性。這是在我們創(chuàng)建文檔時(shí)自動添加的。讓我們通過在Book類中添加Bson類型的ID屬性。

internal class Book
   {
       public ObjectId Id { get; set; }
       public string BookName { get; set; }
       public string Description { get; set; }
       public IEnumerable<string> Tags { get; set; }
       public string Remark { get; set; }
       public int PublishYear { get; set; }
   }
 

并運(yùn)行發(fā)現(xiàn)正常了。當(dāng)然你也可以通過設(shè)置IgnoreExtraElement為true來規(guī)避這個(gè)問題

它只是起作用了。所以很多時(shí)候,你會想用表達(dá)式樹語法來構(gòu)建您的查詢。在需要更多粒度的情況下,可以使用其他方法。

看完上述內(nèi)容,你們掌握在.NET Core中使用MongoDB中如何使用Filter語句檢索文檔的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!

網(wǎng)站標(biāo)題:在.NETCore中使用MongoDB中如何使用Filter語句檢索文檔
文章分享:http://bm7419.com/article32/goshsc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站改版、手機(jī)網(wǎng)站建設(shè)、關(guān)鍵詞優(yōu)化做網(wǎng)站、軟件開發(fā)靜態(tài)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都seo排名網(wǎng)站優(yōu)化