Salesforce Apex: What is SOSL?

Query individual terms across multiple objects and fields

Salesforce Apex: What is SOSL?
Photo by Tobias Fischer on Unsplash

Salesforce is fantastic for structuring data…a lot of data. You’ve taken the time to create a library of sObjects, broken apart all the data, but what happens when you want to do a search across multiple sObjects?

This is where Salesforce Object Search Language (SOSL) comes into play.

SOSL is perfect for querying names, emails, and other text-based data across a specified list of sObjects. Do you want to look into all the leads and opportunities that involve a specific email address? SOSL is your best friend.

We’re going to define the different parts of a SOSL query and go over how to parse the subsequent results. Use this article as a starting guide and reference as you take control of your data instead of swimming in it.

Breaking Down a SOSL Query

A SOSL query has three key words and three respective components to fill in. Before we break down the different parts, here’s a sample SOSL query:FIND 'edgar@figaro.com' IN EMAIL FIELDS RETURNING Lead, Opportunity

If we use placeholders for the query components and leave the keywords, our query looks like this:FIND __terms__ IN __fields__ RETURNING __objects__

Now that we’ve identified the keywords, let’s break down the three components to a SOSL query.

  • Terms: The string values that are being searched for. This could be a single string as in the example above, or multiple connected with the OR keyword.
  • Fields: The metadata field type to search through. In addition to EMAIL FIELDS, other options are NAME FIELDS, PHONE FIELDS, and ALL FIELDS.
  • Objects: The sObjects that will be searched through. Can include field lists and even filter logic.

Parsing SOSL Results

Before we begin parsing out the SOSL results, we need to understand the structure of the query response. SOSL queries return a “List of Lists”.

Dissecting our original sample query, the outer list has two entries: List<Lead> and List<Opportunity>. The arrangement is determined by the sequence in the query. Since Lead was first, its list is accessed with the 0 index while the Opportunity object is accessed with the 1 index.

We store the results with the sObject data type which is the parent class of both Lead and Opportunity.List<List<sObject>> results = [FIND 'edgar@figaro.com' IN EMAIL FIELDS RETURNING Lead, Opportunity];

From this point, there are two ways parse the results. We know that the first index is List<Lead> data and the second index is List<Opportunity> data so we could do the following:For(Lead lead: (List<Lead>)results[0]) {
  System.debug(lead.Id);
}For(Opportunity opportunity: (List<Opportunity>)results[1]) {
  System.debug(opportunity.Id);
}

Notice that we coerce each index into the appropriate data type from the generic sObject type.

Another option is to maintain the sObject data type and used nested for loops.For(List<sObject> objectList: results) {
   For(sObject obj: objectList) {
       System.debug(obj.Id);
   }
}

Customizing SOSL Queries

Now that we’ve gone through the structure and how to parse the results, it’s important to highlight how to customize SOSL queries.

Wildcard Characters

When defining search terms, we can use the ? and * characters as wildcards to perform fuzzy searches. The question mark serves as a single character wildcard while the asterisk is a multi-character wildcard.

For example, if we want to search for any Gmail address we could use the search term: '*@gmail.com'

Similarly, we can search for any two-character top-level domain using an asterisk for username, at symbol, asterisk for domain, period, and finally a double question mark: '*@*.??'

Object List Fields and Criteria

In addition to specifying the sObjects to include in the search, fields can be specified in parenthesis after each sObject name. This allows customized field results per sObject.FIND 'edgar@figaro.com' IN EMAIL FIELDS RETURNING Lead(Name, Email, Phone), Opportunity(Name, Amount)

As a small note, when using customized field lists per object, I highly recommend parsing results “per specific sObject” instead of a generic nested for loop.

We can even include criteria within the parenthesis to further customize the search results.FIND 'edgar@figaro.com' IN EMAIL FIELDS RETURNING Lead(Name, Email, Phone), Opportunity(Name, Amount WHERE Stage != 'Closed Won')

This allows us to include object-specific criteria in addition to the aforementioned search term.

Conclusion

SOSL is not to be confused with SOQL. Use SOSL (identified by the FIND keyword) to search across multiple sObjects with flexible criteria and customizable object lists.

Once the query is performed, a “List of Lists” is returned where you can either parse each individual sObject type using its index value, or use a generic nested for loop.


Please share your experiences, questions, and feedback below. Follow Code 85 for more plain language programming guides. Thanks for reading!

Subscribe to Dreams of Fortunes and Cookies

Sign up now to get access to the library of members-only issues.
Jamie Larson
Subscribe