2017-03-21 23 views
2

假設我的結構爲;

{ 
    "class" : "TESTCLASS", 
    "id" : "HyvF1sdZl", 
    "depends" : [ 
     "S11T5ce", 
     "BytQLN6ml", 
     "Byzz8Ea7l", 
     "r1TUNX58x" 
    ], 
    "list" : [ 
     { 
      "class" : "DATA", 
      "id" : "H113d5Pwx" 
     }, 
     { 
      "class" : "DATA", 
      "id" : "H113d5Pwx" 
     }, 
     { 
      "class" : "TEST", 
      "id" : "r1TUNX58x" 
     }, 
     { 
      "class" : "DATA", 
      "id" : "H113d5Pwx" 
     }, 
     { 
      "class" : "TEST", 
      "id" : "r1TUNX58x" 
     }, 
     { 
      "class" : "TEST", 
      "id" : "r1TUNX58x" 
     }, 
     { 
      "class" : "FDSAFAS", 
      "id" : "S11T5ce" 
     }, 
     { 
      "class" : "YENITEST", 
      "id" : "r1TUNX58x" 
     }, 
     { 
      "class" : "FDSAFAS", 
      "id" : "S11T5ce" 
     }, 
     { 
      "class" : "CALENDAR", 
      "id" : "S11T5ce" 
     }, 
     { 
      "class" : "EN", 
      "id" : "BytQLN6ml" 
     }, 
     { 
      "class" : "CALENDAR", 
      "id" : "S11T5ce" 
     }, 
     { 
      "class" : "EN_", 
      "id" : "Byzz8Ea7l" 
     }, 
     { 
      "class" : "TEST", 
      "id" : "r1TUNX58x" 
     }, 
     { 
      "class" : "EN", 
      "id" : "BytQLN6ml" 
     }, 
     { 
      "class" : "FDSAFAS", 
      "id" : "S11T5ce" 
     } 
    ] 
} 

我想projectlist項目,其id的都包括在depends陣列。

我的意思是,我只想得到;

"depends" : [ 
    "S11T5ce", 
    "BytQLN6ml", 
    "Byzz8Ea7l", 
    "r1TUNX58x" 
], 
"list" : [ 
    { 
     "class" : "FDSAFAS", 
     "id" : "S11T5ce" 
    }, 
    { 
     "class" : "EN", 
     "id" : "BytQLN6ml" 
    }, 
    { 
     "class" : "EN_", 
     "id" : "Byzz8Ea7l" 
    }, 
    { 
     "class" : "TEST", 
     "id" : "r1TUNX58x" 
    } 

] 

爲了能夠做到這一點,我寫了;

db.definition.aggregate([ 
    { 
     $project: { 
      _id: 0, 
      depends :1, 
      depends: {$in: ["$list.id"]}, 
      "list.defid": 1, 
      "list.class" :1, 
     } 

    } 
]).pretty() 

但是,這將引發我缺少的是一個錯誤"errmsg" : "Expression $in takes exactly 2 arguments. 1 were passed in."

回答

1

用MongoDB的3.4你可以使用$addFields管道項目等領域沒有明確點名地。作爲一個單一的管道,使用的$setUnion的組合,$filter$in運營商返回所需 陣列。運營商在應用運營商之前有助於消除重複。

跟隨直覺,讓我們跟隨這正好與$filter運營商運行這個例子管道:

db.collection.aggregate([ 
    { 
     "$addFields": { 
      "list": { 
       "$filter": { 
        "input": "$list", 
        "as": "item", 
        "cond": { "$in": ["$$item.id", "$depends"] }      
       } 
      } 
     } 
    } 
]) 

樣本輸出

