SOSL Salesforce Object Search Language: Complete Guide | SalesforceTutorial

Written by Prasanth Kumar Published on Updated on

SOSL (Salesforce Object Search Language) is a powerful full-text search language designed for unstructured queries across multiple Salesforce objects and fields. Unlike SOQL which retrieves structured data from single objects, SOSL searches for keywords across multiple string fields and objects simultaneously. This guide covers SOSL syntax, implementation in Apex, and production best practices for Salesforce developers.

What is SOSL in Salesforce?

SOSL stands for Salesforce Object Search Language. SOSL and SOQL are both implemented in the Force.com platform to index data automatically, whether structured or unstructured. Salesforce Object Search Language is specifically designed for unstructured queries, also called full-text search operations.

When you need to search for a keyword across multiple fields and objects, SOSL provides more efficient results than multiple SOQL queries with filtering conditions. Choose SOSL when searching for words within many string fields across different objects. Use SOQL for single-object queries with specific data type filtering requirements.

SOSL vs SOQL: When to Use Each

SOSL excels at cross-object text searches, while SOQL handles structured data retrieval:

  • Use SOSL for: Searching keywords across multiple objects, full-text search functionality, finding records when you don’t know which object contains the data
  • Use SOQL for: Retrieving specific records from known objects, filtering by non-text fields (dates, numbers, checkboxes), complex relationship queries

SOSL Syntax and Structure

SOSL Salesforce Object Search Language syntax basics
SOSL Basics

SOSL is designed for searching terms across multiple fields, strings, and objects. Search terms in SOSL are string literals and wildcards that target fields containing string data from one or more objects. Avoid using checkboxes, numbers, or date fields in SOSL queries as they are not indexed for text search.

SOSL Query Syntax:

  • FIND {SearchQuery} [IN SearchGroup] [RETURNING FieldSpecification] [LIMIT RecordLimit]

SOSL Syntax Components

Every SOSL query consists of four main parts:

  1. Search Query – The keyword or phrase to search for
  2. Search Group – Optional scope specification
  3. Returning Field Specification – Objects and fields to return
  4. Record Limit – Maximum records returned (default: 200)

1. Search Query

The search query contains keywords or phrases with one or more words. Wildcards (* for multiple characters, ? for single characters) can be included at the middle or end of search terms. Enclose search terms in curly braces {}. Use logical operators AND, OR, and AND NOT for complex searches. Search terms are case-insensitive.

// Basic search
FIND {Smith}

// Wildcard search
FIND {Sm*}

// Logical operators
FIND {Smith AND John}
FIND {Smith OR Jones}
FIND {Smith AND NOT John}

2. Search Group (Optional)

Search groups specify which field types to search:

  • ALL FIELDS – All string field values (default)
  • NAME FIELDS – Standard Name fields only
  • EMAIL FIELDS – Email field types only
  • PHONE FIELDS – Phone field types only
// Search only in name fields
FIND {Smith} IN NAME FIELDS

// Search only in email fields
FIND {john@company.com} IN EMAIL FIELDS

3. Field Specification

Field specification is a comma-separated list of objects and fields to include in results. Specify which objects to search and which fields to return:

// Return specific fields from multiple objects
FIND {Smith} RETURNING Account(Name, Industry), Contact(FirstName, LastName, Email)

// Return all fields (not recommended for production)
FIND {Smith} RETURNING Account, Contact

4. Record Limit

SOSL returns a maximum of 200 records by default. Use LIMIT to specify a different maximum:

// Limit to 50 records total
FIND {Smith} RETURNING Account(Name), Contact(Name) LIMIT 50

SOSL in Apex: Implementation Examples

SOSL queries in Apex return a List of List of sObjects. Each inner list contains results for one object type specified in the RETURNING clause.

Basic SOSL Query in Apex

// Search for 'Acme' across Account and Contact objects
List<List<sObject>> searchResults = [
    FIND 'Acme' 
    RETURNING Account(Id, Name, Industry), 
              Contact(Id, FirstName, LastName, AccountId)
    LIMIT 100
];

// Extract results by object type
List<Account> accounts = (List<Account>) searchResults[0];
List<Contact> contacts = (List<Contact>) searchResults[1];

System.debug('Accounts found: ' + accounts.size());
System.debug('Contacts found: ' + contacts.size());

Dynamic SOSL with Search.query()

// Dynamic SOSL construction
String searchTerm = 'Technology';
String soslQuery = 'FIND \'' + String.escapeSingleQuotes(searchTerm) + 
                   '\' RETURNING Account(Name, Industry) LIMIT 50';

List<List<sObject>> results = Search.query(soslQuery);
List<Account> accounts = (List<Account>) results[0];

// Process results
for (Account acc : accounts) {
    System.debug('Account: ' + acc.Name + ', Industry: ' + acc.Industry);
}

Error Handling and Best Practices

public class SOSLSearchUtility {
    public static List<Account> searchAccounts(String searchTerm) {
        // Input validation
        if (String.isBlank(searchTerm) || searchTerm.length() < 2) {
            return new List<Account>();
        }
        
        try {
            // Escape special characters
            String escapedTerm = String.escapeSingleQuotes(searchTerm.trim());
            
            List<List<sObject>> results = [
                FIND :escapedTerm 
                RETURNING Account(Id, Name, Industry, BillingCity)
                LIMIT 200
            ];
            
            return (List<Account>) results[0];
            
        } catch (Exception e) {
            System.debug('SOSL search error: ' + e.getMessage());
            return new List<Account>();
        }
    }
}

SOSL Governor Limits and Performance

