evently-cloud / cli

Evently Command-Line Interface
Apache License 2.0
1 stars 0 forks source link

selector:filter event approach #44

Closed evert closed 1 year ago

evert commented 1 year ago

The filter event is a bit trickier than `selector:replay', due to all the nesting.

Some ideas for approaching this.

  1. A --filter-meta and --filter-data argument that take JSON objects. This might look a bit like this:
evently selector:filter \
  --filter-data  '"thermostat": {
      "🌡️-measured": "$.tempInC ? (@ < 21)"
      "🌡️-offline": "$.tempInC ? (@ === true)"
    }'

(Bringing in JSON5 for this might be desirable so the parser is a bit more forgiving with quotes and commas.

  1. Come up with a new syntax
evently selector:filter \
  --filter-data thermostat:🌡️-measured:"$.tempInC ? (@ < 21)" \
  --filter-data thermostat:🌡️-offline": "$.tempInC ? (@ === true)"

I'd say both are probably not ideal and hard to hand-write.. When you think about it's 3 different syntaxes to (shell arguments, JSON maybe and JSONPath). I'm curious if you have any thoughts or alternative ideas.

evert commented 1 year ago

We could also try to do something with positional arguments:

evently selector:filter \
  thermostat 🌡️-measured "$.tempInC ? (@ < 21)" \
  thermostat 🌡️-offline "$.tempInC ? (@ === true)"
mattbishop commented 1 year ago

I like the idea of JSON5 to reduce quotes. I would expect people to use it to test their query to see if they got it right, moreso than trying to construct a large query.

evently selector:filter --data thermostat:🌡️-measured:"$.tempInC ? (@ < 21)"

evert commented 1 year ago

So the example you copy pasted is the 'non-JSON5' version of this:

evently selector:filter --data thermostat:🌡️-measured:"$.tempInC ? (@ < 21)"

Regardless, if you prefer this I'll take that approach. The way I would parse this would be by splitting on the first two colons, and assume the remainder is JSONPath.

Note though that this will not easily support colons inside the entity or event name, unless I come up with an escape mechanism. So if the entity was called thermostat:livingroom we would currently have a problem.

If we wanted to support a colon there, two options are to support URL / percent escaping or a double-backslash:

evently selector:filter --data thermostat%3Alivingroom:🌡️-measured:"$.tempInC ? (@ < 21)"
# or
evently selector:filter --data thermostat\\:livingroom:🌡️-measured:"$.tempInC ? (@ < 21)"
# The two backslashes are needed, because the shell also has escaping

For my initial approach I won't support colons, but let me know if this is important, if or you want the JSON5 format instead of this:

evently selector:filter \
  --filter-data  '"thermostat": {
      "🌡️-measured": "$.tempInC ? (@ < 21)"
      "🌡️-offline": "$.tempInC ? (@ === true)"
    }'

Also just in case you were wondering, the reason I used --data instead of --data is because I try to pick globally unique parameters for concepts. I assume you prefer --data so I'll use that regardless.