I've got an esper query for pulling market data. It looks like
select * from L1Quote(Symbol='MSFT')
This will fire when ever a new quote occurs. I require a first quote/event to do some initial setup. This is no problem for symbols where events/quotes fire every second but for some symbols you won't get a new quote event for a minute.
Working under the assumption that there have been quote events before this expressions is setup.
Is there a way to force output when the expression is first parsed? ie is there a way to say, give me the last event when the expression starts?
You just need to create a window to store the latest quote and then query against it.
In you Esper EPL:
//the L1Quote event definition
create schema L1Quote(Symbol string, ...)
//create a window with the same definition as L1Quote and it retain the latest event by Symbol
create window L1Quotes.std:unique(Symbol) as select * from L1Quote
//insert all incoming quotes into the window we created
insert into L1Quotes select * from L1Quote
Your client will need to both query the window and subscribe to it:
//subscribe to quote updates
EPStatement statement = epAdmin.createEPL("select * from L1Quotes(Symbol='MSFT')");
statement.addListener([my listener]);
//get the latest quote
epEngine.executeQuery("select * from L1Quotes(Symbol='MSFT')");
Esper does not retain old events in memory (unless your EPL specifies so using a data window or pattern). Therefore it does not have past events given the query you provided.
Related
I want to build a CEP-Engine which is dynamic so you can add different event streams. As soon as a new stream is added, Esper should be able to read all the properties of the stream and put it into a list, for example. (For example integer id, long temperature, date timestamp etc.)
Is this possible in Esper?
Would be very grateful for any help
In order to add a stream at runtime you can use create-schema.
create schema MyStream(id int, ...)
For a stream that accepts events that an application sends using EPEventServive#sendEvent you should add the bus and public annotation (or set the equivalent compiler flags).
#public #buseventtype create schema MyStream(id int, ...)
You can now use this stream.
select * from MyStream
You can attach a listener and have it do some logic.
The Esper examples have a lot of detail. The create-schema is used in the "runtimeconfig" example.
Thank you for answering. I'm afraid I didn't make myself clear. I want to be able to add event streams where I don't know beforehand what kind of properties the events have. So I don't know before if there is an integer ID or if there is a date timestamp and which payload might be there. As soon as I add such an unknown event, Esper should examine the stream and return the contained properties of the stream to me.
I want to be able to add event streams where I don't know beforehand what kind of properties the events have. So I don't know before if there is an integer ID or if there is a date timestamp and which payload might be there. As soon as I add such an unknown event, Esper should examine the stream and return the contained properties of the stream to me.
Thank you very much. That actually helps me a lot. But a function which returns all property names directly does not exist, does it? So I would have to use dynamic parameters (trial and error) until I know which ones exist in the eventstream.
Thank you for your help :)
See similar to Add Sensorevents to CEP Engine and get a list of all properties
In the case that you don't have some or all of the properties, you can add the stream without any properties or with those properties that you know that the events have. Here is how to add a stream where you don't know any properties in advance:
#public #buseventtype create schema MyStream()
You can now use EPEventServive#sendEvent to send events.
You can use this stream in various ways. You can simply select the event.
select * from MyStream
Or you can use the dynamic property names, those with a '?' questionmark appended to them. This can refer to properties that may or may not exist.
select id? as id from MyStream
The "id?" returns an Object-type value. You can use "cast" to make it, for instance, a double-type value to total up.
select id? as id, sum(cast(someNumericProperty?, double)) as total from MyStream where
When the property doesn't exist the "?" expression returns null. There is an "exists" function that returns true when the parameter that is a dynamic property exists.
I don't think the Esper runtime actually knows about any dynamic property until the EPL attempts to use that dynamic property. The runtime doesn't inspect any event for actual properties.
You can add your own user-defined function that determines what the property names may be for your specific event underlying. So when the underlying is a java.util.Map the user-defined function can return "event.keySet()".
I'd like to pass the Unix timestamp to a hit level eVar in DTM. I would assume I could pass some Javascript like this:
function() {
var now = new Date();
return now.getTime();
}
However, I am not sure where to pass it in DTM. Would this be passed in the "Customize Page Code" editor in the Tool Settings or somewhere else?
You can create a Data Element of type Custom Code. Name it something like current_timestamp or whatever. The code should not be wrapped in the function declaration syntax (DTM already wraps it in a function callback internally). So just put the following in the code box:
var now = new Date();
return now.getTime();
Then in your Adobe Analytics Tool Config (for global variables), or within a Page Load, Event Based, or Direct Call Rule, within the Adobe Analytics Config section. choose which eVar you want to set, and for the value, put %current_timestamp% (or whatever you named it, using % at start/end of it. You should see it show up in a dropdown as you start typing % in the value field).
Alternatively, if you want to assign the eVar in a custom code box in one of those locations, you can use the following javascript syntax e.g (assume eVar1 in example).
s.eVar1 = _satellite.getVar('current_timestamp');
Note that with this syntax, you do not wrap the data element name with %
One last note. This is client-side code, so the timestamp will be based on the user's browser's timezone settings. So for example, a visitor from the US and another visitor from China both visiting a page physically at the same time (server request at the same time), will show two different timestamps because they are in two different timezones.
This makes for some misleading data in reports, so make sure you break it down by other geo based dimensions, or do some extra math in your Data Element to convert the timestamp to a single timezone (e.g. convert it to EST). In practice, most people will pick whatever timezone their office is located in, or else what their server's timezone is set to.
Currently I'm using Eventstore (by Greg Young) for my company project. In my read model, I store the processed event ids, not the event name. How can I find the event in Eventstore using its Id?
I don't think this is possible currently. I think you have two choices:
in your read model store the stream and index, or the commit/prepare position of the event and then read the event from either the $all stream using the commit/prepare position or from the stream it was written to using the stream and index. This is probably the simplest.
Or create a projection in event store which indexes the events by their id and reprojects into a stream called, say, eventid-{event.id} then you can read directly from this stream.
The second is backwards compatible with your current read model, but I'm not sure is the right thing to do, as projections cause write amplification, and you probably need to make sure you exclude system events from being projected.
You can query the event using the following URL path. This will return the event and the last 20 events before it
{youreventstoredomain}:2113/web/index.html#/streams/$ce-{streamname}/{eventnumber}/backward/20
If my database structure is like this:
and I have this:
ref = Database.database().reference().child(passUserID)
ref?.child("wins").updateChildValues("wins": numerator)
where numerator = (games played beforehand) + (games played after logging in), for the second statement it is giving me an error in the expression that I don't know how to fix.
Also if I try to do this instead:
ref?.child("wins").setValue(numerator)
it messes up my data bad and gives a bad instruction error.
The updateChildValues method takes a Dictionary. So you just need to call the method with a dictionary containing the key-value pairs you want to update, i.e.
ref = Database.database().reference().child(passUserID)
ref?.updateChildValues(["wins": numerator])
For more on how to read/write data to firebase realtime database, refer to: https://firebase.google.com/docs/database/ios/read-and-write
If you use .setValue triggers only in the beginning. Instead of .setValue use updateChildValues(.values/.childAdded/.childRemoved etc..) to update the values inside your tree. It will be executed whenever changes occurs to your node.
How to update particular value of child in Firebase DB