2017-08-15 7 views
0

Ich versuche, eine Summe von Inhalten zu erhalten, die ein Benutzer gemocht, geteilt oder kommentiert hat.MongoDb aggregiert die Anzahl/Summe von 3 Feldern

Mein Inhaltsmodell hat die folgende Struktur.

Content = { 
    _id: ObjectId(), 
    author: ObjectId(), 
    value: <string of post content> 
    tags: [<trings>], 
    likes: [array of user ids], 
    shares: [array of user ids], 
    comments: [{ 
    ContentId(of the same schema), 
    User Id 
    }] 
} 

Nun id mag die Inhaltsdokumente aggregieren über, und ein Ergebnis wie dieses.

{ 
    likes: 20, 
    shares: 10, 
    comments: 5 
} 

Also, kurz gesagt, wann immer es einen Inhalt, wo Benutzer-ID in Gleichen Array ist, wird Gleichen von 1.

Das Gleiche gilt für Aktien und Kommentare erhöht.

Ich bin nicht sicher, ob dies mit Aggregation Framework möglich ist. Ich denke nicht, aber vielleicht einige mongodb Gurus besser wissen

Quick Edit. Teilweise basierend auf dem ersten Post habe ich das gemacht. :)

db.getCollection('contents').aggregate([ 


{$facet: { 
     "likes": [ 
     {$match: {likes: ObjectId("596537d6b63edc2318ee9f0c")} }, 
     {$group: { 
      _id : "$likes", 
      count: { $sum: 1 } 
     }}, 
     { $project: { count: 1} } 
     ], 
     "shares": [ 
     {$match: {shares: ObjectId("596537d6b63edc2318ee9f0c")} }, 
     {$group: { 
      _id : "$shares", 
      count: { $sum: 1 } 
     }}, 
     { $project: { count: 1} } 
     ], 
     "posts": [ 
     {$match: {$and: [ 
      {user: ObjectId("596537d6b63edc2318ee9f0c")}, 
      {parent: {$exists: false} } 
     ]} }, 
     {$group: { 
      _id : "$_id", 
      count: { $sum: 1 } 
     }}, 
     { $project: { count: 1} } 
     ] 
    } 
}]); 

Können Sie vor Ort etwas falsch mit dem Code oben Nun scheint es zu arbeiten, aber ich bin sicher, es gibt eine Art von gotcha, dass im fehlt, da es zu einfach zu sein scheint?

Antwort

0

Sie können die unten Aggregation in Version 3.4 versuchen.

Die folgende Abfrage wird $group alle Dokumente und verwenden Sie Operator, um zu überprüfen, ob der Eingang user_id in den Arrays ist.

Für likes und shares Array verwenden 1 wenn die user_id sonst 0 und $sum gefunden wird, alle Dokumente zu aggregieren über.

Für comments ist es ein zweistufiger Prozess, da es Array von Arrays ist.

$group Schritt ing über die user_id der im Inhaltsdokument zu gehen und überprüft Eingang user_id in jedem Elemente und Ausgang 1 wenn Spiel und sonst 0.

Die comments wird Array Array Werte [[1, 0], [1], [1]] nach Gruppenphase haben. Der nächste Schritt besteht darin, alle Werte zu summieren, um die comments-Zählung unter Verwendung des $reduce Operators zu erhalten.

db.collection_name.aggregate([ 
    { 
    "$group": { 
     "_id": null, 
     "likes": { 
     "$sum": { 
      "$cond": [ 
      { 
       "$in": [ 
       user_id, 
       "$likes" 
       ] 
      }, 
      1, 
      0 
      ] 
     } 
     }, 
     "shares": { 
     "$sum": { 
      "$cond": [ 
      { 
       "$in": [ 
       user_id, 
       "$shares" 
       ] 
      }, 
      1, 
      0 
      ] 
     } 
     }, 
     "comments": { 
     "$push": { 
      "$map": { 
      "input": "$comments", 
      "as": "comment", 
      "in": { 
       "$cond": [ 
       { 
        "$in": [ 
        user_id, 
        "$$comment.user_id" 
        ] 
       }, 
       1, 
       0 
       ] 
      } 
      } 
     } 
     } 
    } 
    }, 
    { 
    "$addFields": { 
     "comments": { 
     "$reduce": { 
      "input": "$comments", 
      "initialValue": 0, 
      "in": { 
      "$add": [ 
       "$$value", 
       { 
       "$sum": "$$this" 
       } 
      ] 
      } 
     } 
     } 
    } 
    } 
]) 
0
db.collection.aggregate([ 
    { 
    $facet: { 
     "LikeCategory": [ 
     { $unwind: "$likes" }, 
     { $group : { 
      _id : "$likes", 
      count: { $sum: 1 } 
     } 
     },{ $project : { 
      userId : "$_id" 
      _id : 0, 
      count : 1 

     }} 
     ], 
     "ShareCategory": [ 
     { $unwind: "$shares" }, 
     { $group : { 
      _id : "$shares", 
      count: { $sum: 1 } 
     } 
     },{ $project : { 
      userId : "$_id" 
      _id : 0, 
      count : 1 

     }} 
     ], 
     "CommentCategory": [ 
     { $unwind: "$comments" }, 
     { $group : { 
      _id : "$comments.userId", 
      count: { $sum: 1 } 
     } 
     },{ $project : { 
      userId : "$_id" 
      _id : 0, 
      count : 1 

     }} 
     ] 
} 
} 
]; 

Auf diese Weise können Sie die Zählimpulse herausfinden. Der obige Code kann einige Syntaxprobleme haben, aber ich hoffe, dass Sie Ihr Problem lösen können.

Verwandte Themen