Groupe et application

Les exemples de cette rubrique montrent comment partitionner des événements en groupes d'événements à l'aide de la fonctionnalité LINQ « group by ». Les agrégations et d'autres opérations peuvent être effectuées sur les groupes d'événements, afin que chaque groupe soit calculé séparément. Le jeu d'opérations appliqué à chaque groupe est appelé branche d'application. La branche d'application peut être fournie implicitement comme une instruction LINQ séparée si elle contient une sous-requête plus complexe, ou dans un groupe unique et appliquer l'instruction. Notez que les branches d'application sont fermées au sein du groupe et de la structure d'application. Cela implique, par exemple, qu'il est impossible de joindre le flux de données groupé avec un flux de données n'appartenant pas au groupe.

Exemples

L'exemple suivant regroupe des événements par la fonction modulo spécifiée. Il applique ensuite une fenêtre d'instantané à chaque groupe et calcule la moyenne sur une colonne de charge utile sur chaque groupe séparément. Par conséquent, la branche d'application comprend la fenêtre et l'agrégation.

// Assuming the following input event type for inputStream:
public class MyPayload 
{
    public int i; 
    public float j; 
}

var avgCount = from v in inputStream
               group v by v.i % 4 into eachGroup
               from window in eachGroup.SnapshotWindow(SnapshotWindowOutputPolicy.Clip)
               select new { avgNumber = window.Avg(e => e.j) };

L'exemple précédent a produit un flux de données avec un champ de charge utile unique, contenant la moyenne du champ j dans chaque fenêtre d'instantané et par groupe.

Vous pouvez également grouper une projection du type d'origine dans une clause « group by », comme indiqué dans l'exemple suivant.

var result = from e in source.AlterEventDuration(e => TimeSpan.FromMinutes(10))
                  group new { myVal = e.Value * 10 } by e.SourceId into g
                  from win in g.SnapshotWindow(SnapshotWindowOutputPolicy.Clip)
                  select new
                  {
                      avg = win.Avg(e => e.myVal)
                   };

Habituellement, la clé de regroupement doit être conservée afin que le résultat de l'agrégation puisse être associé au groupe respectif. L'exemple suivant montre comment récupérer la clé de regroupement.

var avgCount = from v in inputStream
               group v by v.i % 4 into eachGroup
               from window in eachGroup.SnapshotWindow(SnapshotWindowOutputPolicy.Clip)
               select new { avgNumber = window.Avg(e => e.number), groupId = eachGroup.Key };

Il est possible d'effectuer un regroupement sur plusieurs clés, afin que chaque combinaison de clé unique dans le flux d'entrée génère un groupe séparé. Dans ce cas, les clés de regroupement doivent être contenues dans une définition de type anonyme afin qu'elles puissent être récupérées explicitement dans la dernière projection. Notez que tous les champs de regroupement doivent être référencés. L'exemple suivant regroupe des événements par deux champs de charge utile de l'événement et affecte un nouveau nom de clé à l'un d'eux.

// Assuming the following input event type for inputStream:
public class MyPayload 
{
    public int section; 
    public string category; 
    public float value; 
}

var avgCount = from v in inputStream
               group v by new { sec = v.section, v.category } into eachGroup
               from window in eachGroup.SnapshotWindow(SnapshotWindowOutputPolicy.Clip)
               select new { avgNumber = window.Avg(e => e.value), section = eachGroup.Key.sec, category = eachGroup.Key.category };

La branche d'application peut être plus complexe et comprendre une série d'opérations, comme indiqué dans l'exemple ci-dessous.

// Assuming the following input event type for inputStream:
public class MyPayload 
{
    public int section; 
    public string category; 
    public float value; 
}

var result = from s in source
                group s by s.section into sg
                from e in
                    (from e in sg
                    group e by e.category into cg
                    from win in cg.TumblingWindow(TimeSpan.FromMinutes(5), HoppingWindowOutputPolicy.ClipToWindowEnd)
                    select new { cat = cg.Key, top = win.Max(e => e.value) })
                select new { sec = sg.Key, e.cat, e.top };

Celui-ci reprend un flux de données comprenant des mesures effectuées sur plusieurs jauges d'alimentation. Chaque mesure est accompagnée de la moyenne d'une même jauge sur les dix dernières minutes. La requête commence par grouper les données entrantes par ID de jauge. Dans chacun de ces groupes, la moyenne sur les dix dernières minutes est calculée, puis associée aux événements de jauge initiaux.

// Assuming the following input event type for sensorStream:
public class MeterReading
{
    public string meterId; 
    public float usage; 
}

var resultB = from s in sensorStream
              group s by s.meterId into g
              from e in
                  (from left in g
                  from right in
                      (from win in g
                          .AlterEventDuration(e => TimeSpan.FromMinutes(10))
                          .SnapshotWindow(SnapshotWindowOutputPolicy.Clip)
                      select new { avg = win.Avg(e => e.usage) })
                  select new { right.avg, left.usage })
              select new { slidingAvg = e.avg, e.usage, g.Key };

Comme indiqué précédemment, la fonction représentant la branche d'application ne peut intégrer aucun autre flux de données entrant, à l'exception d'applyIN.

Voir aussi

Concepts

Concepts du serveur StreamInsight

Utilisation de fenêtres d'événement

Fenêtres d'instantané