Mongodb

如何查詢匹配的 MongoDB 文件並從嵌入式文件數組中返回欄位子集?

  • February 1, 2022

我有類似以下的文件:

db.etudiants.insert(
   {
       nom:'emile',
       prenom:'zola',
       cours_reussis:[
           { 
               intitule: ['PAI'],
               Periodes: NumberInt(60),
               note: 60,
               date_reussite: NumberInt(2014),
               dispense: true,
               nom_ecole:'EPFC'
           },
           {
               intitule:'TGP',
               Periodes: NumberInt(40),
               note:75,
               date_reussite: NumberInt(2013),
               dispense: true,
               nom_ecole: 'HEB'
           },
           {
               intitule: 'SO2',
               Periodes: NumberInt(60),
               note: 70,
               date_reussite: NumberInt(2015),
               dispense: true,
               nom_ecole: 'ISFCE'
           },
           {
               intitule: 'IBD',
               Periodes: NumberInt(60),
               note: 80,
               date_reussite: NumberInt(2015),
               dispense:true,
               nom_ecole:'ISFCE'
           }
       ]
   }
)

如何從數組中查詢匹配的文件並返回nom_ecole: 'ISFCE'和年份( )?date_reussite``cours_reussis

如果要在 MongoDB 文件中返回匹配數組元素的子集,最好的方法是使用Aggregation Framework。聚合框架處理類似於 Unix 管道的數據:每個聚合階段的輸出作為輸入傳遞給下一個:

db.etudiants.aggregate([
   // Find relevant documents: this can take advantage of an index, if applicable
   { $match: {
       'cours_reussis.nom_ecole': 'ISFCE',
   }},

   // Expand cours_reussis array into a stream of documents
   { $unwind: '$cours_reussis' },

   // Filter based on matching array elements
   { $match: {
       'cours_reussis.nom_ecole': 'ISFCE',
   }},

   // Project desired subset of fields
   { $project: {
       '_id': "$_id",
       'nom': '$nom',
       'prenom': '$prenom',
       'cours_reussis' : { 'nom_ecole': 1, date_reussite: 1 }
   }},

   // Regroup data as per the original document _id
   { $group: {
       _id: "$_id",
       nom: { $first: "$nom" },
       prenom: { $first: "$prenom" },
       cours_reussis: { $push: "$cours_reussis" }
   }}
])

您可以從一個階段開始調試聚合管道,然後假設您看到預期的輸出,一次添加一個階段。

MongoDB 3.2 的範例輸出:

{
 "_id": ObjectId("58462f40f8475aba9f391216"),
 "nom": "emile",
 "prenom": "zola",
 "cours_reussis": [
   {
     "date_reussite": 2015,
     "nom_ecole": "ISFCE"
   },
   {
     "date_reussite": 2015,
     "nom_ecole": "ISFCE"
   }
 ]
}

您可以使用聚合管道階段運算符,在db.collection.aggregate方法中,管道階段出現在一個數組中。文件按順序通過這些階段。

筆記 :

有關特定運算符的詳細資訊,包括語法和範例,請點擊特定運算符以轉到其參考頁面。

對於語法

db.collection.aggregate( [ { <stage> }, ... ] )

$match(聚合)

過濾文件以僅將與指定條件匹配的文件傳遞到下一個管道階段。

$match 階段具有以下原型形式:

{ $match: { <query> } }

如下所述,您的文件詳細資訊

在此處輸入圖像描述

在使用$match(聚合)運算符過濾文件以僅將與指定條件匹配的文件傳遞到下一個管道階段之後。

在此處輸入圖像描述

行為

管道優化

放置 $ match as early in the aggregation pipeline as possible. Because $ match 限制了聚合管道中的文件總數,早期的 $match 操作最大限度地減少了管道的處理量。

如果您將 $match 放在pipeline的最開頭,則查詢可以像任何其他db.collection.find()db.collection.findOne()一樣利用索引。

引用自:https://dba.stackexchange.com/questions/157280