SOSL 쿼리 작성

Isa.log·2025년 6월 24일

SOQL vs SOSL 차이


SOQL = "어떤 객체에서, 어떤 조건으로" [SELECT 필드 FROM 객체 WHERE 조건]
SOSL = "여러 객체 전체에서, 특정 단어가 들어간 모든 걸 찾아줘"

SOSL이란?

SOSL = Salesforce 검색 엔진처럼 동작함.

  • 여러 객체 (Account, Contact, Lead, ...)를 한 번에 검색 가능.
  • 필드의 어디에 있든 특정 단어가 들어가 있으면 찾아줌.
  • Apache Lucene 검색엔진과 비슷한 원리.

SOSL 기본 문법

List<List<SObject>> searchList = 
    [FIND 'SFDC' IN ALL FIELDS RETURNING Account(Name), Contact(FirstName, LastName)];

👉🏻 FIND 'SFDC' → 'SFDC'라는 단어를 찾아라.
👉🏻 IN ALL FIELDS → 모든 필드 안에서 찾아라.
👉🏻 RETURNING Account(Name), Contact(FirstName, LastName) → 검색 결과 중 Account 객체의 Name, Contact 객체의 FirstName, LastName을 반환해라.

예시 하나 더 (Developer Console에서 작성)

Apex에서 SOSL 결과 타입

결과가 2차원 리스트 형태로 나옴.

List<List<SObject>> searchList

바깥쪽 List< ... > → 여러 객체(Account, Contact, Lead 등)를 담는 리스트
안쪽 List<SObject> → 특정 객체(Account만, Contact만, Lead만)를 담는 리스트

전체 검색 결과 = 큰 바구니 (List)
이 바구니 안에 → 객체별 바구니들이 있음 (Account 바구니, Contact 바구니 등)
각 바구니 안에는 → 해당 객체의 레코드들이 들어있음 (SObject들이 들어감)

예를 들어:
searchList[0] → Account 결과
searchList[1] → Contact 결과

따라서 이렇게 꺼내서 쓴다:

Account[] searchAccounts = (Account[])searchList[0];
Contact[] searchContacts = (Contact[])searchList[1];

➡️

왜 이렇게 복잡하게 꺼내쓰는지

1️⃣ SOSL 쿼리 결과 타입이 뭐였지?

List<List<SObject>> searchList

바깥 리스트 → 전체 객체 결과 (Account, Contact, Lead ...)
안쪽 리스트 (List<SObject>) → 각각의 객체 레코드 결과

즉, Salesforce는 모든 객체를 "SObject"라는 공통 부모 타입으로 묶어서 보내준다.

2️⃣ 하지만 Apex에서는 뭘 하고 싶어?

👉 나는 Account는 Account 타입으로,
Contact는 Contact 타입으로
정확하게 꺼내서 다루고 싶어.

왜냐면:
Account 타입이어야 a.Name 이라고 쉽게 접근 가능하고
Contact 타입이어야 c.FirstName 등 필드 접근이 가능하니까!

3️⃣ 그래서 뭐가 필요하다?

다운캐스팅 (Type Casting) 이 필요!

searchList[0] → 지금은 List<SObject> 타입.

나는 이걸 → List<Account> 타입으로 변환하고 싶기에
그래서 (Account[]) 라고 앞에 캐스팅을 써서 변환하는 것.

⚠️ 이것 없으면 어떻게 되냐?

만약 이렇게 캐스팅 안 하면,

SObject s = searchList[0][0];

이렇게 SObject로 밖에 못 다뤄서
즉, s.Name 이렇게 하면 에러가 난다. (SObject는 Name 속성이 없다고 뜸)

참고: 배열ver VS 리스트ver

배열 버전

Account[] searchAccounts = (Account[])searchList[0];

위의 코드보다 아래 리스트 버전 코드를 요새 더 많이 쓴다.
Apex 자체가 컬렉션 기반 언어라서 거의 모든 API, 메서드가 List<T> 기반으로 설계됨
유지보수, 확장성, 코딩 편의성 측면에서 리스트가 훨씬 좋음

리스트 버전

List<Account> searchAccounts = (List<Account>) searchList[0];

요약하자면 둘 다 여러 개의 Account를 담지만,
Account[]는 고정된 배열 (좀 옛날 스타일),
List<Account>는 유연하고 Apex에서 표준으로 권장되는 컬렉션.

중요한 SOSL 특징

여러 객체 한번에 검색: Account, Contact, Lead 등 한 번에 검색 가능
모든 필드 검색 가능: 설명, 이름, 전화번호 등 다양한 필드에서 검색
대소문자 구분 안 함: customer == Customer == CUSTOMER
와일드카드 지원: wing* → wing으로 시작하는 모든 단어 검색 가능
논리 연산자 지원: Wingo OR SFDC 등 복잡한 조건 사용 가능

Developer Console에서 테스트할 때 차이점

Query Editor에서 사용할 땐 {} 중괄호
Apex 코드 안에선 ' ' 작은따옴표

예:
Query Editor

FIND {Wingo} IN ALL FIELDS RETURNING Account(Name)

Apex 코드 안 (Apex Class, Execute Anonymous)

FIND 'Wingo' IN ALL FIELDS RETURNING Account(Name)

Developer Console 안에는 두 가지 모드가 있다.

  1. Apex 코드 안 (Apex Class, Execute Anonymous)
  2. Query Editor

1은 Apex 코드를 실행하는 창이고, 2는 쿼리만 직접 실행하는 창이다.

이 차이 때문에 SOSL을 작성할 때 문법이 달라진다.

1에서는 Apex 코드 안에 SOSL이 들어가므로 SOSL 검색어도 문자열처럼 취급되어 작은따옴표 ' '를 사용한다.

FIND 'Wingo' IN ALL FIELDS RETURNING Account(Name)

반면, Query Editor에서는 SOSL 그 자체만 작성하므로 원래 SOSL 문법대로 검색어를 중괄호 {}로 감싼다.

FIND {Wingo} IN ALL FIELDS RETURNING Account(Name)
profile
세상을 탐험하던 눈으로, 지금은 디버깅 중

0개의 댓글