Understanding SOSL limits is crucial for production implementations:

  • SOSL queries per transaction: 20 (synchronous), 200 (asynchronous)
  • Records returned per query: 2,000 maximum
  • Default limit: 200 records if no LIMIT specified
  • Search term minimum: 2 characters (single characters ignored)
  • Wildcard limitations: Cannot start search terms with wildcards

Performance Optimization Tips

  1. Use specific RETURNING clauses: Only return objects and fields you need
  2. Apply appropriate LIMIT: Reduce network overhead and processing time
  3. Search in specific field groups: Use IN NAME FIELDS, EMAIL FIELDS, etc.
  4. Avoid leading wildcards: Searches starting with * are not supported
  5. Consider search term length: Longer terms provide more targeted results

Common SOSL Use Cases

Global Search Implementation

// Global search across multiple objects
public class GlobalSearchController {
    @AuraEnabled
    public static Map<String, List<sObject>> performGlobalSearch(String searchTerm) {
        Map<String, List<sObject>> results = new Map<String, List<sObject>>();
        
        if (String.isNotBlank(searchTerm) && searchTerm.length() >= 2) {
            List<List<sObject>> searchResults = [
                FIND :searchTerm 
                RETURNING Account(Id, Name, Industry),
                          Contact(Id, Name, Email, Phone),
                          Opportunity(Id, Name, StageName, Amount),
                          Lead(Id, Name, Company, Status)
                LIMIT 50
            ];
            
            results.put('Account', searchResults[0]);
            results.put('Contact', searchResults[1]);
            results.put('Opportunity', searchResults[2]);
            results.put('Lead', searchResults[3]);
        }
        
        return results;
    }
}

Duplicate Detection with SOSL

// Find potential duplicates using SOSL
public static List<Contact> findPotentialDuplicates(String firstName, String lastName, String email) {
    String searchTerm = firstName + ' OR ' + lastName;
    if (String.isNotBlank(email)) {
        searchTerm += ' OR ' + email;
    }
    
    List<List<sObject>> results = [
        FIND :searchTerm 
        RETURNING Contact(Id, FirstName, LastName, Email, AccountId)
        LIMIT 100
    ];
    
    return (List<Contact>) results[0];
}

SOSL Security Considerations

SOSL respects Salesforce security model:

  • Object-level security: Users only see objects they have access to
  • Field-level security: Restricted fields are not returned in results
  • Record-level security: Sharing rules and ownership apply
  • Profile permissions: “View All” permissions affect search scope

Testing SOSL in Apex

@isTest
public class SOSLSearchTest {
    @isTest
    static void testAccountSearch() {
        // Create test data
        Account testAccount = new Account(Name = 'Acme Corporation', Industry = 'Technology');
        insert testAccount;
        
        Test.startTest();
        
        // Set fixed search results for testing
        List<Account> fixedSearchResults = new List<Account>{testAccount};
        Test.setFixedSearchResults(new List<Id>{testAccount.Id});
        
        // Perform SOSL search
        List<List<sObject>> results = [
            FIND 'Acme' 
            RETURNING Account(Id, Name, Industry)
        ];
        
        Test.stopTest();
        
        // Verify results
        List<Account> accounts = (List<Account>) results[0];
        System.assertEquals(1, accounts.size(), 'Should find one account');
        System.assertEquals('Acme Corporation', accounts[0].Name);
    }
}

Troubleshooting Common SOSL Issues

Search Returns No Results

  • Verify search term length (minimum 2 characters)
  • Check object and field-level permissions
  • Ensure data exists and is indexed
  • Review search group specification (ALL FIELDS vs NAME FIELDS)

Performance Issues

  • Reduce RETURNING clause scope
  • Apply appropriate LIMIT values
  • Use specific search groups when possible
  • Avoid overly broad search terms

Governor Limit Exceptions

  • Monitor SOSL query count in transactions
  • Implement bulkification patterns
  • Consider asynchronous processing for large operations

Frequently Asked Questions

What is the difference between SOSL and SOQL in Salesforce?

SOSL (Salesforce Object Search Language) is designed for full-text searches across multiple objects and fields, while SOQL (Salesforce Object Query Language) retrieves structured data from specific objects with precise filtering. Use SOSL for keyword searches across multiple objects; use SOQL for structured queries on single objects.

How do you write SOSL queries in Apex?

SOSL queries in Apex use the FIND keyword and return List<List<sObject>>. Basic syntax: List<List<sObject>> results = [FIND 'searchterm' RETURNING Object(fields)];. Each inner list contains results for one object type specified in the RETURNING clause.

What are SOSL governor limits in Salesforce?

SOSL allows 20 queries per synchronous transaction (200 asynchronous), returns maximum 2,000 records per query with 200 default limit, requires minimum 2-character search terms, and does not support leading wildcards. Always apply appropriate LIMIT clauses for optimal performance.

Can you use wildcards in SOSL search terms?

Yes, SOSL supports wildcards: * for multiple characters and ? for single characters. Wildcards can appear in the middle or end of search terms but not at the beginning. Example: FIND {Sm*} finds “Smith”, “Small”, etc.

How do you test SOSL queries in Apex test classes?

Use Test.setFixedSearchResults() to define fixed search results in test methods. Create test data, call setFixedSearchResults with record IDs, then execute your SOSL query. The query will return the predefined results instead of performing actual search operations.

What field types can be searched with SOSL?

SOSL searches string-based fields including Text, Text Area, Rich Text Area, Email, Phone, and URL field types. It cannot search Number, Date, DateTime, Checkbox, or Picklist fields. Use search groups like NAME FIELDS, EMAIL FIELDS, or PHONE FIELDS to target specific field types.