2016-12-09 3 views
2

mir verzeihen, wenn ich einige Begriffe hier verwirren, aber ich bin eine in einer Aggregation Join-Operation Ausführen des ‚$ Lookup‘ Operator wie hier gezeigt:

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(); 
}); 

Ich führe eine Projektion des Aggregationsergebnisses durch und verwende '$ arrayElemAt', um die einzelne 'usr'-Übereinstimmung aus dem resultierenden Array zu extrahieren. Aus offensichtlichen Gründen möchte ich nicht den gesamten 'usr'-Datensatz zurückgeben, der vertrauliche Informationen enthält. Was ich tun möchte, ist eine Projektion auf das Element mit der Operation '$ arrayElemAt' zurückgegeben. Die einzige Art, wie ich in der Lage bin, dies zu erreichen ist eine zusätzliche Projektion der ursprünglichen Projektion zu verwenden, etwa so:

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(); 
}); 

Gibt es eine Möglichkeit, dies ohne die duplizierten Projektion zu erreichen?

Antwort

3

Sie können den zurückgegebenen Wert einer Variablen mithilfe des Ausdrucks $let zuweisen und die Punktnotation verwenden, um auf das Filialdokumentfeld im Ausdruck in zuzugreifen.

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