@gscdump/analysis 3.8.0 → 4.0.1
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/README.md +18 -4
- package/dist/analyzer/adapt-rows.mjs +6 -7
- package/dist/analyzer/paginate.mjs +12 -1
- package/dist/analyzers/brand.mjs +46 -29
- package/dist/analyzers/cannibalization.mjs +22 -9
- package/dist/analyzers/clustering.mjs +20 -6
- package/dist/analyzers/concentration.mjs +3 -3
- package/dist/analyzers/decay.mjs +27 -15
- package/dist/analyzers/movers.d.mts +19 -7
- package/dist/analyzers/movers.mjs +226 -149
- package/dist/analyzers/opportunity.mjs +9 -5
- package/dist/analyzers/seasonality.mjs +6 -3
- package/dist/analyzers/striking-distance.mjs +2 -3
- package/dist/analyzers/zero-click.mjs +8 -9
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +2 -2
- package/dist/report/reports/movers.mjs +27 -10
- package/dist/report/reports/opportunities.mjs +11 -7
- package/dist/report/reports/pre-publish.mjs +3 -2
- package/dist/report/reports/risks.mjs +5 -5
- package/dist/report/runtime.mjs +5 -3
- package/dist/report/sections.mjs +6 -2
- package/package.json +6 -6
|
@@ -1,12 +1,26 @@
|
|
|
1
1
|
import { queriesQueryState } from "../analyzer/adapt-rows.mjs";
|
|
2
|
+
import { paginateClause, paginateInMemory, resolveSort } from "../analyzer/paginate.mjs";
|
|
2
3
|
import { parseJsonRows, rowString } from "../analyzer/row-values.mjs";
|
|
3
|
-
import { buildPeriodMap } from "../types.mjs";
|
|
4
4
|
import { percentDifference } from "../scoring.mjs";
|
|
5
|
-
import { num } from "@gscdump/engine/analysis-types";
|
|
5
|
+
import { fetchBudgetOf, num } from "@gscdump/engine/analysis-types";
|
|
6
6
|
import { defineAnalyzer } from "@gscdump/engine/analyzer";
|
|
7
7
|
import { comparisonOf } from "@gscdump/engine/period";
|
|
8
8
|
import { enumeratePartitions } from "@gscdump/engine/planner";
|
|
9
9
|
import { METRIC_EXPR } from "@gscdump/engine/sql-fragments";
|
|
10
|
+
const MOVERS_SORT_METRICS = [
|
|
11
|
+
"clicks",
|
|
12
|
+
"impressions",
|
|
13
|
+
"clicksDelta",
|
|
14
|
+
"clicksDeltaPercent",
|
|
15
|
+
"impressionsDelta",
|
|
16
|
+
"impressionsDeltaPercent",
|
|
17
|
+
"positionDelta"
|
|
18
|
+
];
|
|
19
|
+
const DEFAULT_SORT = {
|
|
20
|
+
sortBy: "clicksDelta",
|
|
21
|
+
sortDir: "desc"
|
|
22
|
+
};
|
|
23
|
+
const DEFAULT_MOVERS_LIMIT = 2e3;
|
|
10
24
|
function withCanonicalFields(r) {
|
|
11
25
|
return {
|
|
12
26
|
...r,
|
|
@@ -19,90 +33,112 @@ function withCanonicalFields(r) {
|
|
|
19
33
|
prevPosition: r.baselinePosition
|
|
20
34
|
};
|
|
21
35
|
}
|
|
22
|
-
function
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
return
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
total,
|
|
32
|
-
rising: rising.length,
|
|
33
|
-
declining: declining.length,
|
|
34
|
-
stable: stable.length
|
|
35
|
-
}
|
|
36
|
-
};
|
|
36
|
+
function sortValue(row, sortBy) {
|
|
37
|
+
switch (sortBy) {
|
|
38
|
+
case "clicks": return row.recentClicks;
|
|
39
|
+
case "impressions": return row.recentImpressions;
|
|
40
|
+
case "clicksDelta": return Math.abs(row.clicksChange);
|
|
41
|
+
case "clicksDeltaPercent": return Math.abs(row.clicksChangePercent);
|
|
42
|
+
case "impressionsDelta": return Math.abs(row.impressionsChange);
|
|
43
|
+
case "impressionsDeltaPercent": return Math.abs(row.impressionsChangePercent);
|
|
44
|
+
case "positionDelta": return Math.abs(row.positionChange ?? 0);
|
|
37
45
|
}
|
|
38
|
-
|
|
46
|
+
}
|
|
47
|
+
function moversComparator(sortBy, sortDir) {
|
|
48
|
+
const mult = sortDir === "asc" ? 1 : -1;
|
|
49
|
+
return (a, b) => (sortValue(a, sortBy) - sortValue(b, sortBy)) * mult || a.keyword.localeCompare(b.keyword) || (a.page ?? "").localeCompare(b.page ?? "");
|
|
50
|
+
}
|
|
51
|
+
const SQL_SORT_EXPR = {
|
|
52
|
+
clicks: "recentClicks",
|
|
53
|
+
impressions: "recentImpressions",
|
|
54
|
+
clicksDelta: "ABS(clicksChange)",
|
|
55
|
+
clicksDeltaPercent: "ABS(clicksChangePercent)",
|
|
56
|
+
impressionsDelta: "ABS(impressionsChange)",
|
|
57
|
+
impressionsDeltaPercent: "ABS(impressionsChangePercent)",
|
|
58
|
+
positionDelta: "ABS(COALESCE(positionChange, 0))"
|
|
59
|
+
};
|
|
60
|
+
function selectMoversDirection(result, params, compare) {
|
|
61
|
+
const tag = (direction) => (r) => withCanonicalFields({
|
|
62
|
+
...r,
|
|
63
|
+
direction
|
|
64
|
+
});
|
|
65
|
+
const selected = params.direction === "rising" ? result.rising.map(tag("rising")) : params.direction === "declining" ? result.declining.map(tag("declining")) : [...result.rising.map(tag("rising")), ...result.declining.map(tag("declining"))].sort(compare);
|
|
66
|
+
const paged = paginateInMemory(selected, {
|
|
67
|
+
limit: params.limit ?? DEFAULT_MOVERS_LIMIT,
|
|
68
|
+
offset: params.offset
|
|
69
|
+
});
|
|
39
70
|
return {
|
|
40
|
-
results:
|
|
71
|
+
results: paged,
|
|
41
72
|
meta: {
|
|
42
|
-
total:
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
73
|
+
total: selected.length,
|
|
74
|
+
returned: paged.length,
|
|
75
|
+
rising: result.rising.length,
|
|
76
|
+
declining: result.declining.length,
|
|
77
|
+
stable: result.stable.length
|
|
46
78
|
}
|
|
47
79
|
};
|
|
48
80
|
}
|
|
81
|
+
function pairKey(query, page) {
|
|
82
|
+
return `${query}\u0000${page ?? ""}`;
|
|
83
|
+
}
|
|
84
|
+
function periodMap(rows, factor) {
|
|
85
|
+
const out = /* @__PURE__ */ new Map();
|
|
86
|
+
for (const row of rows) {
|
|
87
|
+
const page = row.page ?? null;
|
|
88
|
+
out.set(pairKey(row.query, page), {
|
|
89
|
+
query: row.query,
|
|
90
|
+
page,
|
|
91
|
+
clicks: num(row.clicks) / factor,
|
|
92
|
+
impressions: num(row.impressions) / factor,
|
|
93
|
+
position: num(row.position)
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
return out;
|
|
97
|
+
}
|
|
49
98
|
function analyzeMovers(input, options = {}) {
|
|
50
|
-
const { changeThreshold = .2, minImpressions = 50, sortBy =
|
|
51
|
-
const
|
|
52
|
-
const
|
|
53
|
-
clicks: num(r.clicks) / normFactor,
|
|
54
|
-
impressions: num(r.impressions) / normFactor,
|
|
55
|
-
position: num(r.position),
|
|
56
|
-
page: r.page ?? null
|
|
57
|
-
}));
|
|
58
|
-
const pageMap = /* @__PURE__ */ new Map();
|
|
59
|
-
for (const row of input.current) if (!pageMap.has(row.query) && row.page) pageMap.set(row.query, row.page);
|
|
60
|
-
for (const row of input.previous) if (!pageMap.has(row.query) && row.page) pageMap.set(row.query, row.page);
|
|
99
|
+
const { changeThreshold = .2, minImpressions = 50, sortBy = DEFAULT_SORT.sortBy, sortDir = DEFAULT_SORT.sortDir } = options;
|
|
100
|
+
const current = periodMap(input.current, 1);
|
|
101
|
+
const previous = periodMap(input.previous, input.normalizationFactor ?? 1);
|
|
61
102
|
const rising = [];
|
|
62
103
|
const declining = [];
|
|
63
104
|
const stable = [];
|
|
64
|
-
for (const
|
|
65
|
-
const
|
|
66
|
-
const
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
const
|
|
70
|
-
const baselineClicksRaw =
|
|
71
|
-
const baselineImpressionsRaw =
|
|
72
|
-
|
|
105
|
+
for (const key of /* @__PURE__ */ new Set([...current.keys(), ...previous.keys()])) {
|
|
106
|
+
const cur = current.get(key);
|
|
107
|
+
const prev = previous.get(key);
|
|
108
|
+
const identity = cur ?? prev;
|
|
109
|
+
const clicks = cur?.clicks ?? 0;
|
|
110
|
+
const impressions = cur?.impressions ?? 0;
|
|
111
|
+
const baselineClicksRaw = prev?.clicks ?? 0;
|
|
112
|
+
const baselineImpressionsRaw = prev?.impressions ?? 0;
|
|
113
|
+
if (Math.max(impressions, baselineImpressionsRaw) < minImpressions) continue;
|
|
114
|
+
const recentPosition = cur?.position ?? null;
|
|
115
|
+
const baselinePosition = prev?.position ?? null;
|
|
116
|
+
const baselineClicks = Math.round(baselineClicksRaw);
|
|
117
|
+
const baselineImpressions = Math.round(baselineImpressionsRaw);
|
|
73
118
|
const clicksChangePercent = percentDifference(clicks, baselineClicksRaw);
|
|
74
|
-
const impressionsChangePercent = percentDifference(impressions, baselineImpressionsRaw);
|
|
75
119
|
const data = {
|
|
76
|
-
keyword:
|
|
77
|
-
page:
|
|
120
|
+
keyword: identity.query,
|
|
121
|
+
page: identity.page,
|
|
78
122
|
recentClicks: clicks,
|
|
79
123
|
recentImpressions: impressions,
|
|
80
|
-
recentPosition
|
|
81
|
-
baselineClicks
|
|
82
|
-
baselineImpressions
|
|
124
|
+
recentPosition,
|
|
125
|
+
baselineClicks,
|
|
126
|
+
baselineImpressions,
|
|
83
127
|
baselinePosition,
|
|
84
|
-
clicksChange: clicks -
|
|
128
|
+
clicksChange: clicks - baselineClicks,
|
|
85
129
|
clicksChangePercent,
|
|
86
|
-
|
|
87
|
-
|
|
130
|
+
impressionsChange: impressions - baselineImpressions,
|
|
131
|
+
impressionsChangePercent: percentDifference(impressions, baselineImpressionsRaw),
|
|
132
|
+
positionChange: recentPosition != null && baselinePosition != null ? recentPosition - baselinePosition : null
|
|
88
133
|
};
|
|
89
134
|
const absChange = Math.abs(clicksChangePercent / 100);
|
|
90
135
|
if (clicksChangePercent > 0 && absChange >= changeThreshold) rising.push(data);
|
|
91
136
|
else if (clicksChangePercent < 0 && absChange >= changeThreshold) declining.push(data);
|
|
92
137
|
else stable.push(data);
|
|
93
138
|
}
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
case "impressions": return b.recentImpressions - a.recentImpressions;
|
|
98
|
-
case "clicksChange": return Math.abs(b.clicksChangePercent) - Math.abs(a.clicksChangePercent);
|
|
99
|
-
case "impressionsChange": return Math.abs(b.impressionsChangePercent) - Math.abs(a.impressionsChangePercent);
|
|
100
|
-
case "positionChange": return Math.abs(b.positionChange ?? 0) - Math.abs(a.positionChange ?? 0);
|
|
101
|
-
default: return Math.abs(b.clicksChangePercent) - Math.abs(a.clicksChangePercent);
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
rising.sort(sortFn);
|
|
105
|
-
declining.sort(sortFn);
|
|
139
|
+
const compare = moversComparator(sortBy, sortDir);
|
|
140
|
+
rising.sort(compare);
|
|
141
|
+
declining.sort(compare);
|
|
106
142
|
stable.sort((a, b) => b.recentClicks - a.recentClicks);
|
|
107
143
|
return {
|
|
108
144
|
rising,
|
|
@@ -110,13 +146,18 @@ function analyzeMovers(input, options = {}) {
|
|
|
110
146
|
stable
|
|
111
147
|
};
|
|
112
148
|
}
|
|
149
|
+
function resolveMoversSort(params) {
|
|
150
|
+
return resolveSort(params, MOVERS_SORT_METRICS, DEFAULT_SORT);
|
|
151
|
+
}
|
|
113
152
|
const moversAnalyzer = defineAnalyzer({
|
|
114
153
|
id: "movers",
|
|
115
154
|
buildSql(params) {
|
|
116
155
|
const { current: cur, previous: prev } = comparisonOf(params);
|
|
117
156
|
const minImpressions = params.minImpressions ?? 50;
|
|
118
157
|
const changeThreshold = params.changeThreshold ?? .2;
|
|
119
|
-
const
|
|
158
|
+
const { sortBy, sortDir } = resolveMoversSort(params);
|
|
159
|
+
const orderBy = `${SQL_SORT_EXPR[sortBy]} ${sortDir === "asc" ? "ASC" : "DESC"}, keyword ASC, page ASC`;
|
|
160
|
+
const directions = params.direction === "rising" ? `('rising')` : params.direction === "declining" ? `('declining')` : `('rising', 'declining')`;
|
|
120
161
|
return {
|
|
121
162
|
sql: `
|
|
122
163
|
WITH cur AS (
|
|
@@ -139,6 +180,67 @@ const moversAnalyzer = defineAnalyzer({
|
|
|
139
180
|
WHERE date >= ? AND date <= ?
|
|
140
181
|
GROUP BY query, url
|
|
141
182
|
),
|
|
183
|
+
joined AS (
|
|
184
|
+
SELECT
|
|
185
|
+
COALESCE(c.query, p.query) AS keyword,
|
|
186
|
+
COALESCE(c.url, p.url) AS page,
|
|
187
|
+
COALESCE(c.clicks, 0.0) AS recentClicks,
|
|
188
|
+
COALESCE(c.impressions, 0.0) AS recentImpressions,
|
|
189
|
+
c.position AS recentPosition,
|
|
190
|
+
COALESCE(p.clicks, 0.0) AS baselineClicks,
|
|
191
|
+
COALESCE(p.impressions, 0.0) AS baselineImpressions,
|
|
192
|
+
p.position AS baselinePosition
|
|
193
|
+
FROM cur c
|
|
194
|
+
FULL OUTER JOIN prev p ON c.query = p.query AND c.url = p.url
|
|
195
|
+
WHERE GREATEST(COALESCE(c.impressions, 0.0), COALESCE(p.impressions, 0.0)) >= ?
|
|
196
|
+
),
|
|
197
|
+
derived AS (
|
|
198
|
+
SELECT
|
|
199
|
+
*,
|
|
200
|
+
(recentClicks - baselineClicks) AS clicksChange,
|
|
201
|
+
CASE
|
|
202
|
+
WHEN baselineClicks = 0 THEN CASE WHEN recentClicks > 0 THEN 100.0 ELSE 0.0 END
|
|
203
|
+
ELSE (recentClicks - baselineClicks) * 100.0 / baselineClicks
|
|
204
|
+
END AS clicksChangePercent,
|
|
205
|
+
(recentImpressions - baselineImpressions) AS impressionsChange,
|
|
206
|
+
CASE
|
|
207
|
+
WHEN baselineImpressions = 0 THEN CASE WHEN recentImpressions > 0 THEN 100.0 ELSE 0.0 END
|
|
208
|
+
ELSE (recentImpressions - baselineImpressions) * 100.0 / baselineImpressions
|
|
209
|
+
END AS impressionsChangePercent,
|
|
210
|
+
CASE
|
|
211
|
+
WHEN recentPosition IS NOT NULL AND baselinePosition IS NOT NULL THEN (recentPosition - baselinePosition)
|
|
212
|
+
ELSE NULL
|
|
213
|
+
END AS positionChange
|
|
214
|
+
FROM joined
|
|
215
|
+
),
|
|
216
|
+
classified AS (
|
|
217
|
+
SELECT
|
|
218
|
+
*,
|
|
219
|
+
CASE
|
|
220
|
+
WHEN clicksChangePercent > 0 AND ABS(clicksChangePercent) / 100.0 >= ? THEN 'rising'
|
|
221
|
+
WHEN clicksChangePercent < 0 AND ABS(clicksChangePercent) / 100.0 >= ? THEN 'declining'
|
|
222
|
+
ELSE 'stable'
|
|
223
|
+
END AS direction
|
|
224
|
+
FROM derived
|
|
225
|
+
),
|
|
226
|
+
counted AS (
|
|
227
|
+
SELECT
|
|
228
|
+
*,
|
|
229
|
+
CAST(SUM(CASE WHEN direction = 'rising' THEN 1 ELSE 0 END) OVER () AS DOUBLE) AS risingCount,
|
|
230
|
+
CAST(SUM(CASE WHEN direction = 'declining' THEN 1 ELSE 0 END) OVER () AS DOUBLE) AS decliningCount,
|
|
231
|
+
CAST(SUM(CASE WHEN direction = 'stable' THEN 1 ELSE 0 END) OVER () AS DOUBLE) AS stableCount
|
|
232
|
+
FROM classified
|
|
233
|
+
),
|
|
234
|
+
selected AS (
|
|
235
|
+
SELECT *
|
|
236
|
+
FROM counted
|
|
237
|
+
WHERE direction IN ${directions}
|
|
238
|
+
ORDER BY ${orderBy}
|
|
239
|
+
${paginateClause({
|
|
240
|
+
limit: params.limit ?? DEFAULT_MOVERS_LIMIT,
|
|
241
|
+
offset: params.offset
|
|
242
|
+
})}
|
|
243
|
+
),
|
|
142
244
|
weekly AS (
|
|
143
245
|
SELECT query, url, date_trunc('week', CAST(date AS DATE)) AS week,
|
|
144
246
|
${METRIC_EXPR.clicks} AS clicks,
|
|
@@ -151,7 +253,8 @@ const moversAnalyzer = defineAnalyzer({
|
|
|
151
253
|
SELECT query, url, date, clicks, impressions
|
|
152
254
|
FROM read_parquet({{FILES_PREV}}, union_by_name = true)
|
|
153
255
|
WHERE date >= ? AND date <= ?
|
|
154
|
-
)
|
|
256
|
+
) u
|
|
257
|
+
SEMI JOIN selected ON u.query = selected.keyword AND u.url = selected.page
|
|
155
258
|
GROUP BY query, url, week
|
|
156
259
|
),
|
|
157
260
|
series_by_entity AS (
|
|
@@ -161,55 +264,24 @@ const moversAnalyzer = defineAnalyzer({
|
|
|
161
264
|
'impressions': impressions
|
|
162
265
|
} ORDER BY week)) AS seriesJson
|
|
163
266
|
FROM weekly GROUP BY query, url
|
|
164
|
-
),
|
|
165
|
-
joined AS (
|
|
166
|
-
SELECT
|
|
167
|
-
c.query AS keyword,
|
|
168
|
-
c.url AS page,
|
|
169
|
-
c.clicks AS recentClicks,
|
|
170
|
-
c.impressions AS recentImpressions,
|
|
171
|
-
c.position AS recentPosition,
|
|
172
|
-
COALESCE(p.clicks, 0.0) AS baselineClicks,
|
|
173
|
-
COALESCE(p.impressions, 0.0) AS baselineImpressions,
|
|
174
|
-
p.position AS baselinePosition,
|
|
175
|
-
(c.clicks - COALESCE(p.clicks, 0.0)) AS clicksChange,
|
|
176
|
-
CASE
|
|
177
|
-
WHEN COALESCE(p.clicks, 0.0) = 0 THEN CASE WHEN c.clicks > 0 THEN 100.0 ELSE 0.0 END
|
|
178
|
-
ELSE (c.clicks - p.clicks) * 100.0 / p.clicks
|
|
179
|
-
END AS clicksChangePercent,
|
|
180
|
-
CASE
|
|
181
|
-
WHEN COALESCE(p.impressions, 0.0) = 0 THEN CASE WHEN c.impressions > 0 THEN 100.0 ELSE 0.0 END
|
|
182
|
-
ELSE (c.impressions - p.impressions) * 100.0 / p.impressions
|
|
183
|
-
END AS impressionsChangePercent,
|
|
184
|
-
CASE WHEN p.position IS NOT NULL THEN (c.position - p.position) ELSE NULL END AS positionChange,
|
|
185
|
-
s.seriesJson
|
|
186
|
-
FROM cur c
|
|
187
|
-
LEFT JOIN prev p ON c.query = p.query AND c.url = p.url
|
|
188
|
-
LEFT JOIN series_by_entity s ON c.query = s.query AND c.url = s.url
|
|
189
|
-
WHERE c.impressions >= ?
|
|
190
267
|
)
|
|
191
|
-
SELECT
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
ELSE 'stable'
|
|
196
|
-
END AS direction
|
|
197
|
-
FROM joined
|
|
198
|
-
ORDER BY ABS(clicksChangePercent) DESC
|
|
199
|
-
LIMIT ${Number(limit)}
|
|
268
|
+
SELECT selected.*, s.seriesJson
|
|
269
|
+
FROM selected
|
|
270
|
+
LEFT JOIN series_by_entity s ON selected.keyword = s.query AND selected.page = s.url
|
|
271
|
+
ORDER BY ${orderBy}
|
|
200
272
|
`,
|
|
201
273
|
params: [
|
|
202
274
|
cur.startDate,
|
|
203
275
|
cur.endDate,
|
|
204
276
|
prev.startDate,
|
|
205
277
|
prev.endDate,
|
|
278
|
+
minImpressions,
|
|
279
|
+
changeThreshold,
|
|
280
|
+
changeThreshold,
|
|
206
281
|
cur.startDate,
|
|
207
282
|
cur.endDate,
|
|
208
283
|
prev.startDate,
|
|
209
|
-
prev.endDate
|
|
210
|
-
minImpressions,
|
|
211
|
-
changeThreshold,
|
|
212
|
-
changeThreshold
|
|
284
|
+
prev.endDate
|
|
213
285
|
],
|
|
214
286
|
current: {
|
|
215
287
|
table: "page_queries",
|
|
@@ -222,41 +294,48 @@ const moversAnalyzer = defineAnalyzer({
|
|
|
222
294
|
};
|
|
223
295
|
},
|
|
224
296
|
reduceSql(rows, params) {
|
|
225
|
-
const
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
297
|
+
const arr = Array.isArray(rows) ? rows : [];
|
|
298
|
+
const results = arr.map((r) => withCanonicalFields({
|
|
299
|
+
keyword: rowString(r.keyword),
|
|
300
|
+
page: r.page == null ? null : rowString(r.page),
|
|
301
|
+
recentClicks: num(r.recentClicks),
|
|
302
|
+
recentImpressions: num(r.recentImpressions),
|
|
303
|
+
recentPosition: r.recentPosition == null ? null : num(r.recentPosition),
|
|
304
|
+
baselineClicks: Math.round(num(r.baselineClicks)),
|
|
305
|
+
baselineImpressions: Math.round(num(r.baselineImpressions)),
|
|
306
|
+
baselinePosition: r.baselinePosition == null ? null : num(r.baselinePosition),
|
|
307
|
+
clicksChange: num(r.clicksChange),
|
|
308
|
+
clicksChangePercent: num(r.clicksChangePercent),
|
|
309
|
+
impressionsChange: num(r.impressionsChange),
|
|
310
|
+
impressionsChangePercent: num(r.impressionsChangePercent),
|
|
311
|
+
positionChange: r.positionChange == null ? null : num(r.positionChange),
|
|
312
|
+
direction: rowString(r.direction),
|
|
313
|
+
series: parseJsonRows(r.seriesJson).map((s) => ({
|
|
314
|
+
week: rowString(s.week),
|
|
315
|
+
clicks: num(s.clicks),
|
|
316
|
+
impressions: num(s.impressions)
|
|
317
|
+
}))
|
|
318
|
+
}));
|
|
319
|
+
const first = arr[0];
|
|
320
|
+
const rising = num(first?.risingCount);
|
|
321
|
+
const declining = num(first?.decliningCount);
|
|
322
|
+
const stable = num(first?.stableCount);
|
|
323
|
+
return {
|
|
324
|
+
results,
|
|
325
|
+
meta: {
|
|
326
|
+
total: params.direction === "rising" ? rising : params.direction === "declining" ? declining : rising + declining,
|
|
327
|
+
returned: results.length,
|
|
328
|
+
rising,
|
|
329
|
+
declining,
|
|
330
|
+
stable
|
|
331
|
+
}
|
|
332
|
+
};
|
|
254
333
|
},
|
|
255
334
|
buildRows(params) {
|
|
256
335
|
const { current, previous } = comparisonOf(params);
|
|
257
336
|
return {
|
|
258
|
-
current: queriesQueryState(current, params
|
|
259
|
-
previous: queriesQueryState(previous, params
|
|
337
|
+
current: queriesQueryState(current, fetchBudgetOf(params)),
|
|
338
|
+
previous: queriesQueryState(previous, fetchBudgetOf(params))
|
|
260
339
|
};
|
|
261
340
|
},
|
|
262
341
|
reduceRows(rows, params) {
|
|
@@ -264,20 +343,18 @@ const moversAnalyzer = defineAnalyzer({
|
|
|
264
343
|
current: [],
|
|
265
344
|
previous: []
|
|
266
345
|
};
|
|
267
|
-
const
|
|
268
|
-
|
|
269
|
-
|
|
346
|
+
const current = map.current ?? [];
|
|
347
|
+
const previous = map.previous ?? [];
|
|
348
|
+
const { sortBy, sortDir } = resolveMoversSort(params);
|
|
349
|
+
return selectMoversDirection(analyzeMovers({
|
|
350
|
+
current,
|
|
351
|
+
previous
|
|
270
352
|
}, {
|
|
271
353
|
changeThreshold: params.changeThreshold,
|
|
272
|
-
minImpressions: params.minImpressions
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
direction: "rising"
|
|
277
|
-
})), result.declining.map((r) => withCanonicalFields({
|
|
278
|
-
...r,
|
|
279
|
-
direction: "declining"
|
|
280
|
-
})), [], params);
|
|
354
|
+
minImpressions: params.minImpressions,
|
|
355
|
+
sortBy,
|
|
356
|
+
sortDir
|
|
357
|
+
}), params, moversComparator(sortBy, sortDir));
|
|
281
358
|
}
|
|
282
359
|
});
|
|
283
|
-
export { analyzeMovers, moversAnalyzer };
|
|
360
|
+
export { MOVERS_SORT_METRICS, analyzeMovers, moversAnalyzer };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { queriesQueryState } from "../analyzer/adapt-rows.mjs";
|
|
2
|
-
import { paginateClause, paginateSortedInMemory } from "../analyzer/paginate.mjs";
|
|
3
|
-
import { num } from "@gscdump/engine/analysis-types";
|
|
2
|
+
import { TOTAL_COUNT_SELECT, paginateClause, paginateSortedInMemory, totalCountOf } from "../analyzer/paginate.mjs";
|
|
3
|
+
import { fetchBudgetOf, num } from "@gscdump/engine/analysis-types";
|
|
4
4
|
import { defineAnalyzer } from "@gscdump/engine/analyzer";
|
|
5
5
|
import { periodOf } from "@gscdump/engine/period";
|
|
6
6
|
import { enumeratePartitions } from "@gscdump/engine/planner";
|
|
@@ -151,7 +151,8 @@ const opportunityAnalyzer = defineAnalyzer({
|
|
|
151
151
|
ELSE 0.10
|
|
152
152
|
END
|
|
153
153
|
)) AS DOUBLE) AS potentialClicks,
|
|
154
|
-
positionScore, impressionScore, ctrGapScore
|
|
154
|
+
positionScore, impressionScore, ctrGapScore,
|
|
155
|
+
${TOTAL_COUNT_SELECT}
|
|
155
156
|
FROM gapped
|
|
156
157
|
ORDER BY opportunityScore DESC
|
|
157
158
|
${paginateClause({
|
|
@@ -188,11 +189,14 @@ const opportunityAnalyzer = defineAnalyzer({
|
|
|
188
189
|
ctrGapScore: num(r.ctrGapScore)
|
|
189
190
|
}
|
|
190
191
|
})),
|
|
191
|
-
meta: {
|
|
192
|
+
meta: {
|
|
193
|
+
total: totalCountOf(arr),
|
|
194
|
+
returned: arr.length
|
|
195
|
+
}
|
|
192
196
|
};
|
|
193
197
|
},
|
|
194
198
|
buildRows(params) {
|
|
195
|
-
return { queries: queriesQueryState(periodOf(params), params
|
|
199
|
+
return { queries: queriesQueryState(periodOf(params), fetchBudgetOf(params)) };
|
|
196
200
|
},
|
|
197
201
|
reduceRows(rows, params) {
|
|
198
202
|
const results = analyzeOpportunity((Array.isArray(rows) ? rows : []) ?? [], { minImpressions: params.minImpressions });
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { datesQueryState } from "../analyzer/adapt-rows.mjs";
|
|
2
2
|
import { rowBoolean, rowString } from "../analyzer/row-values.mjs";
|
|
3
|
-
import { num } from "@gscdump/engine/analysis-types";
|
|
3
|
+
import { fetchBudgetOf, num } from "@gscdump/engine/analysis-types";
|
|
4
4
|
import { defineAnalyzer } from "@gscdump/engine/analyzer";
|
|
5
5
|
import { periodOf } from "@gscdump/engine/period";
|
|
6
6
|
import { enumeratePartitions } from "@gscdump/engine/planner";
|
|
@@ -123,13 +123,16 @@ const seasonalityAnalyzer = defineAnalyzer({
|
|
|
123
123
|
};
|
|
124
124
|
},
|
|
125
125
|
buildRows(params) {
|
|
126
|
-
return { dates: datesQueryState(periodOf(params), params
|
|
126
|
+
return { dates: datesQueryState(periodOf(params), fetchBudgetOf(params)) };
|
|
127
127
|
},
|
|
128
128
|
reduceRows(rows, params) {
|
|
129
129
|
const result = analyzeSeasonality(Array.isArray(rows) ? rows : [], { metric: params.metric });
|
|
130
130
|
return {
|
|
131
131
|
results: result.monthlyBreakdown,
|
|
132
|
-
meta: {
|
|
132
|
+
meta: {
|
|
133
|
+
total: result.monthlyBreakdown.length,
|
|
134
|
+
strength: result.strength
|
|
135
|
+
}
|
|
133
136
|
};
|
|
134
137
|
}
|
|
135
138
|
});
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { queriesQueryState } from "../analyzer/adapt-rows.mjs";
|
|
2
2
|
import { paginateSortedInMemory } from "../analyzer/paginate.mjs";
|
|
3
|
-
import { num } from "@gscdump/engine/analysis-types";
|
|
3
|
+
import { fetchBudgetOf, num } from "@gscdump/engine/analysis-types";
|
|
4
4
|
import { defineAnalyzer } from "@gscdump/engine/analyzer";
|
|
5
5
|
import { periodOf } from "@gscdump/engine/period";
|
|
6
6
|
import { enumeratePartitions } from "@gscdump/engine/planner";
|
|
7
|
-
const DEFAULT_ROW_LIMIT = 25e3;
|
|
8
7
|
function paginateStrikingDistance(results, options) {
|
|
9
8
|
return paginateSortedInMemory(results, {
|
|
10
9
|
limit: options.limit ?? 1e3,
|
|
@@ -76,7 +75,7 @@ const strikingDistanceAnalyzer = defineAnalyzer({
|
|
|
76
75
|
};
|
|
77
76
|
},
|
|
78
77
|
buildRows(params) {
|
|
79
|
-
return { queries: queriesQueryState(periodOf(params), params
|
|
78
|
+
return { queries: queriesQueryState(periodOf(params), fetchBudgetOf(params)) };
|
|
80
79
|
}
|
|
81
80
|
});
|
|
82
81
|
export { analyzeStrikingDistance, filterStrikingDistance, strikingDistanceAnalyzer };
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { queriesQueryState } from "../analyzer/adapt-rows.mjs";
|
|
2
|
+
import { TOTAL_COUNT_SELECT, paginateClause, paginateSortedInMemory, totalCountOf } from "../analyzer/paginate.mjs";
|
|
3
|
+
import { fetchBudgetOf, num } from "@gscdump/engine/analysis-types";
|
|
3
4
|
import { defineAnalyzer } from "@gscdump/engine/analyzer";
|
|
4
5
|
import { periodOf } from "@gscdump/engine/period";
|
|
5
6
|
import { enumeratePartitions } from "@gscdump/engine/planner";
|
|
6
7
|
import { METRIC_EXPR } from "@gscdump/engine/sql-fragments";
|
|
7
|
-
import { between, date, gsc, page, query } from "gscdump/query";
|
|
8
|
-
const DEFAULT_ROW_LIMIT = 25e3;
|
|
9
8
|
function analyzeZeroClick(rows, options = {}) {
|
|
10
9
|
const minImpressions = options.minImpressions ?? 1e3;
|
|
11
10
|
const maxCtr = options.maxCtr ?? .03;
|
|
@@ -50,7 +49,8 @@ const zeroClickAnalyzer = defineAnalyzer({
|
|
|
50
49
|
WHEN position <= 5 THEN 0.08
|
|
51
50
|
ELSE 0.04
|
|
52
51
|
END
|
|
53
|
-
)) - clicks) AS DOUBLE) AS missedClicks
|
|
52
|
+
)) - clicks) AS DOUBLE) AS missedClicks,
|
|
53
|
+
${TOTAL_COUNT_SELECT}
|
|
54
54
|
FROM agg
|
|
55
55
|
WHERE position <= ? AND ctr < ?
|
|
56
56
|
ORDER BY impressions DESC
|
|
@@ -88,7 +88,8 @@ const zeroClickAnalyzer = defineAnalyzer({
|
|
|
88
88
|
missedClicks: num(r.missedClicks)
|
|
89
89
|
})),
|
|
90
90
|
meta: {
|
|
91
|
-
total: arr
|
|
91
|
+
total: totalCountOf(arr),
|
|
92
|
+
returned: arr.length,
|
|
92
93
|
minImpressions,
|
|
93
94
|
maxCtr,
|
|
94
95
|
maxPosition
|
|
@@ -96,9 +97,7 @@ const zeroClickAnalyzer = defineAnalyzer({
|
|
|
96
97
|
};
|
|
97
98
|
},
|
|
98
99
|
buildRows(params) {
|
|
99
|
-
|
|
100
|
-
const limit = params.limit ?? DEFAULT_ROW_LIMIT;
|
|
101
|
-
return { rows: gsc.select(query, page).where(between(date, period.startDate, period.endDate)).limit(limit).getState() };
|
|
100
|
+
return { rows: queriesQueryState(periodOf(params), fetchBudgetOf(params)) };
|
|
102
101
|
},
|
|
103
102
|
reduceRows(rows, params) {
|
|
104
103
|
const results = analyzeZeroClick(Array.isArray(rows) ? rows : [], {
|
package/dist/index.d.mts
CHANGED
|
@@ -4,7 +4,7 @@ import { CannibalizationCompetitor, CannibalizationEvent, CannibalizationOptions
|
|
|
4
4
|
import { ClusterType, ClusteringOptions, ClusteringResult, KeywordCluster, analyzeClustering } from "./analyzers/clustering.mjs";
|
|
5
5
|
import { ConcentrationInput, ConcentrationItem, ConcentrationOptions, ConcentrationResult, ConcentrationRiskLevel, analyzeConcentration, analyzeKeywordConcentration, analyzePageConcentration } from "./analyzers/concentration.mjs";
|
|
6
6
|
import { DecayInput, DecayOptions, DecayResult, DecaySeriesPoint, DecaySortMetric, analyzeDecay } from "./analyzers/decay.mjs";
|
|
7
|
-
import { MoverData, MoversInput, MoversOptions, MoversResult, MoversSortMetric, analyzeMovers } from "./analyzers/movers.mjs";
|
|
7
|
+
import { MOVERS_SORT_METRICS, MoverData, MoversInput, MoversOptions, MoversResult, MoversSortMetric, analyzeMovers } from "./analyzers/movers.mjs";
|
|
8
8
|
import { OpportunityFactors, OpportunityOptions, OpportunityResult, OpportunitySortMetric, OpportunityWeights, analyzeOpportunity } from "./analyzers/opportunity.mjs";
|
|
9
9
|
import { MonthlyData, SeasonalityMetric, SeasonalityOptions, SeasonalityResult, analyzeSeasonality } from "./analyzers/seasonality.mjs";
|
|
10
10
|
import { StrikingDistanceInputRow, StrikingDistanceOptions, StrikingDistanceResult, analyzeStrikingDistance } from "./analyzers/striking-distance.mjs";
|
|
@@ -18,4 +18,4 @@ import { Analyzer, AnalyzerCapabilityError, AnalyzerRegistry, AnalyzerRegistryIn
|
|
|
18
18
|
import { AnalysisPeriod, ComparisonMode, ComparisonPeriod, PadTimeseriesOptions, ResolveWindowOptions, ResolvedWindow, WindowPreset, comparisonOf, padTimeseries, periodOf, resolveWindow } from "@gscdump/engine/period";
|
|
19
19
|
import { AnalysisQuerySource, AnalysisSourceKind, ENGINE_QUERY_CAPABILITIES, EngineQuerySourceOptions, ExecuteSqlOptions, FileSet, QueryRow, SourceCapabilities, createEngineQuerySource, queryRows, runAnalyzerWithEngine } from "@gscdump/engine/source";
|
|
20
20
|
import { DefineReportOptions, DefinedReport, ReportContext, ReportFinding, ReportPlanStep, ReportResult, ReportSection } from "@gscdump/engine/report";
|
|
21
|
-
export { type AnalysisParams, type AnalysisPeriod, type AnalysisQuerySource, type AnalysisResult, type AnalysisSourceKind, type AnalysisTool, type Analyzer, AnalyzerCapabilityError, type AnalyzerRegistry, type AnalyzerRegistryInit, type AnalyzerRunner, type AnalyzerVariants, type BaseMetrics, type BrandSegmentationOptions, type BrandSegmentationResult, type BrandSegmentationRow, type BrandSummary, type BrowserAnalyzeOptions, type CannibalizationCompetitor, type CannibalizationEvent, type CannibalizationOptions, type CannibalizationPage, type CannibalizationResult, type CannibalizationSortMetric, type ClusterType, type ClusteringOptions, type ClusteringResult, type ComparisonMode, type ComparisonPeriod, type ConcentrationInput, type ConcentrationItem, type ConcentrationOptions, type ConcentrationResult, type ConcentrationRiskLevel, type CurrentSitemapScope, type DateRow, type DecayInput, type DecayOptions, type DecayResult, type DecaySeriesPoint, type DecaySortMetric, type DefineAnalyzerOptions, type DefineReportOptions, type DefinedAnalyzer, type DefinedReport, ENGINE_QUERY_CAPABILITIES, type EngineQuerySourceOptions, type ExecuteSqlOptions, type FileSet, INTENT_CLASSIFIER_VERSION, type IntentClassification, type KeywordCluster, type MonthlyData, type MoverData, type MoversInput, type MoversOptions, type MoversResult, type MoversSortMetric, NORMALIZER_VERSION, type OpportunityFactors, type OpportunityOptions, type OpportunityResult, type OpportunitySortMetric, type OpportunityWeights, type PadTimeseriesOptions, type PageRow, type Plan, type QueriesRow, type QueryPageRow, type QueryRow, type ReduceContext, type ReduceCtx, type Reducer, type ReportContext, type ReportFinding, type ReportPlanStep, type ReportResult, type ReportSection, type RequiredCapability, type ResolveWindowOptions, type ResolvedWindow, type RowQueriesPlan, SEARCH_INTENT_CODE, SITEMAP_SYNC_COLLAPSE_POLICY, SITEMAP_TRUST_COLLAPSE_POLICY, type SearchIntent, type SeasonalityMetric, type SeasonalityOptions, type SeasonalityResult, type SitemapCollapsePolicy, type SitemapCollapseState, type SitemapDelta, type SitemapHealthDiff, type SitemapHealthInput, type SitemapHealthRow, type SitemapHealthTotals, type SortOrder, type SourceCapabilities, type SqlExtraQuery, type SqlPlan, type SqlPlanSpec, type StrikingDistanceInputRow, type StrikingDistanceOptions, type StrikingDistanceResult, type TypedRowQuery, type WindowPreset, type ZeroClickOptions, type ZeroClickResult, analyzeBrandSegmentation, analyzeCannibalization, analyzeClustering, analyzeConcentration, analyzeDecay, analyzeInBrowser, analyzeKeywordConcentration, analyzeMovers, analyzeOpportunity, analyzePageConcentration, analyzeSeasonality, analyzeStrikingDistance, analyzeZeroClick, classifyQueryIntent, classifySitemapCollapse, compareCurrentSitemapScope, comparisonOf, createAnalyzerRegistry, createEngineQuerySource, createSorter, defineAnalyzer, diffSitemapHealth, encodeIntent, normalizeQuery, num, padTimeseries, periodOf, queryRows, resolveWindow, runAnalyzerFromSource, runAnalyzerWithEngine, sitemapHistoryHasCollapse };
|
|
21
|
+
export { type AnalysisParams, type AnalysisPeriod, type AnalysisQuerySource, type AnalysisResult, type AnalysisSourceKind, type AnalysisTool, type Analyzer, AnalyzerCapabilityError, type AnalyzerRegistry, type AnalyzerRegistryInit, type AnalyzerRunner, type AnalyzerVariants, type BaseMetrics, type BrandSegmentationOptions, type BrandSegmentationResult, type BrandSegmentationRow, type BrandSummary, type BrowserAnalyzeOptions, type CannibalizationCompetitor, type CannibalizationEvent, type CannibalizationOptions, type CannibalizationPage, type CannibalizationResult, type CannibalizationSortMetric, type ClusterType, type ClusteringOptions, type ClusteringResult, type ComparisonMode, type ComparisonPeriod, type ConcentrationInput, type ConcentrationItem, type ConcentrationOptions, type ConcentrationResult, type ConcentrationRiskLevel, type CurrentSitemapScope, type DateRow, type DecayInput, type DecayOptions, type DecayResult, type DecaySeriesPoint, type DecaySortMetric, type DefineAnalyzerOptions, type DefineReportOptions, type DefinedAnalyzer, type DefinedReport, ENGINE_QUERY_CAPABILITIES, type EngineQuerySourceOptions, type ExecuteSqlOptions, type FileSet, INTENT_CLASSIFIER_VERSION, type IntentClassification, type KeywordCluster, MOVERS_SORT_METRICS, type MonthlyData, type MoverData, type MoversInput, type MoversOptions, type MoversResult, type MoversSortMetric, NORMALIZER_VERSION, type OpportunityFactors, type OpportunityOptions, type OpportunityResult, type OpportunitySortMetric, type OpportunityWeights, type PadTimeseriesOptions, type PageRow, type Plan, type QueriesRow, type QueryPageRow, type QueryRow, type ReduceContext, type ReduceCtx, type Reducer, type ReportContext, type ReportFinding, type ReportPlanStep, type ReportResult, type ReportSection, type RequiredCapability, type ResolveWindowOptions, type ResolvedWindow, type RowQueriesPlan, SEARCH_INTENT_CODE, SITEMAP_SYNC_COLLAPSE_POLICY, SITEMAP_TRUST_COLLAPSE_POLICY, type SearchIntent, type SeasonalityMetric, type SeasonalityOptions, type SeasonalityResult, type SitemapCollapsePolicy, type SitemapCollapseState, type SitemapDelta, type SitemapHealthDiff, type SitemapHealthInput, type SitemapHealthRow, type SitemapHealthTotals, type SortOrder, type SourceCapabilities, type SqlExtraQuery, type SqlPlan, type SqlPlanSpec, type StrikingDistanceInputRow, type StrikingDistanceOptions, type StrikingDistanceResult, type TypedRowQuery, type WindowPreset, type ZeroClickOptions, type ZeroClickResult, analyzeBrandSegmentation, analyzeCannibalization, analyzeClustering, analyzeConcentration, analyzeDecay, analyzeInBrowser, analyzeKeywordConcentration, analyzeMovers, analyzeOpportunity, analyzePageConcentration, analyzeSeasonality, analyzeStrikingDistance, analyzeZeroClick, classifyQueryIntent, classifySitemapCollapse, compareCurrentSitemapScope, comparisonOf, createAnalyzerRegistry, createEngineQuerySource, createSorter, defineAnalyzer, diffSitemapHealth, encodeIntent, normalizeQuery, num, padTimeseries, periodOf, queryRows, resolveWindow, runAnalyzerFromSource, runAnalyzerWithEngine, sitemapHistoryHasCollapse };
|
package/dist/index.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { analyzeCannibalization } from "./analyzers/cannibalization.mjs";
|
|
|
4
4
|
import { analyzeClustering } from "./analyzers/clustering.mjs";
|
|
5
5
|
import { analyzeConcentration, analyzeKeywordConcentration, analyzePageConcentration } from "./analyzers/concentration.mjs";
|
|
6
6
|
import { analyzeDecay } from "./analyzers/decay.mjs";
|
|
7
|
-
import { analyzeMovers } from "./analyzers/movers.mjs";
|
|
7
|
+
import { MOVERS_SORT_METRICS, analyzeMovers } from "./analyzers/movers.mjs";
|
|
8
8
|
import { analyzeOpportunity } from "./analyzers/opportunity.mjs";
|
|
9
9
|
import { analyzeSeasonality } from "./analyzers/seasonality.mjs";
|
|
10
10
|
import { analyzeStrikingDistance } from "./analyzers/striking-distance.mjs";
|
|
@@ -17,4 +17,4 @@ import { num } from "@gscdump/engine/analysis-types";
|
|
|
17
17
|
import { AnalyzerCapabilityError, createAnalyzerRegistry, defineAnalyzer, runAnalyzerFromSource } from "@gscdump/engine/analyzer";
|
|
18
18
|
import { comparisonOf, padTimeseries, periodOf, resolveWindow } from "@gscdump/engine/period";
|
|
19
19
|
import { ENGINE_QUERY_CAPABILITIES, createEngineQuerySource, queryRows, runAnalyzerWithEngine } from "@gscdump/engine/source";
|
|
20
|
-
export { AnalyzerCapabilityError, ENGINE_QUERY_CAPABILITIES, INTENT_CLASSIFIER_VERSION, NORMALIZER_VERSION, SEARCH_INTENT_CODE, SITEMAP_SYNC_COLLAPSE_POLICY, SITEMAP_TRUST_COLLAPSE_POLICY, analyzeBrandSegmentation, analyzeCannibalization, analyzeClustering, analyzeConcentration, analyzeDecay, analyzeInBrowser, analyzeKeywordConcentration, analyzeMovers, analyzeOpportunity, analyzePageConcentration, analyzeSeasonality, analyzeStrikingDistance, analyzeZeroClick, classifyQueryIntent, classifySitemapCollapse, compareCurrentSitemapScope, comparisonOf, createAnalyzerRegistry, createEngineQuerySource, createSorter, defineAnalyzer, diffSitemapHealth, encodeIntent, normalizeQuery, num, padTimeseries, periodOf, queryRows, resolveWindow, runAnalyzerFromSource, runAnalyzerWithEngine, sitemapHistoryHasCollapse };
|
|
20
|
+
export { AnalyzerCapabilityError, ENGINE_QUERY_CAPABILITIES, INTENT_CLASSIFIER_VERSION, MOVERS_SORT_METRICS, NORMALIZER_VERSION, SEARCH_INTENT_CODE, SITEMAP_SYNC_COLLAPSE_POLICY, SITEMAP_TRUST_COLLAPSE_POLICY, analyzeBrandSegmentation, analyzeCannibalization, analyzeClustering, analyzeConcentration, analyzeDecay, analyzeInBrowser, analyzeKeywordConcentration, analyzeMovers, analyzeOpportunity, analyzePageConcentration, analyzeSeasonality, analyzeStrikingDistance, analyzeZeroClick, classifyQueryIntent, classifySitemapCollapse, compareCurrentSitemapScope, comparisonOf, createAnalyzerRegistry, createEngineQuerySource, createSorter, defineAnalyzer, diffSitemapHealth, encodeIntent, normalizeQuery, num, padTimeseries, periodOf, queryRows, resolveWindow, runAnalyzerFromSource, runAnalyzerWithEngine, sitemapHistoryHasCollapse };
|