簡體   English   中英

Mongoose 從對象數組中獲取與對象項匹配的對象

[英]Mongoose get objects which match an object item from an array of objects

我想找到一個與courseID匹配的文檔,但在文檔中只有材料數組中的對象,其moduleNo與我給出的匹配。 但我目前使用的查詢似乎返回了正確的文檔,但也返回了材料數組中的所有對象。 任何幫助,將不勝感激。

我的架構,

const materialSchema = new mongoose.Schema({
  courseID: String,
  materials: [
    {
      moduleNo: Number,
      moduleMaterial: String,
    },
  ],
});

我的代碼/查詢,

 exports.getMaterials = (req, res) => {
  const { courseID, moduleNo } = req.query;
  Material.findOne(
    { courseID, "materials.moduleNo": moduleNo },
    (err, result) => {
      if (err) {
        console.error(err);
      } else {
        res.json(result);
      }
    }
  );
};

使用$elemMatch運算符,如下所示:

exports.getMaterials = (req, res) => {
  const { courseID, moduleNo } = req.query;
  Material.findOne(
    { courseID },
    {"materials": { $elemMatch: {moduleNo: moduleNo}},
    (err, result) => {
      if (err) {
        console.error(err);
      } else {
        res.json(result);
      }
    }
  );
};

更新:要返回數組中的所有匹配元素,您必須使用具有$filter階段的聚合管道來過濾掉數組元素。 像這樣:

exports.getMaterials = (req, res) => {
  const { courseID, moduleNo } = req.query;
  Material.aggregate(
    [
  {
    $match: {
      courseID: courseID
    }
  },
  {
    "$project": {
      courseID: 1,
      materials: {
        "$filter": {
          "input": "$materials",
          "as": "material",
          "cond": {
            "$eq": [
              "$$material.moduleNo",
              moduleNo
            ]
          }
        }
      }
    }
  }
]
  );
};

這是操場鏈接

方式 1:在項目字段中使用$elemMatch運算符

$elemMatch運算符將查詢結果中的數組字段的內容限制為僅包含與 $elemMatch 條件匹配的第一個元素

結果:只返回一個匹配的數組元素

句法 :

db.collection.find(query,projection)

db.collection.find({
     "field": field_value                  
  },{
    "array_name":{
       $elemMatch:{"key_name": value }
    },
    field:1,
    field_2:1,
    field_3:0
})

https://mongoplayground.net/p/HKT1Gop32Pq

方式2:數組字段限制array.$在項目字段*

結果:只返回一個匹配的數組元素

db.collection.find({
     "field": field_value,
     "array_name.key_name": value       
  },{
        "array_name.$":1,
        field:1,
        field_2:1,
        field_3:0
 });

https://mongoplayground.net/p/Db0azCakQg9

更新:使用 MongoDB 聚合

結果:返回多個匹配的數組元素

db.collection.aggregate([
  {
    "$unwind": "$materials"
  },
  {
    "$match": {
      "courseID": "Demo",
      "materials.moduleNo": 1
    }
  }
]) 

將返回輸出為:

[
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "courseID": "Demo",
    "materials": {
      "moduleMaterial": "A",
      "moduleNo": 1
    }
  },
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "courseID": "Demo",
    "materials": {
      "moduleMaterial": "B",
      "moduleNo": 1
    }
  }
]

如果你想格式化輸出:

db.collection.aggregate([
  {
    "$unwind": "$materials"
  },
  {
    "$match": {
      "courseID": "Demo",
      "materials.moduleNo": 1
    }
  },
  {
    "$group": {
      "_id": {
        "courseID": "$courseID",
        "moduleNo": "$materials.moduleNo"
      },
      "materials": {
        "$push": "$materials.moduleMaterial"
      }
    }
  },
  {
    "$project": {
      "_id": 0,
      "courseID": "$_id.courseID",
      "moduleNo": "$_id.moduleNo",
      "materials": "$materials"
    }
  }
])

將返回結果為:

[
  {
    "courseID": "Demo",
    "materials": [
      "A",
      "B"
    ],
    "moduleNo": 1
  }
]

https://mongoplayground.net/p/vdPVbce6WkX

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM