web-dev-qa-db-fra.com

$ dérouler un objet dans un framework d'agrégation

Dans le cadre d'agrégation MongoDB, j'espérais utiliser l'opérateur $ undind sur un objet (par exemple, une collection JSON). Ne semble-t-il pas que c'est possible , existe-t-il une solution de contournement? Est-il prévu de mettre cela en œuvre?

Par exemple, prenez la collection d'articles à partir de l'agrégation documentation . Supposons qu'il existe un champ supplémentaire "ratings" qui est une carte de l'utilisateur -> rating. Pourriez-vous calculer la note moyenne pour chaque utilisateur? 

Autre que cela, je suis assez satisfait du cadre d'agrégation. 

Mise à jour: voici une version simplifiée de ma collection JSON par demande. Je stocke des données génomiques. Je ne peux pas vraiment transformer un génotype en tableau, car la recherche la plus courante consiste à obtenir le génotype d'une personne aléatoire. 

variants: [

    {
        name: 'variant1', 
        genotypes: {

            person1: 2,
            person2: 5,
            person3: 7,

        }
    }, 

    {
        name: 'variant2', 
        genotypes: {

            person1: 3,
            person2: 3,
            person3: 2,

        }
    }

]
28
Brett Thomas

Depuis la version 3.4.4, vous pouvez transformer un objet en tableau avec $ objectToArray

Voir: https://docs.mongodb.com/manual/reference/operator/aggregation/objectToArray/

6
Adrian

C’est une vieille question, mais j’ai trouvé par hasard quelques informations utiles par essais et erreurs. 

Il est en fait possible de décompresser sur une valeur fictive en trompant l’analyseur de la manière suivante:

db.Opportunity.aggregate(
  { $project: {
        Field1: 1, Field2: 1, Field3: 1,
        DummyUnwindField: { $ifNull: [null, [1.0]] }
    }
  },
  { $unwind: "$DummyUnwindField" }
);

Cela produira 1 ligne par document, que la valeur existe ou non. Vous pourrez peut-être bricoler avec cela pour générer les résultats souhaités. J'avais espéré combiner cela avec plusieurs $ dérouler pour (un peu comme emit () dans map/réduire), mais hélas, le dernier $ dérouler gagne ou ils se combinent comme une intersection plutôt que l'union qui rend impossible d'obtenir les résultats cherchais. Je suis malheureusement déçu de la fonctionnalité du cadre global, car elle ne correspond pas au cas d'utilisation pour lequel j'espérais l'utiliser (et ressemble étrangement à de nombreuses questions sur StackOverflow dans ce domaine) - résultats de commande basés sur la correspondance taux. Améliorer la qualité de la carte pour réduire les performances aurait rendu inutile l’intégralité de cette fonctionnalité.

0
saarp

C'est ce que j'ai trouvé et étendu.

Permet de créer une base de données expérimentale en mongo

db.copyDatabase('livedb' , 'experimentdb')

Now Utilisez experimentdb & convert Array comme objet dans votre collection de tests

db.getCollection('experimentcollection').find({}).forEach(function(e){
    if(e.store){
        e.ratings = [e.ratings]; //Objects name to be converted to array eg:ratings
        db.experimentcollection.save(e);
    }
})

Quelques codes nerdy js pour convertir json en objet plat

var flatArray = [];

var data = db.experimentcollection.find().toArray();

for (var index = 0; index < data.length; index++) {

  var flatObject = {};

  for (var prop in data[index]) {

    var value = data[index][prop];

    if (Array.isArray(value) && prop === 'ratings') {
      for (var i = 0; i < value.length; i++) {
        for (var inProp in value[i]) {
          flatObject[inProp] = value[i][inProp];
        }
      }
    }else{
        flatObject[prop] = value;
    }
  }
  flatArray.Push(flatObject);
}

printjson(flatArray);
0
vijay