2014-06-12 7 views
6

J'ai ces 3 demandes:

db.mycollection.count({requestA:{$exists:true}}) 
db.mycollection.count({requestB:{$exists:true}}) 
db.mycollection.count({requestC:{$exists:true}}) 

Je voudrais faire une seule demande ... donc j'ai essayé les éléments suivants:

db.mycollection.aggregate([ 
    { $group: { 
     '_id' : { user_id: '$user_id'}, 
     requestA_count: { $sum: { 
      $cond: [ {requestA:{'$exists':true}}, 1, 0 ] 
     } }, 
     requestB_count: { $sum: { 
      $cond: [ {requestB:{'$exists':true}}, 1, 0 ] 
     } }, 
     requestC_count: { $sum: { 
      $cond: [ {requestC:{'$exists':true}}, 1, 0 ] 
     } }, 
    } }, 
    { $project: { 
     _id: 0, 
     user_id: '$_id.user_id', 
     requestA_count: 1, 
     requestB_count: 1, 
     requestC_count: 1 
    } } 
]); 

Mais je suis l'erreur:

"errmsg" : "exception: invalid operator '$exists'", 

Je suppose que nous ne pouvons pas utiliser existe $ avec $ projet.

Des conseils sur une bonne approche? Merci

Répondre

10

Vous aviez la bonne idée de base, mais $exists est une condition de requête qui n'est valide qu'avec un $match. Ce que vous voulez est l'opérateur $ifNull faire essentiellement la même chose:

db.mycollection.aggregate([ 
    { "$group": { 
     "_id" : { "user_id": "$user_id" }, 
     "requestA_count": { "$sum": { 
      "$cond": [ { "$ifNull": ["$requestA", false] }, 1, 0 ] 
     } }, 
     "requestB_count": { "$sum": { 
      "$cond": [ { "$ifNull": ["$requestB", false] }, 1, 0 ] 
     } }, 
     "requestC_count": { "$sum": { 
      "$cond": [ { "$ifNull": ["$requestC", false] }, 1, 0 ] 
     } }, 
    } }, 
    { "$project": { 
     "_id": 0, 
     "user_id": "$_id.user_id", 
     "requestA_count": 1, 
     "requestB_count": 1, 
     "requestC_count": 1 
    } } 
]); 

Ainsi, le $ifNull renvoie soit la valeur actuelle du champ si elle existe ou l'argument « côté droit » est retourné si elle ne . La valeur renvoyée autre que false est interprétée comme étant true (à moins bien sûr que la valeur soit réellement fausse). Essentiellement, cela vous donne la même fonctionnalité de tester logiquement l'existence d'une propriété dans le document.

+0

Merci Neil pour l'explication! –

+0

En fait, Neil, requestA_count, requestB_count, requestC_count ont toujours la même valeur ...: /! Je veux dire, si requestA_count = 9 alors requestB_count et requestC_count = 9 –

+0

@JohnSmith pouvez-vous éditer votre question pour montrer des données avec différents champs présents. Pour moi cela fonctionne. Si le champ n'existe pas, la valeur passée à sum est 0. –

Questions connexes