ghost 6.9.1 → 6.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/tryghost-i18n-6.9.3.tgz +0 -0
- package/content/themes/source/package.json +1 -1
- package/core/built/admin/assets/activitypub/activitypub.js +2 -2
- package/core/built/admin/assets/activitypub/{index-C19nEXqT.mjs → index-D-0TWnTq.mjs} +2447 -2443
- package/core/built/admin/assets/activitypub/{index-B29oZuTp.mjs → index-Dz4ykJpN.mjs} +2 -2
- package/core/built/admin/assets/admin-x-settings/{CodeEditorView-C0HG4CwA.mjs → CodeEditorView-C4K2SFCa.mjs} +2 -2
- package/core/built/admin/assets/admin-x-settings/admin-x-settings.js +2 -2
- package/core/built/admin/assets/admin-x-settings/{index-Cjl9AHTm.mjs → index-D1JNSNMf.mjs} +2 -2
- package/core/built/admin/assets/admin-x-settings/{index-DRpMCs_c.mjs → index-DLS4G2Af.mjs} +2 -2
- package/core/built/admin/assets/admin-x-settings/{index-Cz3Y1eRN.mjs → index-jt7mifza.mjs} +23310 -22917
- package/core/built/admin/assets/admin-x-settings/{modals-DXD3MDLp.mjs → modals-Bkrvssih.mjs} +8884 -8879
- package/core/built/admin/assets/{chunk.524.56454d8add89b041f4df.js → chunk.524.6d040cb21c767f0236ae.js} +7 -7
- package/core/built/admin/assets/{chunk.582.a4916bd533becb58fd9c.js → chunk.582.e35aed09ef750c552601.js} +10 -10
- package/core/built/admin/assets/ghost-192beb3c8f2f6e58b70d3aade481ae15.css +1 -0
- package/core/built/admin/assets/{ghost-94d0fbb20e8e880fa9ba144cf26ab050.js → ghost-5fd8d4d5e1ffe4d8405d30f3efba12b7.js} +105 -89
- package/core/built/admin/assets/ghost-dark-e50f4c063ecc977f023e78da2dd67b42.css +1 -0
- package/core/built/admin/assets/posts/posts.js +6745 -6741
- package/core/built/admin/assets/stats/stats.js +16015 -16011
- package/core/built/admin/index.html +4 -4
- package/core/server/data/tinybird/datasources/_mv_hits.datasource +4 -1
- package/core/server/data/tinybird/endpoints/README.md +109 -0
- package/core/server/data/tinybird/endpoints/api_kpis.pipe +2 -23
- package/core/server/data/tinybird/endpoints/api_monitoring_ingestion.pipe +14 -13
- package/core/server/data/tinybird/endpoints/api_monitoring_ingestion_aggregated.pipe +13 -12
- package/core/server/data/tinybird/endpoints/api_top_locations.pipe +0 -19
- package/core/server/data/tinybird/endpoints/api_top_pages.pipe +0 -23
- package/core/server/data/tinybird/endpoints/api_top_sources.pipe +0 -11
- package/core/server/data/tinybird/endpoints/api_top_utm_campaigns.pipe +0 -6
- package/core/server/data/tinybird/endpoints/api_top_utm_contents.pipe +0 -6
- package/core/server/data/tinybird/endpoints/api_top_utm_mediums.pipe +0 -6
- package/core/server/data/tinybird/endpoints/api_top_utm_sources.pipe +0 -6
- package/core/server/data/tinybird/endpoints/api_top_utm_terms.pipe +0 -6
- package/core/server/data/tinybird/pipes/filtered_sessions.pipe +28 -8
- package/core/server/data/tinybird/pipes/mv_hits.pipe +23 -11
- package/core/server/data/tinybird/tests/api_top_pages.yaml +5 -2
- package/core/server/services/email-service/DomainWarmingService.js +47 -9
- package/core/server/services/email-service/DomainWarmingService.ts +62 -11
- package/core/server/services/email-service/EmailServiceWrapper.js +2 -1
- package/core/server/services/member-welcome-emails/jobs/index.js +13 -9
- package/package.json +3 -3
- package/tsconfig.tsbuildinfo +1 -1
- package/yarn.lock +5 -50
- package/components/tryghost-i18n-6.9.1.tgz +0 -0
- package/core/built/admin/assets/ghost-dark-6c9cfa9c364e28c57e5983f68ec6f2fc.css +0 -1
- package/core/built/admin/assets/ghost-f724c1d53f5402f78a2d8cf8beb7c716.css +0 -1
- package/core/built/admin/assets/img/google-docs-1e42cc272fc088da49e4b0ddfb01b006.svg +0 -6
- package/core/built/admin/assets/img/mailchimp-f22b1e130aac764965b9306d7265a6b2.svg +0 -8
- package/core/built/admin/assets/img/patreon-b19a5e6418a72977a16b30039d374d04.svg +0 -7
- package/core/built/admin/assets/img/paypal-38e9448ce7549ea4caf8e7753ae661d6.svg +0 -8
- package/core/built/admin/assets/img/slackicon-406aadea8994ca2ddee9c1d7157208db.png +0 -0
- package/core/built/admin/assets/img/themes/Alto-0dfe76694ed222d6d96fc9c8db979a38.png +0 -0
- package/core/built/admin/assets/img/themes/Bulletin-d66dec818ad0ba2965dd7eb3130c621c.png +0 -0
- package/core/built/admin/assets/img/themes/Casper-9a0ce71df3a1c589c1414ad2aa5b8aeb.png +0 -0
- package/core/built/admin/assets/img/themes/Dawn-302fbfdbc352098a256137159bd83dd8.png +0 -0
- package/core/built/admin/assets/img/themes/Digest-698e78d8e8481daff8ae4a8647528dc9.png +0 -0
- package/core/built/admin/assets/img/themes/Dope-d099dfca697adae16baa76f89520c5b3.png +0 -0
- package/core/built/admin/assets/img/themes/Ease-7075f809892f10c58892e15a57a4aae4.png +0 -0
- package/core/built/admin/assets/img/themes/Edge-1e5e0eec6941d7bdca02cebb66187357.png +0 -0
- package/core/built/admin/assets/img/themes/Edition-10111a2b8458168dcff81b7fb151be70.png +0 -0
- package/core/built/admin/assets/img/themes/Episode-e4c86d1f75ef1d8a77791d7fd519fdd4.png +0 -0
- package/core/built/admin/assets/img/themes/Headline-f70eaf49b9fcae1ddfe3d4496d8be54d.png +0 -0
- package/core/built/admin/assets/img/themes/Journal-07d35b2311501d2738bad1907ba2f7e1.png +0 -0
- package/core/built/admin/assets/img/themes/London-4e042390da16fecef947f3a7001d03db.png +0 -0
- package/core/built/admin/assets/img/themes/Ruby-b896885448e0f28ca62c6dcd56c732aa.png +0 -0
- package/core/built/admin/assets/img/themes/Solo-0292eb9ae0ca7b578cff50824d40cc86.png +0 -0
- package/core/built/admin/assets/img/themes/Source-Magazine-176385eb99561485ce6385598f7599b0.png +0 -0
- package/core/built/admin/assets/img/themes/Source-Newsletter-bb1a8611a326edb78f9ecb8bc1838c81.png +0 -0
- package/core/built/admin/assets/img/themes/Source-f29c6d6abe774ea7d5940a7431069fce.png +0 -0
- package/core/built/admin/assets/img/themes/Taste-a24d2a786900d9caff7e773ca0040991.png +0 -0
- package/core/built/admin/assets/img/themes/Wave-b98fadfd3ed16e8b2e383dd8e8e5dca2.png +0 -0
- package/core/built/admin/assets/img/typeform-9f23f8712d776a7515594676285266f5.svg +0 -7
- package/core/built/admin/assets/img/zero-bounce-ee799eddb1f88e33ab8c462858cbfed9.png +0 -0
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<title>Ghost</title>
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
<meta name="ghost-admin/config/environment" content="%7B%22modulePrefix%22%3A%22ghost-admin%22%2C%22environment%22%3A%22production%22%2C%22cdnUrl%22%3A%22%22%2C%22editorUrl%22%3A%22%22%2C%22rootURL%22%3A%22%22%2C%22locationType%22%3A%22trailing-hash%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%2C%22Array%22%3Atrue%2C%22String%22%3Atrue%2C%22Function%22%3Afalse%7D%2C%22_APPLICATION_TEMPLATE_WRAPPER%22%3Afalse%2C%22_JQUERY_INTEGRATION%22%3Atrue%2C%22_TEMPLATE_ONLY_GLIMMER_COMPONENTS%22%3Atrue%7D%2C%22APP%22%3A%7B%22version%22%3A%226.9%22%2C%22name%22%3A%22ghost-admin%22%7D%2C%22ember-simple-auth%22%3A%7B%7D%2C%22%40sentry%2Fember%22%3A%7B%22disablePerformance%22%3Atrue%2C%22sentry%22%3A%7B%7D%7D%2C%22ember-cli-mirage%22%3A%7B%22usingProxy%22%3Afalse%2C%22useDefaultPassthroughs%22%3Atrue%7D%2C%22exportApplicationGlobal%22%3Afalse%2C%22ember-load%22%3A%7B%22loadingIndicatorClass%22%3A%22ember-load-indicator%22%7D%2C%22editorFilename%22%3A%22koenig-lexical.umd.js%22%2C%22editorHash%22%3A%2237bd1e3e4d%22%2C%22adminXSettingsFilename%22%3A%22admin-x-settings.js%22%2C%22adminXSettingsHash%22%3A%
|
|
9
|
+
<meta name="ghost-admin/config/environment" content="%7B%22modulePrefix%22%3A%22ghost-admin%22%2C%22environment%22%3A%22production%22%2C%22cdnUrl%22%3A%22%22%2C%22editorUrl%22%3A%22%22%2C%22rootURL%22%3A%22%22%2C%22locationType%22%3A%22trailing-hash%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%2C%22Array%22%3Atrue%2C%22String%22%3Atrue%2C%22Function%22%3Afalse%7D%2C%22_APPLICATION_TEMPLATE_WRAPPER%22%3Afalse%2C%22_JQUERY_INTEGRATION%22%3Atrue%2C%22_TEMPLATE_ONLY_GLIMMER_COMPONENTS%22%3Atrue%7D%2C%22APP%22%3A%7B%22version%22%3A%226.9%22%2C%22name%22%3A%22ghost-admin%22%7D%2C%22ember-simple-auth%22%3A%7B%7D%2C%22%40sentry%2Fember%22%3A%7B%22disablePerformance%22%3Atrue%2C%22sentry%22%3A%7B%7D%7D%2C%22ember-cli-mirage%22%3A%7B%22usingProxy%22%3Afalse%2C%22useDefaultPassthroughs%22%3Atrue%7D%2C%22exportApplicationGlobal%22%3Afalse%2C%22ember-load%22%3A%7B%22loadingIndicatorClass%22%3A%22ember-load-indicator%22%7D%2C%22editorFilename%22%3A%22koenig-lexical.umd.js%22%2C%22editorHash%22%3A%2237bd1e3e4d%22%2C%22adminXSettingsFilename%22%3A%22admin-x-settings.js%22%2C%22adminXSettingsHash%22%3A%223d200b447b%22%2C%22activitypubFilename%22%3A%22activitypub.js%22%2C%22activitypubHash%22%3A%2241a8ee70ff%22%2C%22postsFilename%22%3A%22posts.js%22%2C%22postsHash%22%3A%2273ad0a757c%22%2C%22statsFilename%22%3A%22stats.js%22%2C%22statsHash%22%3A%229c456bb0f1%22%2C%22activitypubRemoteConfigUrl%22%3A%22%2F.ghost%2Factivitypub%2Fstable%2Fclient-config%22%7D" />
|
|
10
10
|
|
|
11
11
|
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1, minimal-ui, viewport-fit=cover" />
|
|
12
12
|
<meta name="pinterest" content="nopin" />
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
</style>
|
|
29
29
|
|
|
30
30
|
<link integrity="" rel="stylesheet" href="assets/vendor-0ede59da8efb5e28fa929557f7ff7154.css">
|
|
31
|
-
<link integrity="" rel="stylesheet" href="assets/ghost-
|
|
31
|
+
<link integrity="" rel="stylesheet" href="assets/ghost-192beb3c8f2f6e58b70d3aade481ae15.css" title="light">
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
</head>
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
|
|
50
50
|
<script src="assets/vendor-aed0068cf9b67d042dd23a6343545b7b.js"></script>
|
|
51
51
|
<script src="assets/chunk.397.a720333cfffc99c47e71.js"></script>
|
|
52
|
-
<script src="assets/chunk.524.
|
|
53
|
-
<script src="assets/ghost-
|
|
52
|
+
<script src="assets/chunk.524.6d040cb21c767f0236ae.js"></script>
|
|
53
|
+
<script src="assets/ghost-5fd8d4d5e1ffe4d8405d30f3efba12b7.js"></script>
|
|
54
54
|
</body>
|
|
55
55
|
</html>
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
SCHEMA >
|
|
2
2
|
`site_uuid` LowCardinality(String),
|
|
3
3
|
`timestamp` DateTime,
|
|
4
|
+
`received_at` DateTime64(3),
|
|
5
|
+
`inserted_at` DateTime64(3),
|
|
6
|
+
`ingestion_latency_ms` Int64,
|
|
4
7
|
`action` LowCardinality(String),
|
|
5
8
|
`version` LowCardinality(String),
|
|
6
9
|
`session_id` String,
|
|
@@ -23,4 +26,4 @@ SCHEMA >
|
|
|
23
26
|
|
|
24
27
|
ENGINE "MergeTree"
|
|
25
28
|
ENGINE_PARTITION_KEY "toYYYYMM(timestamp)"
|
|
26
|
-
ENGINE_SORTING_KEY "site_uuid, timestamp, session_id"
|
|
29
|
+
ENGINE_SORTING_KEY "site_uuid, timestamp, session_id"
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Tinybird Analytics Endpoints
|
|
2
|
+
|
|
3
|
+
## Filtering Architecture
|
|
4
|
+
|
|
5
|
+
### Session-Level vs Hit-Level Attributes
|
|
6
|
+
|
|
7
|
+
Ghost analytics distinguishes between two types of attributes:
|
|
8
|
+
|
|
9
|
+
#### Session-Level Attributes
|
|
10
|
+
These are captured from the **first hit** (earliest timestamp) in a session using `argMin(field, timestamp)` in the `mv_session_data` materialized view:
|
|
11
|
+
|
|
12
|
+
- `source` - Referring domain
|
|
13
|
+
- `utm_source` - UTM source parameter
|
|
14
|
+
- `utm_medium` - UTM medium parameter
|
|
15
|
+
- `utm_campaign` - UTM campaign parameter
|
|
16
|
+
- `utm_term` - UTM term parameter
|
|
17
|
+
- `utm_content` - UTM content parameter
|
|
18
|
+
|
|
19
|
+
Session-level attributes represent the **origin** of the session and remain constant throughout the entire session, even if subsequent pageviews have different UTM parameters or come from different sources.
|
|
20
|
+
|
|
21
|
+
#### Hit-Level Attributes
|
|
22
|
+
These can vary across pageviews within a session:
|
|
23
|
+
|
|
24
|
+
- `pathname` - URL path of the page
|
|
25
|
+
- `post_uuid` - UUID of the post/page
|
|
26
|
+
- `member_status` - Member status at time of hit (can change during a session)
|
|
27
|
+
|
|
28
|
+
### How Filtering Works
|
|
29
|
+
|
|
30
|
+
All endpoint filtering is handled through the `filtered_sessions.pipe`, which uses a two-stage approach:
|
|
31
|
+
|
|
32
|
+
**Stage 1: Query Filters (Hit-Level)**
|
|
33
|
+
```sql
|
|
34
|
+
NODE query_filters
|
|
35
|
+
```
|
|
36
|
+
Finds sessions where **at least one hit** matches the hit-level filter criteria (pathname, post_uuid, member_status). A session qualifies if ANY of its pageviews match the specified criteria.
|
|
37
|
+
|
|
38
|
+
**Stage 2: Session Attributes (Session-Level)**
|
|
39
|
+
```sql
|
|
40
|
+
NODE sessions_filtered_by_session_attributes
|
|
41
|
+
```
|
|
42
|
+
Further filters by session-level attributes (source, utm_*) by joining with `mv_session_data`. These filters check attributes from the **first hit only**.
|
|
43
|
+
|
|
44
|
+
**Stage 3: Final Output**
|
|
45
|
+
```sql
|
|
46
|
+
NODE filtered_sessions
|
|
47
|
+
```
|
|
48
|
+
Returns session IDs that match **all** filter criteria (both hit-level and session-level).
|
|
49
|
+
|
|
50
|
+
### Important Behavior: All Hits from Matching Sessions
|
|
51
|
+
|
|
52
|
+
When endpoints join `_mv_hits` with `filtered_sessions`, they return **ALL hits from sessions that match the filter criteria**, not just the specific hits that matched.
|
|
53
|
+
|
|
54
|
+
#### Example: api_top_pages
|
|
55
|
+
|
|
56
|
+
```sql
|
|
57
|
+
select
|
|
58
|
+
post_uuid,
|
|
59
|
+
pathname,
|
|
60
|
+
uniqExact(session_id) as visits
|
|
61
|
+
from _mv_hits h
|
|
62
|
+
inner join filtered_sessions fs
|
|
63
|
+
on fs.session_id = h.session_id
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Scenario:** Filter by `utm_medium=social`
|
|
67
|
+
|
|
68
|
+
If there are 5 sessions where the first hit had `utm_medium=social`:
|
|
69
|
+
- The query returns ALL pageviews from those 5 sessions
|
|
70
|
+
- A single session might visit multiple pages (e.g., /, /about/, /blog/post/)
|
|
71
|
+
- Each page shows how many of the 5 sessions visited it
|
|
72
|
+
- The sum of visits across all pages can exceed 5 because sessions are counted once per unique page they visited
|
|
73
|
+
|
|
74
|
+
**Result:**
|
|
75
|
+
```json
|
|
76
|
+
{"pathname":"/about/","visits":3} // 3 of the 5 sessions visited /about/
|
|
77
|
+
{"pathname":"/","visits":3} // 3 of the 5 sessions visited /
|
|
78
|
+
{"pathname":"/blog/hello/","visits":2} // 2 of the 5 sessions visited /blog/hello/
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Total: 8 page-session combinations from 5 unique sessions.
|
|
82
|
+
|
|
83
|
+
This behavior answers the question: **"What pages did users visit when they came from [source/utm]?"** rather than **"Which specific pageviews had [source/utm] in the URL?"**
|
|
84
|
+
|
|
85
|
+
### Filter Placement Rules
|
|
86
|
+
|
|
87
|
+
When creating or modifying endpoints:
|
|
88
|
+
|
|
89
|
+
1. **Session-level filters** (source, utm_*) → Only in `filtered_sessions.pipe`
|
|
90
|
+
2. **Hit-level filters** (pathname, post_uuid, member_status) → Can be in both:
|
|
91
|
+
- `filtered_sessions.pipe` (for session qualification)
|
|
92
|
+
- Endpoint queries (for additional filtering of results)
|
|
93
|
+
3. **Never duplicate** session-level filters in endpoint queries - always rely on `filtered_sessions`
|
|
94
|
+
|
|
95
|
+
### API Endpoint Patterns
|
|
96
|
+
|
|
97
|
+
All analytics endpoints follow this pattern:
|
|
98
|
+
|
|
99
|
+
```sql
|
|
100
|
+
from _mv_hits h
|
|
101
|
+
inner join filtered_sessions fs
|
|
102
|
+
on fs.session_id = h.session_id
|
|
103
|
+
where
|
|
104
|
+
site_uuid = {{ site_uuid }}
|
|
105
|
+
-- Date range filters
|
|
106
|
+
-- Hit-level filters only (if needed for this specific endpoint)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
The join with `filtered_sessions` ensures only hits from sessions matching the filter criteria are included, while the `where` clause can apply additional hit-level filtering specific to the endpoint's purpose.
|
|
@@ -79,17 +79,6 @@ SQL >
|
|
|
79
79
|
on fs.session_id = sd.session_id
|
|
80
80
|
where
|
|
81
81
|
site_uuid = {{ String(site_uuid, 'mock_site_uuid', description="Tenant ID", required=True) }}
|
|
82
|
-
{% if defined(date_from) and day_diff(date_from, date_to) == 0 %}
|
|
83
|
-
and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) = {{ Date(date_from) }}
|
|
84
|
-
{% else %}
|
|
85
|
-
{% if defined(date_from) %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) >= {{ Date(date_from) }} {% else %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) >= timestampAdd(today(), interval -7 day) {% end %}
|
|
86
|
-
{% if defined(date_to) %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) <= {{ Date(date_to) }} {% else %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) <= today() {% end %}
|
|
87
|
-
{% end %}
|
|
88
|
-
{% if defined(utm_source) %} and utm_source = {{ String(utm_source, description="UTM source to filter on", required=False) }} {% end %}
|
|
89
|
-
{% if defined(utm_medium) %} and utm_medium = {{ String(utm_medium, description="UTM medium to filter on", required=False) }} {% end %}
|
|
90
|
-
{% if defined(utm_campaign) %} and utm_campaign = {{ String(utm_campaign, description="UTM campaign to filter on", required=False) }} {% end %}
|
|
91
|
-
{% if defined(utm_term) %} and utm_term = {{ String(utm_term, description="UTM term to filter on", required=False) }} {% end %}
|
|
92
|
-
{% if defined(utm_content) %} and utm_content = {{ String(utm_content, description="UTM content to filter on", required=False) }} {% end %}
|
|
93
82
|
|
|
94
83
|
|
|
95
84
|
NODE data
|
|
@@ -131,24 +120,14 @@ SQL >
|
|
|
131
120
|
{% else %}
|
|
132
121
|
a.date = toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
133
122
|
{% end %}
|
|
123
|
+
inner join filtered_sessions fs
|
|
124
|
+
on fs.session_id = h.session_id
|
|
134
125
|
where
|
|
135
126
|
site_uuid = {{ String(site_uuid, 'mock_site_uuid', description="Tenant ID", required=True) }}
|
|
136
|
-
{% if defined(date_from) and day_diff(date_from, date_to) == 0 %}
|
|
137
|
-
and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) = {{ Date(date_from) }}
|
|
138
|
-
{% else %}
|
|
139
|
-
{% if defined(date_from) %} and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) >= {{ Date(date_from) }} {% else %} and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) >= timestampAdd(today(), interval -7 day) {% end %}
|
|
140
|
-
{% if defined(date_to) %} and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) <= {{ Date(date_to) }} {% else %} and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) <= today() {% end %}
|
|
141
|
-
{% end %}
|
|
142
127
|
{% if defined(member_status) %} and member_status IN {{ Array(member_status, "'undefined', 'free', 'paid'", description="Member status to filter on", required=False) }} {% end %}
|
|
143
|
-
{% if defined(source) %} and source = {{ String(source, description="Source to filter on", required=False) }} {% end %}
|
|
144
128
|
{% if defined(location) %} and location = {{ String(location, description="Location to filter on", required=False) }} {% end %}
|
|
145
129
|
{% if defined(pathname) %} and pathname = {{ String(pathname, description="Pathname to filter on", required=False) }} {% end %}
|
|
146
130
|
{% if defined(post_uuid) %} and post_uuid = {{String(post_uuid, description="Post UUID to filter on", required=False) }} {% end %}
|
|
147
|
-
{% if defined(utm_source) %} and utm_source = {{ String(utm_source, description="UTM source to filter on", required=False) }} {% end %}
|
|
148
|
-
{% if defined(utm_medium) %} and utm_medium = {{ String(utm_medium, description="UTM medium to filter on", required=False) }} {% end %}
|
|
149
|
-
{% if defined(utm_campaign) %} and utm_campaign = {{ String(utm_campaign, description="UTM campaign to filter on", required=False) }} {% end %}
|
|
150
|
-
{% if defined(utm_term) %} and utm_term = {{ String(utm_term, description="UTM term to filter on", required=False) }} {% end %}
|
|
151
|
-
{% if defined(utm_content) %} and utm_content = {{ String(utm_content, description="UTM content to filter on", required=False) }} {% end %}
|
|
152
131
|
group by date
|
|
153
132
|
order by date
|
|
154
133
|
|
|
@@ -4,15 +4,16 @@ TOKEN "axis" READ
|
|
|
4
4
|
NODE ingestion_latency
|
|
5
5
|
SQL >
|
|
6
6
|
%
|
|
7
|
-
SELECT
|
|
7
|
+
SELECT
|
|
8
8
|
toDate(inserted_at) as date,
|
|
9
9
|
site_uuid,
|
|
10
10
|
inserted_at,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
FROM
|
|
14
|
-
WHERE
|
|
15
|
-
|
|
11
|
+
received_at,
|
|
12
|
+
ingestion_latency_ms
|
|
13
|
+
FROM _mv_hits
|
|
14
|
+
WHERE
|
|
15
|
+
-- ingestion_latency_ms is set to -1 if received_at is invalid
|
|
16
|
+
ingestion_latency_ms >= 0
|
|
16
17
|
{% if defined(start_date) %}
|
|
17
18
|
AND toDate(inserted_at) >= {{ Date(start_date, description="Start date for filtering", required=False) }}
|
|
18
19
|
{% else %}
|
|
@@ -30,19 +31,19 @@ SQL >
|
|
|
30
31
|
NODE ingestion_metrics
|
|
31
32
|
SQL >
|
|
32
33
|
%
|
|
33
|
-
SELECT
|
|
34
|
+
SELECT
|
|
34
35
|
date,
|
|
35
36
|
{% if defined(site_uuid) %}
|
|
36
37
|
site_uuid,
|
|
37
38
|
{% end %}
|
|
38
39
|
count() as total_events,
|
|
39
|
-
round(avg(
|
|
40
|
-
round(quantile(0.5)(
|
|
41
|
-
round(quantile(0.95)(
|
|
42
|
-
round(min(
|
|
43
|
-
round(max(
|
|
40
|
+
round(avg(ingestion_latency_ms)) as avg_latency_ms,
|
|
41
|
+
round(quantile(0.5)(ingestion_latency_ms)) as p50_latency_ms,
|
|
42
|
+
round(quantile(0.95)(ingestion_latency_ms)) as p95_latency_ms,
|
|
43
|
+
round(min(ingestion_latency_ms)) as min_latency_ms,
|
|
44
|
+
round(max(ingestion_latency_ms)) as max_latency_ms
|
|
44
45
|
FROM ingestion_latency
|
|
45
46
|
GROUP BY date{% if defined(site_uuid) %}, site_uuid{% end %}
|
|
46
47
|
ORDER BY date DESC{% if defined(site_uuid) %}, site_uuid{% end %}
|
|
47
48
|
|
|
48
|
-
TYPE ENDPOINT
|
|
49
|
+
TYPE ENDPOINT
|
|
@@ -4,14 +4,15 @@ TOKEN "axis" READ
|
|
|
4
4
|
NODE ingestion_latency
|
|
5
5
|
SQL >
|
|
6
6
|
%
|
|
7
|
-
SELECT
|
|
7
|
+
SELECT
|
|
8
8
|
site_uuid,
|
|
9
9
|
inserted_at,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
FROM
|
|
13
|
-
WHERE
|
|
14
|
-
|
|
10
|
+
received_at,
|
|
11
|
+
ingestion_latency_ms
|
|
12
|
+
FROM _mv_hits
|
|
13
|
+
WHERE
|
|
14
|
+
-- ingestion_latency_ms is set to -1 if received_at is invalid
|
|
15
|
+
ingestion_latency_ms >= 0
|
|
15
16
|
{% if defined(start_date) %}
|
|
16
17
|
AND toDate(inserted_at) >= {{ Date(start_date, description="Start date for filtering", required=False) }}
|
|
17
18
|
{% else %}
|
|
@@ -29,16 +30,16 @@ SQL >
|
|
|
29
30
|
NODE ingestion_metrics
|
|
30
31
|
SQL >
|
|
31
32
|
%
|
|
32
|
-
SELECT
|
|
33
|
+
SELECT
|
|
33
34
|
{% if defined(site_uuid) %}
|
|
34
35
|
site_uuid,
|
|
35
36
|
{% end %}
|
|
36
37
|
count() as total_events,
|
|
37
|
-
round(avg(
|
|
38
|
-
round(quantile(0.5)(
|
|
39
|
-
round(quantile(0.95)(
|
|
40
|
-
round(min(
|
|
41
|
-
round(max(
|
|
38
|
+
round(avg(ingestion_latency_ms)) as avg_latency_ms,
|
|
39
|
+
round(quantile(0.5)(ingestion_latency_ms)) as p50_latency_ms,
|
|
40
|
+
round(quantile(0.95)(ingestion_latency_ms)) as p95_latency_ms,
|
|
41
|
+
round(min(ingestion_latency_ms)) as min_latency_ms,
|
|
42
|
+
round(max(ingestion_latency_ms)) as max_latency_ms
|
|
42
43
|
FROM ingestion_latency
|
|
43
44
|
{% if defined(site_uuid) %}
|
|
44
45
|
GROUP BY site_uuid
|
|
@@ -13,24 +13,6 @@ SQL >
|
|
|
13
13
|
on fs.session_id = h.session_id
|
|
14
14
|
where
|
|
15
15
|
site_uuid = {{String(site_uuid, 'mock_site_uuid', description="Tenant ID", required=True)}}
|
|
16
|
-
{% if defined(date_from) %}
|
|
17
|
-
and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
18
|
-
>=
|
|
19
|
-
{{ Date(date_from, description="Starting day for filtering a date range", required=False) }}
|
|
20
|
-
{% else %}
|
|
21
|
-
and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
22
|
-
>=
|
|
23
|
-
timestampAdd(today(), interval -7 day)
|
|
24
|
-
{% end %}
|
|
25
|
-
{% if defined(date_to) %}
|
|
26
|
-
and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
27
|
-
<=
|
|
28
|
-
{{ Date(date_to, description="Finishing day for filtering a date range", required=False) }}
|
|
29
|
-
{% else %}
|
|
30
|
-
and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
31
|
-
<=
|
|
32
|
-
today()
|
|
33
|
-
{% end %}
|
|
34
16
|
{% if defined(member_status) %}
|
|
35
17
|
and member_status IN (
|
|
36
18
|
select arrayJoin(
|
|
@@ -39,7 +21,6 @@ SQL >
|
|
|
39
21
|
)
|
|
40
22
|
)
|
|
41
23
|
{% end %}
|
|
42
|
-
{% if defined(source) %} and source = {{ String(source, description="Source to filter on", required=False) }} {% end %}
|
|
43
24
|
{% if defined(location) %} and location = {{ String(location, description="Location to filter on", required=False) }} {% end %}
|
|
44
25
|
{% if defined(pathname) %} and pathname = {{ String(pathname, description="Pathname to filter on", required=False) }} {% end %}
|
|
45
26
|
{% if defined(post_uuid) %} and post_uuid = {{ String(post_uuid, description="Post UUID to filter on", required=False) }} {% end %}
|
|
@@ -14,24 +14,6 @@ SQL >
|
|
|
14
14
|
on fs.session_id = h.session_id
|
|
15
15
|
where
|
|
16
16
|
site_uuid = {{String(site_uuid, 'mock_site_uuid', description="Tenant ID", required=True)}}
|
|
17
|
-
{% if defined(date_from) %}
|
|
18
|
-
and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
19
|
-
>=
|
|
20
|
-
{{ Date(date_from, description="Starting day for filtering a date range", required=False) }}
|
|
21
|
-
{% else %}
|
|
22
|
-
and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
23
|
-
>=
|
|
24
|
-
timestampAdd(today(), interval -7 day)
|
|
25
|
-
{% end %}
|
|
26
|
-
{% if defined(date_to) %}
|
|
27
|
-
and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
28
|
-
<=
|
|
29
|
-
{{ Date(date_to, description="Finishing day for filtering a date range", required=False) }}
|
|
30
|
-
{% else %}
|
|
31
|
-
and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
32
|
-
<=
|
|
33
|
-
today()
|
|
34
|
-
{% end %}
|
|
35
17
|
{% if defined(member_status) %}
|
|
36
18
|
and member_status IN (
|
|
37
19
|
select arrayJoin(
|
|
@@ -50,11 +32,6 @@ SQL >
|
|
|
50
32
|
and (post_type != 'post' or post_type is null)
|
|
51
33
|
{% end %}
|
|
52
34
|
{% end %}
|
|
53
|
-
{% if defined(utm_source) %} and utm_source = {{ String(utm_source, description="UTM source to filter on", required=False) }} {% end %}
|
|
54
|
-
{% if defined(utm_medium) %} and utm_medium = {{ String(utm_medium, description="UTM medium to filter on", required=False) }} {% end %}
|
|
55
|
-
{% if defined(utm_campaign) %} and utm_campaign = {{ String(utm_campaign, description="UTM campaign to filter on", required=False) }} {% end %}
|
|
56
|
-
{% if defined(utm_term) %} and utm_term = {{ String(utm_term, description="UTM term to filter on", required=False) }} {% end %}
|
|
57
|
-
{% if defined(utm_content) %} and utm_content = {{ String(utm_content, description="UTM content to filter on", required=False) }} {% end %}
|
|
58
35
|
group by post_uuid, pathname
|
|
59
36
|
order by visits desc
|
|
60
37
|
limit {{ Int32(skip, 0) }},{{ Int32(limit, 50) }}
|
|
@@ -12,17 +12,6 @@ SQL >
|
|
|
12
12
|
on fs.session_id = sd.session_id
|
|
13
13
|
where
|
|
14
14
|
site_uuid = {{ String(site_uuid, 'mock_site_uuid', description="Tenant ID", required=True) }}
|
|
15
|
-
{% if defined(date_from) and day_diff(date_from, date_to) == 0 %}
|
|
16
|
-
and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) = {{ Date(date_from) }}
|
|
17
|
-
{% else %}
|
|
18
|
-
{% if defined(date_from) %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) >= {{ Date(date_from) }} {% else %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) >= timestampAdd(today(), interval -7 day) {% end %}
|
|
19
|
-
{% if defined(date_to) %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) <= {{ Date(date_to) }} {% else %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) <= today() {% end %}
|
|
20
|
-
{% end %}
|
|
21
|
-
{% if defined(utm_source) %} and utm_source = {{ String(utm_source, description="UTM source to filter on", required=False) }} {% end %}
|
|
22
|
-
{% if defined(utm_medium) %} and utm_medium = {{ String(utm_medium, description="UTM medium to filter on", required=False) }} {% end %}
|
|
23
|
-
{% if defined(utm_campaign) %} and utm_campaign = {{ String(utm_campaign, description="UTM campaign to filter on", required=False) }} {% end %}
|
|
24
|
-
{% if defined(utm_term) %} and utm_term = {{ String(utm_term, description="UTM term to filter on", required=False) }} {% end %}
|
|
25
|
-
{% if defined(utm_content) %} and utm_content = {{ String(utm_content, description="UTM content to filter on", required=False) }} {% end %}
|
|
26
15
|
group by source
|
|
27
16
|
order by visits desc
|
|
28
17
|
limit {{ Int32(skip, 0) }},{{ Int32(limit, 50) }}
|
|
@@ -13,12 +13,6 @@ SQL >
|
|
|
13
13
|
where
|
|
14
14
|
site_uuid = {{ String(site_uuid, 'mock_site_uuid', description="Tenant ID", required=True) }}
|
|
15
15
|
and utm_campaign != ''
|
|
16
|
-
{% if defined(date_from) and day_diff(date_from, date_to) == 0 %}
|
|
17
|
-
and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) = {{ Date(date_from) }}
|
|
18
|
-
{% else %}
|
|
19
|
-
{% if defined(date_from) %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) >= {{ Date(date_from) }} {% else %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) >= timestampAdd(today(), interval -7 day) {% end %}
|
|
20
|
-
{% if defined(date_to) %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) <= {{ Date(date_to) }} {% else %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) <= today() {% end %}
|
|
21
|
-
{% end %}
|
|
22
16
|
group by utm_campaign
|
|
23
17
|
order by visits desc
|
|
24
18
|
limit {{ Int32(skip, 0) }},{{ Int32(limit, 50) }}
|
|
@@ -13,12 +13,6 @@ SQL >
|
|
|
13
13
|
where
|
|
14
14
|
site_uuid = {{ String(site_uuid, 'mock_site_uuid', description="Tenant ID", required=True) }}
|
|
15
15
|
and utm_content != ''
|
|
16
|
-
{% if defined(date_from) and day_diff(date_from, date_to) == 0 %}
|
|
17
|
-
and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) = {{ Date(date_from) }}
|
|
18
|
-
{% else %}
|
|
19
|
-
{% if defined(date_from) %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) >= {{ Date(date_from) }} {% else %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) >= timestampAdd(today(), interval -7 day) {% end %}
|
|
20
|
-
{% if defined(date_to) %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) <= {{ Date(date_to) }} {% else %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) <= today() {% end %}
|
|
21
|
-
{% end %}
|
|
22
16
|
group by utm_content
|
|
23
17
|
order by visits desc
|
|
24
18
|
limit {{ Int32(skip, 0) }},{{ Int32(limit, 50) }}
|
|
@@ -13,12 +13,6 @@ SQL >
|
|
|
13
13
|
where
|
|
14
14
|
site_uuid = {{ String(site_uuid, 'mock_site_uuid', description="Tenant ID", required=True) }}
|
|
15
15
|
and utm_medium != ''
|
|
16
|
-
{% if defined(date_from) and day_diff(date_from, date_to) == 0 %}
|
|
17
|
-
and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) = {{ Date(date_from) }}
|
|
18
|
-
{% else %}
|
|
19
|
-
{% if defined(date_from) %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) >= {{ Date(date_from) }} {% else %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) >= timestampAdd(today(), interval -7 day) {% end %}
|
|
20
|
-
{% if defined(date_to) %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) <= {{ Date(date_to) }} {% else %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) <= today() {% end %}
|
|
21
|
-
{% end %}
|
|
22
16
|
group by utm_medium
|
|
23
17
|
order by visits desc
|
|
24
18
|
limit {{ Int32(skip, 0) }},{{ Int32(limit, 50) }}
|
|
@@ -13,12 +13,6 @@ SQL >
|
|
|
13
13
|
where
|
|
14
14
|
site_uuid = {{ String(site_uuid, 'mock_site_uuid', description="Tenant ID", required=True) }}
|
|
15
15
|
and utm_source != ''
|
|
16
|
-
{% if defined(date_from) and day_diff(date_from, date_to) == 0 %}
|
|
17
|
-
and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) = {{ Date(date_from) }}
|
|
18
|
-
{% else %}
|
|
19
|
-
{% if defined(date_from) %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) >= {{ Date(date_from) }} {% else %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) >= timestampAdd(today(), interval -7 day) {% end %}
|
|
20
|
-
{% if defined(date_to) %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) <= {{ Date(date_to) }} {% else %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) <= today() {% end %}
|
|
21
|
-
{% end %}
|
|
22
16
|
group by utm_source
|
|
23
17
|
order by visits desc
|
|
24
18
|
limit {{ Int32(skip, 0) }},{{ Int32(limit, 50) }}
|
|
@@ -13,12 +13,6 @@ SQL >
|
|
|
13
13
|
where
|
|
14
14
|
site_uuid = {{ String(site_uuid, 'mock_site_uuid', description="Tenant ID", required=True) }}
|
|
15
15
|
and utm_term != ''
|
|
16
|
-
{% if defined(date_from) and day_diff(date_from, date_to) == 0 %}
|
|
17
|
-
and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) = {{ Date(date_from) }}
|
|
18
|
-
{% else %}
|
|
19
|
-
{% if defined(date_from) %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) >= {{ Date(date_from) }} {% else %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) >= timestampAdd(today(), interval -7 day) {% end %}
|
|
20
|
-
{% if defined(date_to) %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) <= {{ Date(date_to) }} {% else %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) <= today() {% end %}
|
|
21
|
-
{% end %}
|
|
22
16
|
group by utm_term
|
|
23
17
|
order by visits desc
|
|
24
18
|
limit {{ Int32(skip, 0) }},{{ Int32(limit, 50) }}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
TOKEN "axis" READ
|
|
2
2
|
|
|
3
|
-
NODE
|
|
3
|
+
NODE sessions_filtered_by_hit_attributes
|
|
4
4
|
DESCRIPTION >
|
|
5
|
-
Get sessions
|
|
5
|
+
Get sessions where at least one hit matches the hit-level filter criteria.
|
|
6
|
+
Hit-level filters (pathname, post_uuid, member_status, location) can vary across pageviews within a session.
|
|
7
|
+
A session qualifies if ANY of its hits match the specified criteria.
|
|
6
8
|
|
|
7
9
|
SQL >
|
|
8
10
|
%
|
|
@@ -20,22 +22,40 @@ SQL >
|
|
|
20
22
|
)
|
|
21
23
|
)
|
|
22
24
|
{% end %}
|
|
23
|
-
{% if defined(source) %} and source = {{ String(source, description="Source to filter on", required=False) }} {% end %}
|
|
24
25
|
{% if defined(location) %} and location = {{ String(location, description="Location to filter on", required=False) }} {% end %}
|
|
25
26
|
{% if defined(pathname) %} and pathname = {{ String(pathname, description="Pathname to filter on", required=False) }} {% end %}
|
|
26
|
-
{% if defined
|
|
27
|
+
{% if defined(post_uuid) %} and post_uuid = {{ String(post_uuid, description="Post UUID to filter on", required=False) }} {% end %}
|
|
27
28
|
|
|
28
|
-
NODE
|
|
29
|
+
NODE sessions_filtered_by_session_attributes
|
|
29
30
|
DESCRIPTION >
|
|
30
|
-
Further filter by
|
|
31
|
+
Further filter by session-level attributes (source, utm_*). This is necessary because these attributes are specific to the first hit in a session,
|
|
31
32
|
whereas other filters are on hits.
|
|
32
33
|
|
|
33
34
|
SQL >
|
|
34
35
|
%
|
|
35
36
|
select session_id
|
|
36
37
|
from mv_session_data sd
|
|
37
|
-
inner join
|
|
38
|
-
on
|
|
38
|
+
inner join sessions_filtered_by_hit_attributes sfha
|
|
39
|
+
on sfha.session_id = sd.session_id
|
|
39
40
|
where
|
|
40
41
|
site_uuid = {{ String(site_uuid, 'mock_site_uuid', description="Tenant ID", required=True) }}
|
|
42
|
+
{% if defined(date_from) %}
|
|
43
|
+
{# Filter from specified start date #}
|
|
44
|
+
and toDate(toTimezone(first_pageview,{{ String(timezone, 'Etc/UTC', description="Site timezone", required=True) }})) >= {{ Date(date_from) }}
|
|
45
|
+
{% else %}
|
|
46
|
+
{# Default to last 7 days if no start date provided #}
|
|
47
|
+
and toDate(toTimezone(first_pageview,{{ String(timezone, 'Etc/UTC', description="Site timezone", required=True) }})) >= timestampAdd(today(), interval -7 day)
|
|
48
|
+
{% end %}
|
|
49
|
+
{% if defined(date_to) %}
|
|
50
|
+
{# Filter to specified end date #}
|
|
51
|
+
and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) <= {{ Date(date_to) }}
|
|
52
|
+
{% else %}
|
|
53
|
+
{# Default to today if no end date provided #}
|
|
54
|
+
and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) <= today()
|
|
55
|
+
{% end %}
|
|
41
56
|
{% if defined(source) %} and source = {{ String(source, description="Source to filter on", required=False) }} {% end %}
|
|
57
|
+
{% if defined(utm_source) %} and utm_source = {{ String(utm_source, description="UTM source to filter on", required=False) }} {% end %}
|
|
58
|
+
{% if defined(utm_medium) %} and utm_medium = {{ String(utm_medium, description="UTM medium to filter on", required=False) }} {% end %}
|
|
59
|
+
{% if defined(utm_campaign) %} and utm_campaign = {{ String(utm_campaign, description="UTM campaign to filter on", required=False) }} {% end %}
|
|
60
|
+
{% if defined(utm_term) %} and utm_term = {{ String(utm_term, description="UTM term to filter on", required=False) }} {% end %}
|
|
61
|
+
{% if defined(utm_content) %} and utm_content = {{ String(utm_content, description="UTM content to filter on", required=False) }} {% end %}
|
|
@@ -4,6 +4,10 @@ NODE mv_hits_0
|
|
|
4
4
|
SQL >
|
|
5
5
|
|
|
6
6
|
SELECT timestamp,
|
|
7
|
+
inserted_at,
|
|
8
|
+
-- payload.meta.received_timestamp may be missing or null
|
|
9
|
+
-- Nullable fields incur performance penalty in clickhouse, so we default to zero (unix epoch) instead of null.
|
|
10
|
+
parseDateTime64BestEffortOrZero(JSONExtractString(payload, 'meta', 'received_timestamp'), 3) as received_at,
|
|
7
11
|
action,
|
|
8
12
|
version,
|
|
9
13
|
coalesce(session_id, '0') as session_id,
|
|
@@ -37,6 +41,14 @@ SQL >
|
|
|
37
41
|
SELECT
|
|
38
42
|
site_uuid,
|
|
39
43
|
timestamp,
|
|
44
|
+
received_at,
|
|
45
|
+
inserted_at,
|
|
46
|
+
case
|
|
47
|
+
-- set to -1 if received_at is the unix epoch, or if received_at is after inserted_at
|
|
48
|
+
when toUnixTimestamp(received_at) = 0 then -1
|
|
49
|
+
when received_at > inserted_at then -1
|
|
50
|
+
else date_diff('millisecond', received_at, inserted_at)
|
|
51
|
+
end as ingestion_latency_ms,
|
|
40
52
|
action,
|
|
41
53
|
version,
|
|
42
54
|
session_id,
|
|
@@ -54,20 +66,20 @@ SQL >
|
|
|
54
66
|
when referrer IN ('Instagram', 'www.instagram.com') then 'Instagram'
|
|
55
67
|
when referrer IN ('LinkedIn', 'LINKEDIN_COMPANY') then 'LinkedIn'
|
|
56
68
|
when referrer IN ('l.threads.com') then 'Threads'
|
|
57
|
-
|
|
69
|
+
|
|
58
70
|
-- Reddit Ecosystem
|
|
59
71
|
when referrer IN ('www.reddit.com', 'out.reddit.com', 'old.reddit.com', 'com.reddit.frontpage') then 'Reddit'
|
|
60
|
-
|
|
72
|
+
|
|
61
73
|
-- Search Engines (keep distinctions)
|
|
62
74
|
when referrer IN ('search.brave.com') then 'Brave Search'
|
|
63
75
|
when referrer IN ('www.ecosia.org') then 'Ecosia'
|
|
64
|
-
|
|
76
|
+
|
|
65
77
|
-- Email Services
|
|
66
78
|
when referrer IN ('Gmail', 'com.google.android.gm', 'mail.google.com') then 'Gmail'
|
|
67
79
|
when referrer IN ('Outlook.com') then 'Outlook'
|
|
68
80
|
when referrer IN ('Yahoo!', 'www.yahoo.com', 'Yahoo! Mail', 'r.search.yahoo.com') then 'Yahoo!'
|
|
69
81
|
when referrer IN ('AOL Mail') then 'AOL Mail'
|
|
70
|
-
|
|
82
|
+
|
|
71
83
|
-- Content Platforms
|
|
72
84
|
when referrer IN ('flipboard', 'flipboard.com', 'flipboard.app') then 'Flipboard'
|
|
73
85
|
when referrer IN ('substack', 'substack.com') then 'Substack'
|
|
@@ -75,22 +87,22 @@ SQL >
|
|
|
75
87
|
when referrer IN ('buffer') then 'Buffer'
|
|
76
88
|
when referrer IN ('Taboola') then 'Taboola'
|
|
77
89
|
when referrer IN ('AppNexus') then 'AppNexus'
|
|
78
|
-
|
|
90
|
+
|
|
79
91
|
-- Wikipedia
|
|
80
92
|
when referrer IN ('en.wikipedia.org', 'en.m.wikipedia.org') then 'Wikipedia'
|
|
81
|
-
|
|
93
|
+
|
|
82
94
|
-- Mastodon Network
|
|
83
95
|
when referrer IN ('mastodon.social', 'mastodon.online', 'org.joinmastodon.android', 'phanpy.social', 'dev.phanpy.social') then 'Mastodon'
|
|
84
|
-
|
|
96
|
+
|
|
85
97
|
-- News Aggregators
|
|
86
98
|
when referrer IN ('www.memeorandum.com', 'memeorandum.com') then 'Memeorandum'
|
|
87
99
|
when referrer IN ('ground.news') then 'Ground News'
|
|
88
100
|
when referrer IN ('apple.news') then 'Apple News'
|
|
89
101
|
when referrer IN ('www.smartnews.com') then 'SmartNews'
|
|
90
|
-
|
|
102
|
+
|
|
91
103
|
-- Keep other sources as-is
|
|
92
|
-
when domainWithoutWWW(referrer) != '' then domainWithoutWWW(referrer)
|
|
93
|
-
else referrer
|
|
104
|
+
when domainWithoutWWW(referrer) != '' then domainWithoutWWW(referrer)
|
|
105
|
+
else referrer
|
|
94
106
|
end as source,
|
|
95
107
|
pathname,
|
|
96
108
|
href,
|
|
@@ -137,4 +149,4 @@ SQL >
|
|
|
137
149
|
FROM mv_hits_0
|
|
138
150
|
|
|
139
151
|
TYPE materialized
|
|
140
|
-
DATASOURCE _mv_hits
|
|
152
|
+
DATASOURCE _mv_hits
|
|
@@ -94,19 +94,22 @@
|
|
|
94
94
|
parameters: site_uuid=mock_site_uuid&date_from=2100-01-01&date_to=2100-01-07&timezone=Etc/UTC&utm_medium=social
|
|
95
95
|
expected_result: |
|
|
96
96
|
{"post_uuid":"06b1b0c9-fb53-4a15-a060-3db3fde7b1fc","pathname":"\/about\/","visits":3}
|
|
97
|
-
{"post_uuid":"","pathname":"\/","visits":
|
|
97
|
+
{"post_uuid":"","pathname":"\/","visits":3}
|
|
98
|
+
{"post_uuid":"6b8635fb-292f-4422-9fe4-d76cfab2ba31","pathname":"\/blog\/hello-world\/","visits":2}
|
|
98
99
|
|
|
99
100
|
- name: Filtered by utm_campaign - brand_awareness
|
|
100
101
|
description: Filtered by utm_campaign - brand_awareness
|
|
101
102
|
parameters: site_uuid=mock_site_uuid&date_from=2100-01-01&date_to=2100-01-07&timezone=Etc/UTC&utm_campaign=brand_awareness
|
|
102
103
|
expected_result: |
|
|
103
|
-
{"post_uuid":"","pathname":"\/","visits":
|
|
104
|
+
{"post_uuid":"","pathname":"\/","visits":2}
|
|
105
|
+
{"post_uuid":"06b1b0c9-fb53-4a15-a060-3db3fde7b1fc","pathname":"\/about\/","visits":1}
|
|
104
106
|
{"post_uuid":"6b8635fb-292f-4422-9fe4-d76cfab2ba31","pathname":"\/blog\/hello-world\/","visits":1}
|
|
105
107
|
|
|
106
108
|
- name: Filtered by utm_term - discount
|
|
107
109
|
description: Filtered by utm_term - discount
|
|
108
110
|
parameters: site_uuid=mock_site_uuid&date_from=2100-01-01&date_to=2100-01-07&timezone=Etc/UTC&utm_term=discount
|
|
109
111
|
expected_result: |
|
|
112
|
+
{"post_uuid":"06b1b0c9-fb53-4a15-a060-3db3fde7b1fc","pathname":"\/about\/","visits":1}
|
|
110
113
|
{"post_uuid":"6b8635fb-292f-4422-9fe4-d76cfab2ba31","pathname":"\/blog\/hello-world\/","visits":1}
|
|
111
114
|
|
|
112
115
|
- name: Filtered by utm_content - post_123
|