如何投影单个数组字段

How to project single array field

从此文档架构开始

{ 
    "_id" : ObjectId("5a5cfde58c8a4a35a89726b4"), 
    "Names" : [ 
                { "Code" : "en", "Name" : "ITALY" }, 
                { "Code" : "it", "Name" : "ITALIA" } 
              ],
    "TenantID" : ObjectId("5a5cfde58c8a4a35a89726b2"),
    ...extra irrelevant fields
}

我需要这样的对象

{ 
    "ID" : ObjectId("5a5cfde58c8a4a35a89726b4"), 
    "Name" : "ITALY"
}

按数组的代码字段过滤(示例中按 'en')。

我写了一个聚合查询,这个

db.Countries.aggregate([{$project: {_id:0, 'ID': '$_id', 'Names': {$filter: {input: '$Names', as: 'item', cond: {$eq: ['$$item.Code', 'en']}}}}},{$skip: 10},{$limit: 5}]);

正确地 return 仅记录具有 'en' 名称值的文档,return仅记录子数组匹配元素。

现在我找不到将名称字段值 return 转换为新的 'Name' 字段的方法。 执行此操作的最佳和最有效方法是什么?

实际上我正在尝试 Mongo shell,但稍后我需要使用 .NET 驱动程序复制此行为。

使用 MongoDB 3.6

谢谢

您可以尝试下面的聚合查询。

$match 只考虑数组中至少有一个元素匹配输入条件的文档。

$filter 输入条件数组和 $arrayElemAt 投影单个匹配元素。

$let 从匹配的对象中输出名称。

db.Countries.aggregate([
  {"$match":{"Names.Code":"en"}},
  {"$project":{
    "_id":0, 
    "ID": "$_id",
    "Name":{
      "$let":{
        "vars":{
          "obj":{
            "$arrayElemAt":[
              {"$filter":{
                "input":"$Names",
                "as":"name",
                "cond":{"$eq":["$$name.Code","en"]}
              }},
              0]
          }
        },
        "in":"$$obj.Name"
      }
    }
  }},
 {"$skip": 10},
 {"$limit": 5}
])