MongoDB请求:仅从嵌入数组中的嵌入文档中过滤特定字段

时间:2018-03-01 13:02:56

标签: node.js mongodb mongoose mongodb-query aggregation-framework

我遇到了一些我想要执行的MongoDB请求的麻烦。我在 js上下文中使用 MongoDB 3.2 Mongoose。这是文件:

{
  _id: ObjectId('12345'),
  name: "The name",
  components: [
    {
      name: "Component 1",
      description: "The description",
      container: {
        parameters: [
          {
            name: "Parameter 1",
            value: "1"
          },
          // other parameters
        ],
        // other information...
      }
    },
    // other components
  ]
}

我想在此输出中列出特定文档(使用_id)中特定组件的所有参数名称(使用组件名称):

['Parameter 1', 'Parameter 2', ...]

我有一个mongoose Schema来处理我的应用程序中的finddistinct方法。我使用$定位运算符尝试了很多操作。这是我的尝试,但返回所有组件的所有参数:

listParameters(req, res) {
  DocumentModel.distinct(
    "components.container.parameters.name", 
    {_id: req.params.modelId, "components.name": req.params.compId},
    (err, doc) => {            
      if (err) {
        return res.status(500).send(err);
      }
      res.status(200).json(doc);
    }
  );
}

但输出是参数名称列表但没有特定组件的过滤器。你能帮我找到合适的要求吗? (如果可能在mongoose JS中,但如果它是Mongo命令行,那将非常好:))

2 个答案:

答案 0 :(得分:1)

您需要运行使用 $arrayElemAt $filter 运算符的聚合管道来获得所需的结果。

$filter 运算符将过滤components数组以返回满足给定条件的元素,而 $arrayElemAt 返回来自给定索引位置的数组的文档。使用该文档,您可以将嵌套的parameters数组元素投影到另一个数组。

结合上述内容,您最好希望进行以下聚合操作:

DocumentModel.aggregate([
    { "$match": { "_id": mongoose.Types.ObjectId(req.params.modelId) } },
    { "$project": {
        "component": {
            "$arrayElemAt": [
                {
                    "$filter": {
                        "input": "$components",
                        "as": "el",
                        "cond": { "$eq": ["$$el.name", req.params.compId] }
                    }
                }, 0
            ]
        }
    } },
    { "$project": {
        "parameters": "$component.container.parameters.name"
    } }
], (err, doc) => {            
  if (err) {
    return res.status(500).send(err);
  }
  const result = doc.length >= 1 ? doc[0].parameters : [];
  res.status(200).json(result);
})

答案 1 :(得分:0)

我不知道怎么用猫鼬做这件事,但这对mongo来说很有用



db.getCollection('your collaction').aggregate([ // change to youe collaction
    {$match: {_id: ObjectId("5a97ff4cf832104b76d29af7")}}, //change to you id
    {$unwind: '$components'},
    {$match: {'components.name': 'Component 1'}}, // change to the name you want 
    {$unwind: '$components.container.parameters'},
    {
        $group: {
            _id: '$_id',
            params: {$push: '$components.container.parameters.name'}
        }
    }


]);