Combinaciones

Los ejemplos de este tema muestran cómo establecer correlaciones entre valores de flujos distintos usando una operación de combinación. Una operación de combinación compara cada evento de un flujo de entrada con otro evento de uno o varios flujos de entrada de tipo CepStream. Si sus intervalos de tiempo válidos se superponen y se mantiene la condición de combinación, la operación produce un evento de salida.

Tal como es habitual en LINQ, la condición de combinación se puede especificar como un predicado de combinación de igualdad entre dos flujos de entrada mediante la cláusula on … equals o mediante una cláusula where que pueda hacer referencia a dos o más flujos de entrada. El predicado de combinación de igualdad puede comparar campos individuales, como where x.a equals y.a, o claves compuestas, por ejemplo where {x.a, x.b} equals {y.a, y.b} o where x equals y.

Ejemplos

Combinación interna

Una operación de combinación interna devuelve todos los eventos de dos o más flujos de entrada cuando el predicado de combinación entre ellos se evalúa como TRUE. Un predicado de combinación es una expresión que compara los campos de carga de los flujos de eventos que se combinan. Una combinación interna elimina todos los eventos que no tienen un evento correspondiente en los demás flujos de eventos especificados.

Combinación de igualdad

En el siguiente ejemplo se comparan los eventos del flujo stream1 con los eventos del flujo stream2. Los eventos del flujo que cumplen los criterios de igualdad definidos en la cláusula on (además de superponerse en los intervalos de tiempo de los dos eventos) se combinan y generan un nuevo evento que contiene los campos de carga i y j del evento e1 y el campo j del evento e2.

// Assuming the following input event type for both stream1 and stream2.
public class MyPayload
{
    public int i;
    public float j;
}

var equiJoin = from e1 in stream1
               join e2 in stream2
               on e1.i equals e2.i
               select new { e1.i, e1.j, e2.j };

El predicado de igualdad permite comparar ambos tipos primitivos y compuestos. Por ejemplo, es posible combinar on {e1i, e1j} equals {e2i, e2j}.

Combinación cruzada

Una operación de combinación cruzada (producto cartesiano) devuelve un flujo de eventos que es la combinación de cada evento del primer flujo con cada evento del segundo flujo, mientras dura la superposición de los intervalos del evento de cada flujo. Se puede usar una expresión de filtro en la cláusula where para limitar los eventos de cada flujo de entrada. Es importante destacar que para dos flujos de entrada una combinación cruzada con una cláusula where que comprueba la igual es equivalente a una combinación de igualdad con la cláusula on ... equals correspondiente. En el caso de los predicados que no son de igualdad o más de dos flujos de entrada, se tiene que usar una combinación cruzada.

En el siguiente ejemplo, los eventos de stream1 con un valor superior a 3 en el campo de carga i se combinan con los eventos de stream2 con un valor inferior a 10 en el campo de carga j.

var crossJoin = from e1 in stream1
                from e2 in stream2
                where e1.i > 3 && e2.j < 10
                select new { e1.i, e2.j };

Left Anti Semi Join

Esta combinación produce un resultado de combinación para cada evento del lado izquierdo solamente si el resultado de la combinación normal está vacío para cada momento. Esta operación es útil para detectar huecos sin ningún evento.

var leftAntiSemiJoin = from left in stream1 
                       where (from right in stream2 
                              where left.v == right.v
                              select right).IsEmpty()
                       select left;

En la siguiente ilustración se muestra el resultado de la unión anterior con dos flujos de entrada de ejemplo, suponiendo que la condición de combinación se evalúa como TRUE. También se muestra el resultado de la combinación normal intermedia.

Ejemplo de anti semi join con dos flujos

Combinar múltiples flujos

Se pueden combinar varios flujos en una sola consulta, tal como se muestra en el ejemplo siguiente.

var slopetest = from f in fastSignal
                          from s in slowSignal
                          from r in refSignal
                          select new { alarm = f.avg / s.avg < r.Threshold };