过滤后,猫鼬提取第一个子阵列元素

时间:2016-09-19 18:51:51

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

我有像这样的子文档中的数组

    {
    "_id" : ObjectId("512e28984815cbfcb21646a7"),
    "descDay" : [
        {
            "language" : "en",
            "desc": "day description"
        },
        {
            "language" : "es",
            "desc": "descripcion del dia"
        }
    ]
}

我想按语言过滤子文档。我可以这样做

db.test.aggregate([
    { $project: {
        descDay: {$filter: {
            input: '$list',
            as: 'item',
            cond: {$gt: ['$$item.language', 'en']}
        }}
    }}
])

这会给我一些像

的东西
{
  "_id" : ObjectId("512e28984815cbfcb21646a7"),
   "descDay" : [
      {
        "language" : "en",
        "desc": "day description"
       }]
}

但我需要descDay成为一个不是数组的文档,如下所示:

   {
      "_id" : ObjectId("512e28984815cbfcb21646a7"),
       "descDay" : 
          {
            "language" : "en",
            "desc": "day description"
           }
    }

我怎么能得到它?

1 个答案:

答案 0 :(得分:3)

您可以使用$unwind将单元素descDay数组展开到对象中:

db.test.aggregate([
    { $project: {
        descDay: {$filter: {
            input: '$descDay',
            as: 'item',
            cond: {$eq: ['$$item.language', 'en']}
        }}
    }},
    { $unwind: '$descDay' }
])

或者,正如@chridam所提到的,您可以在$project中使用$arrayElemAt并直接投影第一个元素:

db.test.aggregate([
    { $project: {descDay: {$arrayElemAt: [
        {$filter: {
            input: '$descDay',
            as: 'item',
            cond: {$eq: ['$$item.language', 'en']}
        }}, 0]
    }}}
])

无论哪种方式,输出都是:

{ 
    "_id" : ObjectId("512e28984815cbfcb21646a7"), 
    "descDay" : {
        "language" : "en", 
        "desc" : "day description"
    }
}

请注意,我必须在原始查询中修复一些问题:

  1. '$list''$descDay'
  2. $gt$eq