sql >> Database teknologi >  >> NoSQL >> MongoDB

$vind et objekt i aggregeringsramme

Det er ikke muligt at udføre den type beregning, du beskriver med aggregeringsrammen - og det er ikke fordi der ikke er nogen $unwind metode til ikke-arrays. Selvom person:value-objekterne var dokumenter i et array, $unwind ville ikke hjælpe.

"Grupper efter" funktionaliteten (hvad enten det er i MongoDB eller i en hvilken som helst relationsdatabase) udføres på værdien af ​​et felt eller en kolonne. Vi grupperer efter værdi af felt og sum/gennemsnit/etc baseret på værdien af ​​et andet felt.

Simpelt eksempel er en variant af det, du foreslår, vurderingsfelt tilføjet til eksempelartikelsamlingen, men ikke som et kort fra bruger til vurdering, men som et array som dette:

{ title : title of article", ...
  ratings: [
         { voter: "user1", score: 5 },
         { voter: "user2", score: 8 },
         { voter: "user3", score: 7 }
  ]
}

Nu kan du samle dette med:

[ {$unwind: "$ratings"},
  {$group : {_id : "$ratings.voter", averageScore: {$avg:"$ratings.score"} } } 
]

Men dette eksempel struktureret, som du beskriver det, ville se sådan ud:

{ title : title of article", ...
  ratings: {
         user1: 5,
         user2: 8,
         user3: 7
  }
}

eller endda dette:

{ title : title of article", ...
  ratings: [
         { user1: 5 },
         { user2: 8 },
         { user3: 7 }
  ]
}

Også selvom du kunne $unwind dette er der ikke noget at samle på her. Medmindre du kender den komplette liste over alle mulige nøgler (brugere), kan du ikke gøre meget med dette. [*]

Et analogt relationelt DB-skema til det, du har, ville være:

CREATE TABLE T (
   user1: integer,
   user2: integer,
   user3: integer
   ...
);

Det er ikke, hvad der ville blive gjort, i stedet ville vi gøre dette:

CREATE TABLE T (
   username: varchar(32),
   score: integer
);

og nu samler vi ved hjælp af SQL:

select username, avg(score) from T group by username;

Der er en forbedringsanmodning til MongoDB, som muligvis giver dig mulighed for at gøre dette i aggregeringsrammen i fremtiden - evnen til at projicere værdier til nøgler til omvendt. I mellemtiden er der altid kort/reducer.

[*] Der er en kompliceret måde at gøre dette på, hvis du kender alle unikke nøgler (du kan finde alle unikke nøgler med en metode, der ligner denne), men hvis du kender alle nøglerne, kan du lige så godt bare køre en sekvens af forespørgsler fra form db.articles.find({"ratings.user1":{$exists:true}},{_id:0,"ratings.user1":1}) for hver brugerX, som vil returnere alle deres vurderinger, og du kan summere og gennemsnittet dem ganske enkelt i stedet for at lave en meget kompleks projektion, som aggregeringsrammen ville kræve.



  1. MongoDB 2.1 Aggregate Framework Sum af matrixelementer, der matcher et navn

  2. MongoDB $type Query Operator

  3. Hvad er fordelene ved at bruge en skemafri database som MongoDB sammenlignet med en relationel database?

  4. Forespørgsel efter dokumenter, hvor matrixstørrelsen er større end 1