{ 
    "_id" : ObjectId("58d0e0d97a3871921504bb69"), 
    "class" : "TESTCLASS", 
    "id" : "HyvF1sdZl", 
    "depends" : [ 
     "S11T5ce", 
     "BytQLN6ml", 
     "Byzz8Ea7l", 
     "r1TUNX58x" 
    ], 
    "list" : [ 
     { 
      "class" : "TEST", 
      "id" : "r1TUNX58x" 
     }, 
     { 
      "class" : "TEST", 
      "id" : "r1TUNX58x" 
     }, 
     { 
      "class" : "TEST", 
      "id" : "r1TUNX58x" 
     }, 
     { 
      "class" : "FDSAFAS", 
      "id" : "S11T5ce" 
     }, 
     { 
      "class" : "YENITEST", 
      "id" : "r1TUNX58x" 
     }, 
     { 
      "class" : "FDSAFAS", 
      "id" : "S11T5ce" 
     }, 
     { 
      "class" : "CALENDAR", 
      "id" : "S11T5ce" 
     }, 
     { 
      "class" : "EN", 
      "id" : "BytQLN6ml" 
     }, 
     { 
      "class" : "CALENDAR", 
      "id" : "S11T5ce" 
     }, 
     { 
      "class" : "EN_", 
      "id" : "Byzz8Ea7l" 
     }, 
     { 
      "class" : "TEST", 
      "id" : "r1TUNX58x" 
     }, 
     { 
      "class" : "EN", 
      "id" : "BytQLN6ml" 
     }, 
     { 
      "class" : "FDSAFAS", 
      "id" : "S11T5ce" 
     } 
    ] 
} 

隨着$setUnion操作,重複在應用之前首先被消除爲:

db.collection.aggregate([ 
    { 
     "$addFields": { 

      "list": { 
       "$filter": { 
        "input": { "$setUnion": ["$list", []] }, 
        "as": "item", 
        "cond": { "$in": ["$$item.id", "$depends"] }      
       }     
      }    
     } 
    } 
]) 

樣本輸出

{ 
    "class" : "TESTCLASS", 
    "id" : "HyvF1sdZl", 
    "depends" : [ 
     "S11T5ce", 
     "BytQLN6ml", 
     "Byzz8Ea7l", 
     "r1TUNX58x" 
    ], 
    "list" : [ 
     { 
      "class" : "FDSAFAS", 
      "id" : "S11T5ce" 
     }, 
     { 
      "class" : "TEST", 
      "id" : "r1TUNX58x" 
     }, 
     { 
      "class" : "YENITEST", 
      "id" : "r1TUNX58x" 
     }, 
     { 
      "class" : "EN_", 
      "id" : "Byzz8Ea7l" 
     }, 
     { 
      "class" : "CALENDAR", 
      "id" : "S11T5ce" 
     }, 
     { 
      "class" : "EN", 
      "id" : "BytQLN6ml" 
     } 
    ] 
} 
+1

在MongoDB 3.4中,您應該使用['$ in'](https://docs.mongodb。com/manual/reference/operator/aggregation/in /)聚合運算符而不是'$ setIsSubset' – styvane

+0

@ M.StyvaneSoukossi確實!感謝指針 – chridam

1

你可先用$project$filter濾除對象其中id是不是depends數組,但然後通過ID返回唯一對象,也包括類是有點問題,因爲如果你使用$addToSet你不能指定領域您想要使其唯一,但忽略對象中的其他字段,或者在此例中列出class

db.col.aggregate([ 
    {$project: { 
     depends: 1, 
     class: 1, 
     list: { 
      $filter: { 
       input: '$list', 
       as: 'item', 
       cond: { 
        $setIsSubset: [['$$item.id'], '$depends'] 
       } 
      } 
     } 
    }}, 
    {$unwind: '$list'}, 
    {$group: { 
     _id: '$_id', 
     depends: {$first: '$depends'}, 
     class: {$first: '$class'}, 
     list: { 
      $addToSet: { 
       id: '$list.id', 
       class: '$list.class' 
      } 
     }, 

    }} 
]) 

最後的結果是這樣的

[{ 
    "_id": "58d0cea6aecf3102684e4f0e", 
    "depends": ["S11T5ce", "BytQLN6ml", "Byzz8Ea7l", "r1TUNX58x"], 
    "class": "TESTCLASS", 
    "list": [{ 
    "id": "Byzz8Ea7l", 
    "class": "EN_" 
    }, { 
    "id": "BytQLN6ml", 
    "class": "EN" 
    }, { 
    "id": "S11T5ce", 
    "class": "FDSAFAS" 
    }, { 
    "id": "r1TUNX58x", 
    "class": "YENITEST" 
    }, { 
    "id": "S11T5ce", 
    "class": "CALENDAR" 
    }, { 
    "id": "r1TUNX58x", 
    "class": "TEST" 
    }] 
}] 
+0

如果你不希望在最終結果的ID,你可以在末尾添加多一個'$ project' https://jsfiddle.net/Lg0wyt9u/1724/ –