MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Agregar dados mongo php


A estrutura de dados aqui não é uma boa implementação, há muitos problemas com a forma como ela é estruturada e é completamente inadequada para agregação. Os principais problemas aqui são:

  • Sua estrutura na verdade não usa nenhum array, agora não

  • Todos os nomes de chave específicos são um problema real, e isso pode ser evitado.

Como tal, a única maneira de percorrer esse tipo de estrutura é usando JavaScript com mapReduce.

Definindo um mapeador:
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]
          );
    }
  }

};

Então, o que isso está fazendo é percorrer cada uma das entradas das versões e também por tudo no conteúdo. A chave é emitida para cada uma das chaves de conteúdo desejadas, bem como pela chave "chairtype". E o valor é esse valor correspondente.

E então um redutor:
var reducer = function (key,values) {

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

};

Que é apenas uma maneira simples de produzir uma média de todos os valores que chegam para o mapeador com a mesma chave.

Então, embora isso deva funcionar bem, o que você deve fazer é mudar sua estrutura. Então, de fato, se você tivesse algo assim:
{
    "_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 }
    ]
}

Ou geralmente mais ou menos dessa forma, a operação de agregação se torna muito simples:
db.collection.aggregate([
    { "$unwind": "$content" },
    { "$group": {
       "_id": {
           "chairtype": "$chairtype",
           "key": "$content.key"
       },
       "average": { "$avg": "$content.value" }
    }}
])

Ou qualquer outra variação disso é necessária, mas agora é possível alterando a estrutura.

Portanto, sem que o documento seja estruturado de maneira diferente, você precisará usar mapReduce para fazer isso.