Documentation
¶
Overview ¶
Package query is the segmentation backbone: filter events by their properties and break them down (group by) a property. Every report (funnel, retention, trends) gets filtering + breakdown by composing these over the event slice before the deterministic compute — the thing that makes analytics powerful.
Index ¶
- func Apply(events []event.Event, filters []Filter) []event.Event
- func ApplyMode(evs []event.Event, filters []Filter, anyMode bool) []event.Event
- func FirstUnknownProp(events []event.Event, filters []Filter) (string, []string)
- func ScopeUsers(events []event.Event, filters []Filter, anyMode bool) []event.Event
- func StampFirstTouch(events []event.Event, prop string) []event.Event
- func Validate(filters []Filter) error
- type Filter
- type Group
- type Op
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Apply ¶
Apply returns the events matching ALL filters — and enforces the one default scope of the whole query layer: events stamped env=development are EXCLUDED unless the filters explicitly reference "env". Localhost traffic polluting production funnels is the classic silent report-corruptor; asking for dev data stays one filter away (env eq development). Living inside Apply means every surface (HTTP API, MCP, dashboard) inherits the same rule — the agreement test depends on that.
func ApplyMode ¶ added in v0.9.1
ApplyMode is Apply with an any/all switch: all = every filter must match (the default AND), any = at least one must (the OR mode of the dashboard's filter builder). Dev-traffic exclusion applies in both modes, before the user filters.
func FirstUnknownProp ¶ added in v0.9.1
FirstUnknownProp returns the first filter property that uses a POSITIVE operator (eq/contains/gt/lt/in/set/regex — ones that can only match when the property exists) yet appears on NO event, plus a sorted list of the properties that DO exist. This is how a filtered report tells a typo ("plann=pro" → no such property) apart from a genuine empty result, instead of silently returning 0 as if it were the honest answer. Negative operators (neq/notin/notset/notcontains) are skipped: a missing property legitimately satisfies them. Returns ("", nil) when every positive filter is known.
func ScopeUsers ¶ added in v0.9.1
ScopeUsers keeps every event of any user who has at least one event matching the filters — user-level scoping (vs Apply's event-level). Funnels use this so a filter on a user attribute (plan, device) that isn't present on every step event scopes the POPULATION, not the events, and later steps aren't dropped. Empty filters = unchanged.
func StampFirstTouch ¶ added in v0.9.1
StampFirstTouch returns a copy of events where every event of a user carries that user's FIRST-TOUCH value of `prop` (from their earliest event that has it). This lets a funnel/report breakdown segment by an acquisition/user attribute (referrer, device, country) even though the conversion events don't carry it — otherwise the breakdown collapses everyone into "(none)". Referrer values are reduced to their host.
Types ¶
type Group ¶
type Group struct {
Value string `json:"value"`
Events []event.Event `json:"-"`
Count int `json:"count"`
}
Group is one breakdown bucket: a property value and its events.
type Op ¶
type Op string
Op is a filter comparison.
const ( Eq Op = "eq" Neq Op = "neq" Contains Op = "contains" Gt Op = "gt" Lt Op = "lt" In Op = "in" // value is one of a list — expresses OR over one property (source in [hn, twitter]) NotIn Op = "notin" // value is none of a list (or the property is missing) Set Op = "set" // the property exists on the event (value ignored) NotSet Op = "notset" // the property is missing (value ignored) Regex Op = "regex" // value is a Go regexp matched against the stringified property NotContains Op = "ncontains" )