sql >> Databasteknik >  >> NoSQL >> MongoDB

Aggregerad mongo-data php

Datastrukturen här är ingen bra implementering, det finns massor av problem med hur detta är uppbyggt och det är helt olämpligt för aggregering. De största problemen här är:

  • Din struktur använder faktiskt inga arrayer, just nu gör den inte det

  • Alla de specifika nyckelnamnen är ett verkligt problem, och detta kan undvikas.

Som sådan är det enda sättet att gå igenom denna typ av struktur att använda JavaScript med mapReduce.

Definiera en kartläggare:

var mapper = function () {

  for ( var n in this.versions ) {
    for ( var k in this.versions[n].content ) {
      if (
        ( k != 'confirmed' ) ||
        ( k != 'visited' ) )
          emit(
            {
              type: this.chairtype,
              key: k
            },
            this.versions[n].content[k]
          );
    }
  }

};

Så vad detta gör är att cykla igenom var och en av versionsposterna och sedan också genom allt om innehåll. Nyckeln sänds ut för var och en av innehållsnycklarna du vill ha samt av "chairtype"-tangenten. Och värdet är det matchande värdet.

Och så en reducering:

var reducer = function (key,values) {

    return ( Array.sum( values ) != 0 ) 
        ? Array.sum( values ) / values.length : 0;

};

Vilket bara är ett enkelt sätt att producera ett medelvärde från alla värden som kommer in för mapparen med samma nyckel.

Så även om det borde fungera bra, är det du bör göra att ändra din struktur. Så faktiskt om du hade något sånt här:

{
    "_id": ObjectId("52b85dfa32b6249513f15897"),
    "parent": "47de3176-bbc3-44e0-8063-8920ac56fdc8",
    "type": "chair",
    "chairtype": "E",
    "content": [
        { "key": "atkswlntfd", "value": 0, "version": 0 },
        { "key": "auwbsjqzir", "value": 0, "version": 0 },
        { "key": "avqrnjzbgd", "value": 0, "version": 0 }
    ]
}

Eller generellt mer eller mindre i den formen blir aggregeringsoperationen väldigt enkel:

db.collection.aggregate([
    { "$unwind": "$content" },
    { "$group": {
       "_id": {
           "chairtype": "$chairtype",
           "key": "$content.key"
       },
       "average": { "$avg": "$content.value" }
    }}
])

Eller vilken annan variant av detta som krävs, men nu är det möjligt genom att ändra strukturen.

Så utan att dokumentet är strukturerat annorlunda måste du använda mapReduce för att göra detta.




  1. Mongodb:db.collection.copyTo() och eval() har fasats ut. Vilka är alternativen?

  2. MongoDB Hur får vi alla AKTUELLA öppna markörer och de frågor de kör?

  3. Hur konverterar man mongo ObjectId .toString utan att inkludera 'ObjectId()'-omslaget -- bara värdet?

  4. Problem med PUT-begäran med Node.js (express), Angular och MongoDB