그룹 및 적용
이 항목의 예에서는 LINQ "그룹화" 기능을 사용하여 이벤트를 이벤트 그룹으로 분할하는 방법을 보여 줍니다. 각 이벤트 그룹이 개별적으로 계산되도록 그룹에 대해 집계 및 기타 연산을 수행할 수 있습니다. 각 그룹에 적용되는 연산 집합을 적용 분기라고 합니다. 적용 분기를 단일 그룹 및 적용 문 내에 암시적으로 제공할 수도 있고, 보다 복잡한 하위 쿼리가 포함된 경우에는 별도의 LINQ 문으로 제공할 수도 있습니다. 적용 분기가 그룹 및 적용 구문 내에 닫혀 있어 그룹화된 스트림을 그룹화 외부의 스트림에 조인할 수 없습니다.
예
다음 예에서는 지정된 modulo 함수를 기준으로 이벤트를 그룹화합니다. 그런 다음 각 그룹에 스냅숏 창을 적용하고 각 그룹의 페이로드 열 평균을 별도로 계산합니다. 즉, 적용 분기는 창과 집계로 구성됩니다.
// 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) };
위의 예에서는 단일 페이로드 필드가 포함된 스트림이 생성됩니다. 각 스냅숏 창 내에는 그룹별로 j 필드의 평균이 포함됩니다.
또한 다음 예와 같이 "group by" 절에서 원본 유형의 프로젝션을 그룹화할 수 있습니다.
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)
};
일반적으로는 집계 결과를 개별 그룹에 연결할 수 있도록 그룹화 키를 유지해야 합니다. 다음 예에서는 그룹화 키를 검색하는 방법을 보여 줍니다.
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 };
입력 스트림에서 각 고유 키를 조합하면 개별 그룹이 생성되도록 여러 키를 그룹화할 수 있습니다. 이 경우 그룹화 키가 익명 형식 정의에 포함되어 있어야 최종 프로젝션에서 명시적으로 검색할 수 있습니다. 모든 그룹화 필드를 참조해야 합니다. 다음 예에서는 두 이벤트 페이로드 필드를 기준으로 이벤트를 그룹화한 다음 그룹 중 하나에 새 키 이름을 지정합니다.
// 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 };
아래 예와 같이 적용 분기는 일련의 작업을 포함하여 보다 복잡해질 수 있습니다.
// 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 };
다음 예에서는 여러 측정기의 데이터를 포함하는 전원 측정기 판독값의 스트림이 가정됩니다. 이 예에서는 각 판독값에 동일한 측정기에 대해 마지막 10분을 초과하는 평균값 주석을 추가합니다. 먼저 쿼리는 들어오는 데이터를 측정기 ID로 그룹화합니다. 이러한 각 그룹에서 10분을 초과하는 평균값이 계산되어 원래 측정기 이벤트에 조인됩니다.
// 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 };
위에서 언급한 대로 적용 분기를 나타내는 함수는 applyIn을 제외한 다른 들어오는 스트림을 통합할 수 없습니다.