編寫與除錯 CQL
CQL 是 Croct 的類英語查詢語言。相同的表達式語法可支援受眾、來自 SDK 與 HTTP API 的即時評估,以及動態內容值。此處所有內容均來自 docs.croct.com;當有內容未涵蓋時,請查閱線上文檔(位於此檔案底部),切勿自行猜測。
工作流程
- 識別查詢的執行位置:受眾(必須為布林值)、
evaluate/API(任何 JSON 值,最多 500 個字元)或動態值(結果必須符合屬性型別,否則使用default)。 - 選擇資料來源:當前上下文(
page、cart、location、campaign、device)、儲存的個人檔案(user's ...、user's stats)、工作階段(session's ...)或歷史記錄(user has ...事件表達式,Scale 方案)。 - 檢查資料是否已收集:任何標記為 需要整合 的內容(個人檔案屬性、購物車、興趣、目標、登入狀態)在應用程式尚未發送資料前,永遠不會匹配。
- 使用下方的速查表進行編寫;如需查詢確切屬性,請參閱 context-and-data-types.md。
- 執行陷阱檢查清單,然後使用
croct.evaluate()或儀表板估算工具進行測試。
速查表
// 自然、技術與混合風格均可互換
user's score is greater than 90
user.score > 90
user's score > 90
| 需求 | 語法 |
|---|---|
| 屬性 | user's address's city、user's stats' orders、property city of user's address、user.address.city |
| 特殊鍵值 / 索引 | page.query['coupon-code']、list[0]、(user's interests)[0] |
| 選擇器 | cart.items[1st]、[:first]、[:last(2)]、items[*].price、data[...].price |
| 字面值 | null、true、42、3.14 (十進位)、3.14f、51%、"str"、'raw'、~/re/i、[1, 2]、["k": "v"] |
| 日期 | 無字面值:"2026-01-01" as date、"2026-01-01T12:00" as datetime;today + 1 day |
| 邏輯 | and or not (&& || !);and 的綁定優先級高於 or |
| 比較 | == != > >= < <=;1 < x < 3;is equal to X ignoring case |
| 字面值簡寫 | X is "value"、X is not 0(右側必須是字面值) |
| 字串 | starts with、ends with、matches "sub" / matches ~/re/i (區分大小寫)、is like "sub" (不區分大小寫) |
| 集合 | contains X、X is in [..]、contains all of [..]、contains either [..]、contains neither [..] |
| 存在性 | is defined / is known、is empty |
| 使用者/工作階段 | user is returning、user is anonymous、user is identified、session is starting |
| 日期 | is before、is after、is at "12:00"、is between A and B [exclusive]、today's weekday is "monday" |
| 量詞 | some x in C satisfies P、every、no、not every、at least 2 of any [distinct] x in C satisfies P |
| 巨集 | count of、sum of、average of、min of、max of、first of、last of、keys of、length of、number of days between A and B、this month |
| 修飾符 | as number、rounded [down]、in title case、sorted descending、without duplicates、replacing "a" with "b"、today at "12:00" |
| 備用值 | user's name or else "Anonymous" (??) |
| 條件式 | "A" if cond otherwise "B"、cond ? "A" : "B" |
| 變數 | let orders = user's stats' orders; orders >= 5 |
| 事件 (Scale) | user has <event> [with prop value] [at least N times] [in last 7 days] |
| 註解 | // line、# line、/* block */ |
關鍵字與識別碼不區分大小寫;字串字面值則區分大小寫。
上下文速覽
| 變數 | 常用屬性 |
|---|---|
user | id、firstName、email、age、company、jobTitle、interests、activities、stats' sessions、stats' orders、任何自訂屬性 |
session | start、duration、landingPage、referrer、stats' pageviews、stats' orders、audiences、experiences、experiments、自訂屬性 |
page (網頁) | title、url、path、query、anchor、referrer |
location | continentCode、countryCode、countryName、stateCode/regionCode (state's code 的別名)、stateName、cityName、timeZone、tags |
device / browser | category (desktop、tablet、mobile、bot、...)、vendor、name、os;browser's name、type |
campaign | name、source、medium、content、term (UTM) |
cart | stage (browsing、shopping、checkout)、items、total、subtotal、coupon、discount |
context | timeZone、在評估時傳入的屬性 |
now、today、yesterday、tomorrow | weekday、day、month、year、hour... |
最有用的模式
user is returning
user is not returning
session is starting
device's category is "mobile"
device's category is not "bot"
location's countryCode is "US"
location's state's code is in ["NY", "CA"]
location's cityName is "New York" and today's weekday is "monday"
campaign's source is "google" and campaign's medium is "cpc"
campaign's name matches "sale"
page's path is in ["/pricing", "/plans"]
page's query's newsletter is "daily-news"
page.query['coupon-code'] is defined
session's referrer matches "google"
session's landingPage starts with "https://example.com/promo"
session's duration > 5 minutes and session's stats' orders is 0
user's interests contains either ["marketing", "sales"]
user's age is between 18 and 30
user's stats' orders is 0
user's plan is "premium"
cart's stage is "checkout" and cart's total is greater than 100
some item in cart's items satisfies item's brand is "Apple"
(no item in cart's items satisfies item's name is like "smartphone") and user is returning
user has abandoned a cart at least 2 times
user has viewed a product with category "Shoes" in last 7 days
user has completed goal "demo-requested" last session
user's firstName or else "there"
按使用案例(活動、地理位置、技術、工作階段、個人檔案、購物車、訂單、值查詢)查看更多:references/recipes.md。
從程式碼評估
import croct from '@croct/plug';
const isReturning = await croct.evaluate<boolean>('user is returning').catch(() => false);
const inList = await croct.evaluate<boolean>(
"context's countries include location's countryName",
{attributes: {countries: ['United States', 'Canada']}}, // 讀取為 `context's countries`
);
Next.js 伺服器端:使用 @croct/plug-next/server 中的 await evaluate(query) 或 await cql`user's persona is in ${roles}` 。React:使用 useEvaluation(query)。HTTP:POST https://api.croct.io/client/web/evaluate,主體為 {"query": "..."}。詳細資訊、屬性限制、動態值與估算,請參閱:references/evaluation.md。
陷阱與除錯
| 症狀 | 可能原因 | 修正 |
|---|---|---|
x is y 語法錯誤 | is 簡寫需要右側為字面值 | 使用 x is equal to y 或 x == y |
location city is "Berlin" 語法錯誤 | 缺少存取器:變數與其屬性之間的裸詞 | 使用 location's cityName、property cityName of location 或 location.cityName |
比較 "1" > 0 或 session's start > "2026-01-01" 時出錯 | 關係運算子絕不會轉換型別 | 進行轉換:"1" as number > 0、... > "2026-01-01" as datetime,或使用 is after |
| 地理位置/代碼永不匹配 | 大小寫錯誤:代碼為大寫 ("US"、"NA"、"CA") 且字串區分大小寫 | 使用大寫、is like、is equal to ... ignoring case 或 ~/.../i |
matches "Sale" 錯過 "sale" | matches、starts with、ends with 區分大小寫 | 使用 is like "sale" 或 matches ~/sale/i |
| 量詞吞掉後續條件 | 量詞謂語延伸至結尾 | 將整個量詞用括號括起來 |
a or b and c 行為異常 | and 的綁定優先級高於 or | 加上括號 |
| 條件結果被錯誤相乘 | 條件式是貪婪的 | (A if c otherwise B) * price |
| 個人檔案/購物車/興趣條件永不成立 | 需要整合的資料尚未發送 | 追蹤事件或設定屬性(請參閱 croct-track-events 技能) |
X is greater than 30 和 X is not greater than 30 都為 false | 值未定義:布林錯誤容錯產生 false | 使用 X is defined and ... 或 X or else 0 |
user is identified 總是 false | 未追蹤登入/登出事件 | 追蹤它們;否則使用者永遠是匿名 |
cart.items[2nd]、first of、average of、min of 錯誤 | 缺少元素或空集合 | 附加 or else null / or else 0 |
contains none of [] 對比 contains neither [] | 空右側:none 為 false,neither 為 true | 對於「無重疊」使用 contains neither |
混合 's 與括號時出錯 | 所有格/屬有格加上括號需要括號 | 使用 (cart's items)[1st] 或點記法 cart.items[*] |
| 事件表達式不可用 | 它們是 Scale 方案的功能 | 在可能的情況下使用個人檔案/工作階段統計資料 (user's stats' orders) |
| 「無法使用估算」 | 使用了 page、當前上下文或 now/today/yesterday | 這是預期行為;受眾在執行時期仍可正常運作 |
| 範圍錯誤 | .. 範圍最多 30 個項目 | 縮小範圍 |
| 變數/參數名稱錯誤 | 變數無法重新定義;名稱必須是識別碼 | 重新命名;避免使用內建名稱 (user、page) 和通用詞彙 |
應做事項:
- 在與非開發人員共享的受眾中,優先使用明確的
is equal to、is greater than;當技術風格讀起來更順時再使用它。 - 使用
is defined或or else保護可選資料。 - 在
and鏈中將計算成本低的條件放在前面(短路求值會跳過其餘條件)。 - 使用
contains either/contains neither,而不是否定contains all/contains none。
不應事項:
- 不要發明測試、變數或事件措辭。例如
user is new或user has made purchase等範例出現在文件敘述中,但並非有記錄的結構;請使用user is not returning和user's stats' orders is not 0(或user has placed an order)。 - 不要將
location's countryName與代碼進行比較;對於"US"請使用countryCode。 - 不要在算術中依賴隱式的日期轉換:
"2021-01-01" as date + 1 day。
參考資料
| 檔案 | 何時閱讀 |
|---|---|
| references/syntax.md | 詞法規則、let、函式、字面值、存取器與選擇器、優先級表、條件式、持續時間 |
| references/context-and-data-types.md | 每個變數與屬性、可用性標記、列舉(裝置類別、購物車階段、洲別、位置標籤)、轉換 |
| references/expressions.md | 所有測試、運算子、錯誤容錯、量詞、巨集、修飾符 |
| references/events.md | 事件表達式、條件運算子、計數量詞、時間視窗、追蹤需求 |
| references/evaluation.md | SDK evaluate / cql / hooks、評估 API、上下文屬性、動態值、受眾估算 |
| references/recipes.md | 按使用案例分類的即用受眾與值查詢 |
相關技能:croct-integrate-sdk (SDK 設定)、croct-track-events (發送查詢讀取的事件與屬性)、croct-use-api (HTTP API)、croct-model-content (內容定義中的動態值)、croct-personalize-and-test (使用受眾的體驗與實驗)、croct-use-croct (概念與導覽)。