Salesforce - Developer - SOSL

salesforce-developer

https://trailhead.salesforce.com/apex_database/apex_database_sosl
https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_soql_sosl_intro.htm
https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_sosl_find.htm

// Salesforce - Developer - SOSL: Salesforce Object Search Language

// Differences and Similarities Between SOQL and SOSL:

1. Unlike SOQL, which can only query one standard or custom object at a time, a 
   single SOSL query can search all objects.

2. SOSL matches fields based on a word match while SOQL performs an exact match 
   by default (when not using wildcards). For example, searching for 'Digital' 
   in SOSL returns records whose field values are 'Digital' or 'The Digital 
   Company', but SOQL returns only records with field values of 'Digital'.

3. SOQL and SOSL are two separate languages with different syntax. Each language 
   has a distinct use case:
   a. Use SOQL to retrieve records for a single object.
   b. Use SOSL to search fields across multiple objects. SOSL queries can search 
      most text fields on an object.

With SOSL you can search against different object types that may have similar 
data, such as contacts and leads.

The general syntax for  SOSL:

FIND 'SearchQuery' [IN SearchGroup] [RETURNING ObjectsAndFields]

SearchQuery is the text to search for (a single word or a phrase). Search terms 
can be grouped with logical operators (AND, OR) and parentheses. We can  also
include wildcard characters (*, ?) in the search term. The * wildcard matches 
zero or more characters at the middle or end of the search term. The ? wildcard 
matches only one character at the middle or end of the search term.  The text to 
be searched is case-insensitive.

SearchGroup is optional. It is the scope of the fields to search. If not 
specified, the default search scope is all fields. SearchGroup can take one of 
the following values:

ALL FIELDS
NAME FIELDS
EMAIL FIELDS
PHONE FIELDS
SIDEBAR FIELDS

ObjectsAndFields is optional. It is the information to be returned in the search 
result, a list of one or more sObjects and, within each sObject, list of one or 
more fields, with optional values to filter against. If not specified, the 
search results contain the IDs of all objects found.

A SearchQuery contains two types of text:

1. Single Word: single word, such as test or hello. Words in the SearchQuery are 
   delimited by spaces, punctuation, and changes from letters to digits (and 
   vice-versa). Words are always case insensitive.

2. Phrase: collection of words and spaces surrounded by double quotes such as 
   "john smith". Multiple words can be combined together with logic and grouping 
   operators to form a more complex query.

List<List<sObject>> searchList = [
  FIND 'Wingo OR SFDC' 
  IN ALL FIELDS 
  RETURNING 
    Account(Name, Industry WHERE Industry='Apparel' ORDER BY Name LIMIT 10), 
    Contact(FirstName,LastName,Department)
];
Account[] searchAccounts = (Account[])searchList[0];
Contact[] searchContacts = (Contact[])searchList[1];

System.debug('Found the following accounts.');
for (Account a : searchAccounts) {
    System.debug(a.Name);
}

System.debug('Found the following contacts.');
for (Contact c : searchContacts) {
    System.debug(c.LastName + ', ' + c.FirstName);
}

In the above code, because SOSL queries can return multiple sObject types, 
those filters are applied within each sObject inside the RETURNING clause.  The
above code also show us how to use the WHERE clause and the ORDER BY, and
the LIMIT clause.  

// Dynamic SOSL:

public class ContactAndLeadSearch {
    public static List<List< SObject>> searchContactsAndLeads(String searchFor) {
        List<List<sObject>> searchList = [
            FIND searchFor 
            IN ALL FIELDS 
            RETURNING 
                Lead(FirstName, LastName), 
                Contact(FirstName, LastName)
        ];
    }
}

Ideally, the above code should work, but it does not.  To work around this issue,
we have to use dynamic SOSL:

public class ContactAndLeadSearch {
    public static List<List< SObject>> searchContactsAndLeads(String searchFor) {
        String sosl = 'FIND \'' + searchFor + '\' IN ALL FIELDS RETURNING Lead(FirstName, LastName), Contact(FirstName, LastName)';

        List<List<sObject>> searchList = search.query(sosl);
        return searchList;
    }
}
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License