2016-12-09 37 views
2

原諒我,如果我在這裏混淆了一些術語回來了,但我在執行使用「$查找」運營商聚集一結合操作如下所示:

db.collection('items').aggregate([{$match: {}}, 
{ 
    $lookup: { 
     from: 'usr', 
     localField: 'usr._id', 
     foreignField: '_id', 
     as: '__usr' 
    } 
}, { 
    $project: { 
     info: 1, 
     timestamp: 1, 
     usr: { 
      "$arrayElemAt": [ "$__usr", 0 ] 
     } 
    } 
}], (err, result) => { 
    res.json(result); 
    db.close(); 
}); 

我正在對聚合結果執行投影,並且使用'$ arrayElemAt'從結果數組中提取單個'usr'匹配。 由於顯而易見的原因,我不想返回包含敏感信息的整個'usr'記錄。 我正在做的是對使用'$ arrayElemAt'操作返回的元素執行投影。 我已經能夠做到這一點的唯一方法是使用原始投影的附加投射,就像這樣:

db.collection('items').aggregate([{$match: {}}, 
{ 
    $lookup: { 
     from: 'usr', 
     localField: 'usr._id', 
     foreignField: '_id', 
     as: '__usr' 
    } 
}, { 
    $project: { 
     info: 1, 
     timestamp: 1, 
     usr: { 
      "$arrayElemAt": [ "$__usr", 0 ] 
     } 
    } 
}, { 
    $project: { 
     info: 1, 
     timestamp: 1, 
     usr: { 
      "username": 1 
     } 
    } 
}], (err, result) => { 
    res.json(result); 
    db.close(); 
}); 

有沒有辦法做到這一點不重複的投影?

回答

3

您可以使用$let表達式將$arrayElemAt返回值指定給變量,並使用點符號來訪問in表達式中的子文檔字段。

"usr": { 
    "$let": { 
     "vars": { 
      "field": { 
       "$arrayElemAt": [ "$__usr", 0 ] 
      } 
     }, 
     "in": "$$field.username" 
    }