嵌入式文档的项目特定字段

时间:2018-04-05 18:17:50

标签: mongodb aggregation-framework

我试图只获取特定嵌入文档的一个字段。

嵌入式文档应根据两个条件进行过滤 然后只返回该嵌入文档的一个字段。

db.usertest.insertMany(
    [{
    "username" : "userA",
    "objects" : [
        {
        "type" : "fruit",
        "origin" : "ABC",
        "name" : "banana",
        },
        {
        "type" : "fruit",
        "origin" : "XYZ",
        "name" : "pineapple",
        },

        {
        "type" : "vegetable",
        "origin" : "XYZ",
        "name" : "carrot"
        }
    ]
    },
     {
     "username" : "userB",
     "objects" : []
     }
]
)

我想找到字段"用户名"和#34;名称"的 嵌入式文件。

首先我想到了$ elemMatch,但我被困在了$ project部分 它只返回字段" name"所有嵌入文件的时候 $ elemMatch是真的。

db.usertest.aggregate(
    [{$match:{"objects": {"$elemMatch":{
         "type": "fruit",
         "origin": "XYZ"}}}},
     {$project: {
      "username":1,
      "objects.name":1
      }}]
).pretty()

然后我想到了使用$ filter,但它显然只是返回了 整个嵌入式文档而不仅仅是字段" name"。

db.usertest.aggregate(
    [{$project: {
      "username":1,
      "name":{
          $filter: {
             input: "$objects",
             cond: { $and: [
                     { $eq: [ "$$this.type", "fruit" ] },
                  { $eq: [ "$$this.origin", "XYZ" ] }
                 ]}
          }}
      }}]
).pretty()

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

您可以按以下顺序组合多个聚合运算符:

$filter - > $map(仅获取name属性) - > $arrayElemAt(采取第一个元素)

db.usertest.aggregate(
  [{$project: {
    "username":1,
    "name": {
      $arrayElemAt: [
        {
          $map: {
            input: {
              $filter: {
                 input: "$objects",
                 cond: { $and: [
                         { $eq: [ "$$this.type", "fruit" ] },
                      { $eq: [ "$$this.origin", "XYZ" ] }
                     ]}
              }},
              as: "item",
              in: "$$item.name"
          }
        },0
      ]
    }
    }}]
).pretty()

答案 1 :(得分:1)

$project阶段有no $elemMatch operator。因此,要使用模拟类似功能,您可以使用索引为0和$filter的{​​{1}}创建$arrayElemAt,以将中间文档保存在变量中并输出名称。

保留$let阶段,以便只查看至少有一个匹配对象的文档。

这样的东西
$match