2017-05-26 3 views
1

Lassen Sie uns sagen, ich habe ein Match Sammlung in folgendem FormatGruppe den Wert von zwei möglichen Felder

 {user1: "a", user2: "b"}, 
     {user1: "a", user2: "c"}, 
     {user1: "b", user2: "d"}, 
     {user1: "b", user2: "c"}, 
     {user1: "b", user2: "e"}, 
     {user1: "c", user2: "f"} 

Ich möchte wissen, mit denen Benutzer die meisten Aussehen hat (entweder in user1 oder user2). Das Ergebnis sollte in diesem Format nach der Häufigkeit des Auftretens geordnet sein.

{"user": "b", count:4}, 
      {"user": "c", count:3}, 
      {"user": "a", count:2}, 
      {"user": "d", count:1}, 
      {"user": "f", count:1}, 
      {"user": "e", count:1} 

Gibt es eine Möglichkeit, den Wert von zwei Feldern zu gruppieren?

So etwas wie match.aggregate ({$ group: {_id: {$ oder: [ "user1", "user2]}}, zählen: {$ Summe: 1}})

Antwort

7
db.match.aggregate([ 
    {$project: { user: [ "$user1", "$user2" ]}}, 
    {$unwind: "$user"}, 
    {$group: {_id: "$user", count: {$sum:1}}} 
]) 

Erster Stufe Projiziert jedes Dokument in einem Array von Benutzern

{user: ["a", "b"]}, 
    {user: ["a", "c"]}, 
    {user: ["b", "d"]}, 
    ... 

Weiter entspannen wir Arrays

{user:"a"}, 
    {user:"b"}, 
    {user:"a"}, 
    {user:"c"}, 
    {user:"b"}, 
    ... 

Und einfache Gruppierung am Ende

+1

Guter Fang. Ich habe vergessen, dass dies ab 3.2 erlaubt war –

0

Im Grunde genommen ist das Konzept zu $map auf eine Anordnung und von dort aus arbeiten:

db.collection.aggregate([ 
    { "$project": { 
    "_id": 0, 
    "user": { "$map": { 
     "input": ["A","B"], 
     "as": "el", 
     "in": { 
     "$cond": { 
      "if": { "$eq": [ "$$el", "A" ] }, 
      "then": "$user1", 
      "else": "$user2" 
     } 
     } 
    }} 
    }}, 
    { "$unwind": "$user" }, 
    { "$group": { 
    "_id": "$user", 
    "count": { "$sum": 1 } 
    }} 
]) 
0
Let us take an example and go through 

db.users_data.find(); 
{ 
    "_id" : 1, 
    "user1" : "a", 
    "user2" : "aa", 
    "status" : "NEW", 
    "createdDate" : ISODate("2016-05-03T08:52:32.434Z") 
}, 
{ 
    "_id" : 2, 
    "user1" : "a", 
    "user2" : "ab", 
    "status" : "NEW", 
    "createdDate" : ISODate("2016-05-03T09:52:32.434Z") 
}, 
{ 
    "_id" : 3, 
    "user1" : "b", 
    "user2" : "aa", 
    "status" : "NEW", 
    "createdDate" : ISODate("2016-05-03T10:52:32.434Z") 
}, 
{ 
    "_id" : 4, 
    "user1" : "b", 
    "user2" : "ab", 
    "status" : "NEW", 
    "createdDate" : ISODate("2016-05-03T10:52:32.434Z") 
}, 
{ 
    "_id" : 5, 
    "user1" : "a", 
    "user2" : "aa", 
    "status" : "OLD", 
    "createdDate" : ISODate("2015-05-03T08:52:32.434Z") 
}, 
{ 
    "_id" : 6, 
    "user1" : "a", 
    "user2" : "ab", 
    "status" : "OLD", 
    "createdDate" : ISODate("2015-05-03T08:52:32.434Z") 
}, 
Then 
db.users_data.aggregate([ 
     {"$group" : {_id:{user1:"$user1",user2:"$user2"}, count:{$sum:1}}} ]) 
    ]) 
will give the resuls as 
{ "_id" : { "user1" : "a", "user2" : "aa" }, "count" : 2} 
{ "_id" : { "user1" : "a", "user2" : "ab" }, "count" : 2} 
{ "_id" : { "user1" : "b", "user2" : "aa" }, "count" : 1} 
{ "_id" : { "user1" : "b", "user2" : "ab" }, "count" : 1} 

Thus grouping by multiple ids are possible 
Now one more variation 
db.users_data.aggregate([ 
     {"$group" : {_id:{user1:"$user1",user2:"$user2",status:"$status"}, count:{$sum:1}}} ]) 
    ]) 

will give the resuls as 
{ "_id" : { "user1" : "a", "user2" : "aa","status":"NEW" }, "count" : 1} 
{ "_id" : { "user1" : "a", "user2" : "ab","status":"NEW" }, "count" : 1} 
{ "_id" : { "user1" : "b", "user2" : "aa","status":"NEW" }, "count" : 1} 
{ "_id" : { "user1" : "b", "user2" : "ab","status":"NEW" }, "count" : 1} 
{ "_id" : { "user1" : "a", "user2" : "aa","status":"OLD" }, "count" : 1} 
{ "_id" : { "user1" : "a", "user2" : "ab","status":"OLD" }, "count" : 1} 

Hope that helps 

Glückliche Programmierung

Verwandte Themen