SOSL: búsqueda en varios objetos
Cuando sabes qué texto buscas pero no en qué objeto ni en qué campo está: una búsqueda, varios objetos, una lista por cada uno.
✓ En esta sub-lección
- 01Escribir una búsqueda SOSL con FIND, IN y RETURNING.
- 02Leer el resultado List<List<SObject>> y convertir cada lista a su tipo.
- 03Elegir entre SOQL y SOSL según la pregunta de negocio.
La nutria: ¿Te acuerdas? · Repaso de la lección 6
Quieres quedarte solo con las etapas cuyo total supere 100.000. ¿Qué cláusula usas?
Un agente de soporte recibe una llamada: «Soy de Acme, os escribí la semana pasada». ¿Acme es una cuenta, un contacto con ese correo, una oportunidad con ese nombre? SOQL necesita que le digas el objeto y el campo. SOSL no: le das el texto y te dice dónde aparece.
La nutria: El paralelo de Admin
Anatomía de una búsqueda
List<List<SObject>> results = [
FIND 'Acme*'
IN ALL FIELDS
RETURNING Account(Id, Name),
Contact(Id, Name, Email),
Opportunity(Id, Name, StageName WHERE IsClosed = false)
LIMIT 50
];
List<Account> accounts = (List<Account>) results[0];
List<Contact> contacts = (List<Contact>) results[1];
List<Opportunity> opps = (List<Opportunity>) results[2];- FIND: el texto a buscar, entre comillas simples. * es «cualquier cosa a partir de aquí» y ? es «un carácter»: 'Acme*' encuentra Acme, Acme Corp, Acmeline.
- IN: dónde mirar. ALL FIELDS (todos los campos de texto indexados), NAME FIELDS, EMAIL FIELDS o PHONE FIELDS. Cuanto más concreto, más rápido y menos ruido.
- RETURNING: los objetos que te interesan y, entre paréntesis, los campos de cada uno. Cada objeto admite su propio WHERE, ORDER BY y LIMIT, como en SOQL.
- El texto también puede venir de una variable: FIND :term. Enlazado con dos puntos, igual que en la lección 4.
Una lista de listas
SOSL devuelve List<List<SObject>>: una lista exterior con una lista interior por cada objeto del RETURNING, en el mismo orden en que los escribiste. La primera, results[0], son las cuentas; results[1], los contactos. Cada lista interior llega como SObject genérico, así que haces un casting a su tipo real para poder leer sus campos cómodamente. Es la misma idea que el AggregateResult de la lección anterior: el resultado llega con un tipo general y tú le dices qué es.
List<List<SObject>> results = [FIND 'northwind*' IN ALL FIELDS
RETURNING Account(Name), Contact(LastName),
Opportunity(Name WHERE IsClosed = false)];results[0]Account(Name) · 1 filaNorthwind Trading
results[1]Contact(LastName) · 0 filas(lista vacía)
results[2]Opportunity(Name WHERE IsClosed = false) · 0 filas(lista vacía)
El resultado es una lista de listas, en el orden del RETURNING: results[0] siempre son las cuentas aunque vengan vacías. Para usarlas se convierten: (List<Account>) results[0]. Prueba con y sin asterisco: 'torres' encuentra la palabra exacta; 'northwind*', todo lo que empieza así.
¿SOQL o SOSL?
| La pregunta es… | Usa |
|---|---|
| «Las oportunidades de esta cuenta que cierran este mes» | SOQL: sabes objeto, campos y filtros |
| «Todo lo que contenga 'Acme', esté donde esté» | SOSL: sabes el texto, no el sitio |
| «Un contacto por su correo, en cualquier objeto con email» | SOSL con IN EMAIL FIELDS |
| «Totales por etapa», «cuentas sin casos» | SOQL: SOSL no agrega ni recorre relaciones |
La nutria: ¿Y por qué no un Flow? Porque Flow no busca