2016-11-16 9 views
5

(集計を使用して)単一のクエリでユーザーを招待していないユーザーを探したいと思います。ユーザーを招待していないユーザーを見つける

は、例えば:私は

1- AAAがBBBとCCCユーザ

2- BBB招待DDDのユーザを招待ここ

{ 
    "_id" : ObjectId("581a18d41b6c5c752f11c87a"), 
    "name": "aaa", 
    "invitedBy": ObjectId("5808f53d28c14ee470856d8b") 
}, 

{ 
    "_id" : ObjectId("581a1a671b6c5c752f11c87b"), 
    "name": "bbb", 
    "invitedBy": ObjectId("581a18d41b6c5c752f11c87a") 
}, 

{ 
    "_id" : ObjectId("581a1a671b6c5c752f11c87c"), 
    "name": "ccc", 
    "invitedBy": ObjectId("581a18d41b6c5c752f11c87a"), 
}, 

{ 
    "_id" : ObjectId("581a1a671b6c5c752f11c87d"), 
    "name": "ddd", 
    "invitedBy": ObjectId("581a1a671b6c5c752f11c87b"), 
} 

DB 4人のユーザを有する

3 - cccとdddのユーザーはいずれも招待していません

はので、私はそれが良いだろうCCC DDDユーザー

をpicにしたい場合は、私が選択したデータに何らかの操作を行う必要があるため、集計を使用してすることができます。

+0

あなたのMongoDBのバージョンは何ですか? – styvane

+0

MongoDBのバージョンは3.2です@Styvane –

+0

@ 4J41 ['mongodb-aggregation'タグ](http://meta.stackoverflow.com/questions/337096/let-burninate-mongodb-aggregation)を使用しないでください。 – styvane

答えて

5

$lookup演算子を使用すると、コレクション自体に左結合を実行できます。

招待状を送信していないユーザーは、招待状が空のユーザーです。これらのユーザーのみを取得するには、$exists演算子と数値配列インデックスを使用して、$matchステージのドキュメントをフィルタ処理します。得

db.users.aggregate(
    [ 
     { "$lookup": { 
      "from": "users", 
      "localField": "_id", 
      "foreignField": "invitedBy", 
      "as": "invitation" 
     }}, 
     { "$match": { "invitation.0": { "$exists": false } } } 
    ] 
) 

は:

{ 
    "_id" : ObjectId("581a1a671b6c5c752f11c87c"), 
    "name" : "ccc", 
    "invitedBy" : ObjectId("581a18d41b6c5c752f11c87a"), 
    "invitation" : [ ] 
} 
{ 
    "_id" : ObjectId("581a1a671b6c5c752f11c87d"), 
    "name" : "ddd", 
    "invitedBy" : ObjectId("581a1a671b6c5c752f11c87b"), 
    "invitation" : [ ] 
} 
+0

Thanks @Styvane –

1

同じことを行う別の方法があります。しかし、この方法は@ Styvaneの答えより効率が悪くなることがあります。より少ない要素がある場合、これはうまくいくはずです。

も得ることができ、他の情報が必要な場合には
[ 
{$group: {_id: null, senders: {$addToSet: '$invitedBy'}, everyone: {$addToSet: '$_id'}}}, 
{$project: {_id: 0, res: {$setDifference: ['$everyone', '$senders']}}} 
] 

、(申し訳ありませんが、それはここで少し汚れ)

[ 
    {$group: {_id: null, senders: {$addToSet: '$invitedBy'}, everyone: {$addToSet: {id: '$_id', name: '$name'}}}}, 
    {$project: {_id: 0, everyone: 1, res: {$setDifference: ['$everyone.id', '$senders']}}}, 
    {$unwind: '$everyone'}, 
    {$unwind: '$res'}, 
    {$project: {flag: {$eq: ['$everyone.id', '$res']}, everyone: 1}}, 
    {$match: {flag: true}} 
] 
+0

OPが '_id'フィールドだけでなくドキュメントのすべてのフィールドを取得する必要がある場合はどうなりますか? – styvane

+0

@Styvaneがそのケースに対して更新されました。 – hyades

関連する問題