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 (10진수), 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` with {"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 |
| 프로필/장바구니/관심사 조건이 절대 true가 아님 | 통합 필요한 데이터가 전송되지 않음 | 이벤트를 추적하거나 속성 설정 (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 [] vs 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체인에서 비용이 적게 드는 조건을 먼저 넣으세요 (단락 평가로 나머지를 건너<0xEB><0x9B><0x84>).contains all/contains none을 부정하는 대신contains either/contains neither을 사용하세요.
하지 말아야 할 일:
- 테스트, 변수 또는 이벤트 표현을 지어내지 마세요.
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 / 훅, Evaluation 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 (개념 및 오리엔테이션).
라이브 문서
- 인덱스: https://docs.croct.com/llms.txt
- CQL 참조: https://docs.croct.com/reference/cql/introduction.md (모든 페이지에
.md추가) - 검색: https://docs.croct.com/api/search.md?term=