2017-07-26 15 views
1

我使用$ lookup組合了兩個集合,並且我能夠在「已加入」集合上應用過濾器並在起始集合上使用投影,但是我沒有設法在使用$ redact和$ project的幾種方法中,將聯合集合中的過濾器和投影結合起來。我仔細查看了stackoverflow,但我找不到這個組合。 這裏來了一個例子: 收集元:如何在濾波查找中投影數組中的特定字段

{ "Exp": "A","test": "OK","date": "3"} 
{ "Exp": "B","test": "OK","date": "5"} 
{ "Exp": "C","test": "Failed","date": "9"} 

收集合並(要加入'):

{ "Exp": "A","M1": "2","M2": "test","T": "1"} 
{ "Exp": "A","M1": "2","M2": "val", "T": "2"} 
{ "Exp": "A","M1": "2", "M2": "val","T": "3"} 
{ "Exp": "B","M1": "1", "M2": "test","M4": "1","T": "1"} 
{ "Exp": "B","M1": "1","M2": "val","M4": "1","T": "2"} 
{ "Exp": "B","M1": "1","M2": "val","M4": "1","T": "3"} 
{ "Exp": "C","M1": "2","M2": "test","M3": "2","T": "1"} 
{ "Exp": "C","M1": "2","M2": "val","M3": "2","T": "2"} 
{ "Exp": "C","M1": "2","M2": "val","M3": "2","T": "3"} 

和查詢的是:加入 '元' 和 '合併' 使用 '精通' ,並只選擇那些meta.test =「OK」和merge.M2 =「val」,但只顯示meta.Exp,meta.test和merge.M1,merge.M2和merge.T。

這是多遠我得到:

db.meta.aggregate([ 
{ $match: { test: "OK" }}, 
{ $lookup: 
    { from: "merge", 
    localField: "Exp", 
    foreignField: "Exp", 
    as: "kin" 
    } 
}, 
{ $project: 
    { "Exp": true, 
    "test": true, 
    kin : 
    { $filter: 
     { input: "$kin", 
     as: "kin", 
     cond: { $eq: [ "$$kin.M2", "val" ]} 
     } 
    } 
    } 
    } 
]) 

而是試圖與過濾器保持遇事包括merge.M1,merge.M2和merge.T額外的投影在一起。結果應該是:

{ "Exp" : "B", 
    "test" : "OK", 
    "kin" : [ 
     { "M1" : "1", 
     "M2" : "val", 
     "T" : "2"}, 
     { "M1" : "1", 
     "M2" : "val", 
     "T" : "3"}] 
} 
{ "Exp" : "A", 
    "test" : "OK", 
    "kin" : [ 
     { "M1" : "2", 
     "M2" : "val", 
     "T" : "2"}, 
     { "M1" : "2", 
     "M2" : "val", 
     "T" : "3"} 
    ] 
} 

感謝提示! 霍爾迪

+0

如果你想限制數組中的「fields」,你可以使用'$ map',並且只包含你想要的字段。您可以使用'$ filter'作爲''input'''參數到'$ map'。 –

+0

嗨,不能得到它的工作。一個例子會非常好。 – Jordi

+0

那麼我只用** 1 **階段來解決它。也許你應該看看它並學習一些東西。既然你確實要求。 –

回答

0

您使用$map指定數組的領域要返回的:

db.meta.aggregate([ 
    { "$match": { test: "OK" }}, 
    { "$lookup":{ 
    "from": "merge", 
    "localField": "Exp", 
    "foreignField": "Exp", 
    "as": "kin" 
    }}, 
    { "$project": { 
    "Exp": 1, 
    "test": 1, 
    "kin": { 
     "$map": { 
     "input": { 
      "$filter": { 
      "input": "$kin", 
      "as": "k", 
      "cond": { "$eq": [ "$$k.M2", "val" ] } 
      } 
     }, 
     "as": "k", 
     "in": { 
      "M1": "$$k.M1", 
      "M2": "$$k.M2", 
      "T": "$$k.T" 
     } 
     } 
    } 
    }} 
]) 

這對於你返回:

/* 1 */ 
{ 
    "_id" : ObjectId("5979a8857dcd6a5f6a9b4b9a"), 
    "Exp" : "A", 
    "test" : "OK", 
    "kin" : [ 
     { 
      "M1" : "2", 
      "M2" : "val", 
      "T" : "2" 
     }, 
     { 
      "M1" : "2", 
      "M2" : "val", 
      "T" : "3" 
     } 
    ] 
} 

/* 2 */ 
{ 
    "_id" : ObjectId("5979a8857dcd6a5f6a9b4b9b"), 
    "Exp" : "B", 
    "test" : "OK", 
    "kin" : [ 
     { 
      "M1" : "1", 
      "M2" : "val", 
      "T" : "2" 
     }, 
     { 
      "M1" : "1", 
      "M2" : "val", 
      "T" : "3" 
     } 
    ] 
} 
0

的另一種方式,由colleaque建議使用第二$投影。我認爲這比$ map更有效,因爲它不會覆蓋數組中的每個元素。訣竅是從第一個投影重複投影。

db.meta.aggregate([ 
    { $match: { test: "OK" }}, 
    { $lookup: { from: "merge", localField: "Exp", foreignField: "Exp", as: 
    "kin" }}, 
    { $project: 
    { "Exp": true, "test": true, "date": true, 
     kin : { $filter: { input: "$kin", as: "kin", cond: { $eq: [ 
     "$$kin.M2", 
     "val" ]}} 
    } 
    } 
    }, 
    { $project: { 
    "Exp": true, "test": true, "date": true, 
    "kin.M1": true, "kin.M2": true, "kin.T": true } 
    } 
]) 
相關問題