2016-06-15 27 views
0

Ich habe eine Abfolge von Ereignissen zu wiederholen, die so geht:Esper Zählen von Ereignissen in Muster

  1. Ereignis A startet die Sequenz
  • Mehrere Events B passieren
  • Ereignis C stoppt die Sequenz

    Ich tat das mit einem Muster [jedes A -> (B bis C)], es scheint richtig zu sein (was denkst du?). Aber ich kämpfe darum, Informationen aus den B-Ereignissen, die in der Sequenz entstanden sind, zu sammeln und zu sammeln. Ich möchte einfach eine Zählung und vielleicht ein paar AVGs haben, aber nichts scheint zu funktionieren (Beispiel 1 gibt 1 zurück, Beispiel 2 gibt 0 zurück und Beispiel 3 gibt null zurück, auch wenn meine B-Ereignisse vorhanden sind).

    insert into CreateMeasurement 
    select 
        C.source   as source, 
        "carDrivingAnalyse" as type, 
        C.time    as time, 
        { 
         "example1", count(*), 
         "example2", count(B), 
         "example3", B.countOf() 
        } as fragments 
    
    from pattern [ 
        every A = EventCreated(
         type = "Ignition", 
         getString(A, "Ignition.status") = "ON") 
    
        -> (
         B = EventCreated(
          type = "DrivingEvent", 
          source = A.source, 
          getString(B, "DrivingEvent.prop1") = getString(A, "Ignition.prop1"), 
          getNumber(B, "DrivingEvent.prop2") = getNumber(A, "Ignition.prop2")) 
    
         until C = EventCreated(
          type = "Ignition", 
          getString(C, "Ignition.status") = "OFF", 
          source = A.source, 
          getString(C, "Ignition.prop1") = getString(A, "Ignition.prop1"), 
          getNumber(C, "Ignition.prop2") = getNumber(A, "Ignition.prop2")) 
        ) 
    ] 
    
  • Antwort

    0

    würde ich einen anderen Ansatz für diesen Anwendungsfall wählen und einen Kontext anstelle eines Musters verwenden:

    create context EventContext 
        context PartionBySource 
        partition by event.source.value from EventCreated, 
        context ContextBorders 
        initiated by EventCreated(type="EventA") as startEvent 
        terminated by EventCreated(event.type="EventC"); 
    

    Es ist schon ein komplexer Zusammenhang, weil es zwei verschachtelten Kontexten verwendet. Das ist einige grundlegende Abdeckung von Kontexten in den Cumulocity docs (http://cumulocity.com/guides/event-language/advanced/#contexts), aber für diese erweiterte Nutzung würde ich die ausführlichere Esper Dokumentation http://www.espertech.com/esper/release-5.3.0/esper-reference/html/context.html

    Zusammenfassend empfehlen diesem Zusammenhang Folgendes aus:

    auf dem EventCreated Basierend es streamen Partitionieren Sie die Ereignisse zuerst nach ihrem Quellgerät. Es wird jedes Mal eine neue Kontextpartition erstellt, wenn ein EventA vorhanden ist (nur wenn momentan keine Kontextpartition für dieses Gerät vorhanden ist). Mit dem Eintreffen eines EventCs wird die Context-Partition für dieses Gerät beendet.

    Jetzt können Sie nutzen dabei zum Beispiel so machen:

    context EventContext 
    select 
        count(*) as count, 
        avg(getNumber(e, "speed")) as speed 
    from EventCreated e 
    where e.event.type = "EventB" 
    output last when terminated; 
    

    Diese Anweisung verwendet den Kontext. Es gibt das Ergebnis in dem Moment aus, in dem die Kontextpartition endet (also wenn ein EventC ankommt). Es gibt nur das letzte Ereignis aus (ohne das letzte Schlüsselwort gibt es hier jedes Ereignis aus, das empfangen wurde, während die Partition aktiv war). In diesem Beispiel gibt es die Anzahl der Ereignisse aus, die während der Existenz der Kontextpartition empfangen wurden, und den Durchschnittswert des "speed" -Fragments in EventB.

    Beachten Sie, dass hier keine Quellenfilterung durchgeführt werden muss, da der Kontext die Ereignisse von EventCreated bereits nach Quelle partitioniert.

    +0

    Danke für Ihre Antwort, ich lese die ESPER-Dokumentation und ich versuche, den Kontext zu schreiben, aber ich habe bereits Probleme, mein Muster zu übersetzen.Ich habe mein Beispiel vereinfacht, indem ich sagte, Ereignisse B und C müssten dieselbe Quelle wie A haben, aber tatsächlich haben sie mehr Eigenschaften zu überprüfen (ich habe meinen ursprünglichen Beitrag bearbeitet) und im Moment kann ich den getString/getNumber nicht replizieren funktioniert in meinem Kontext. –

    +0

    Und was ist mit bedingter Zählung? Etwas wie "e.countOf (event -> getNumber (event," c8y_HarshBehavior.speed ")> 100)" außer das funktioniert nicht. –

    +0

    Ich würde die getNumber (Ereignis, "c8y_HarshBehavior.speed")> 100 auf die Where-Klausel – TyrManuZ

    0

    Ich bin kein Experte, aber "count ()" gibt nie "null" zurück. Ihre Beobachtung ist in dieser Hinsicht wahrscheinlich falsch. Die "count ()" ist eine Aggregationsfunktion, die die Anzahl der Vorkommen von was auch immer in den Aus-Klauseln zählt. Bei Mustern zählt es die Anzahl der Musterübereinstimmungen.

    Der "count (B)" zählt die Anzahl der (verschiedenen) Nicht-Null-Werte im Ausdruck, siehe doc. Das gibt auch nicht "null" zurück.

    Das "example3" ist, was Sie wollen, stellen Sie nur sicher, dass tatsächlich mehrere B-Ereignisse vor C-Ereignissen gemäß Ihren Testdaten ankommen.

    +0

    Mein Fehler, Sie haben recht, Beispiel 1 (count (*)) gibt logisch 1 zurück, da das gesamte Muster einmal übereinstimmt. Beispiel 2 (count (B)) gibt 0 zurück und Beispiel 3 (B.countOf()) gibt null zurück, genauso wie keine Ereignisse B erstellt wurden. Es ist jedoch nicht der Fall, es gab Ereignisse B. –

    +0

    Vereinfachen Sie die Anweisung und veröffentlichen Sie ein Beispiel, das das EPL-Tool hier verwendet. Der EPL-Tool-Link lautet http://esper-epl-tryout.appspot.com/epltryout/mainform.html – user3613754