Перейти до вмісту

Пошук — не запит

Також доступно 19 мовами

English · Español · 日本語 · Português (Brasil) · Français · Deutsch · Italiano · 한국어 · 简体中文 · Português (Portugal) · 繁體中文 · Bahasa Indonesia · Türkçe · Polski · Tiếng Việt · ไทย · Español (México) · Français (Canada) · Deutsch (Schweiz)

A fishing net full of silver fish being lifted out of the sea over the side of a small boat, water streaming from it.
Зображення згенеровано ШІ

Module 5 of 5 in the chapter Query and Retrieval Architecture, chapter 8 of the Data Architect course. Each module stands on its own. ⟲ Previous: How Salesforce Executes a Query · Next: the next chapter, Integration and Data Movement ⟲

Питання, на яке відповідає цей модуль: Коли шукати замість того, щоб робити запит?

Три модулі про запити, індекси, селективність, плани запитів і skinny tables припускають одне: ви знаєте, що шукаєте. Сьогоднішні доставки Redrock. Звернення, змінені з учора. Доставка з номером партнера DLV-8472914. Структуровані запитання. Але люди не завжди ставлять структуровані запитання. Іноді вони кажуть: «Пам’ятаю, клієнт згадував пошкоджений холодильник у Темпі. Можете знайти?» Це насправді не задача запиту. Це пошук. А пошук — не запит.

Запит починається зі структури; пошук починається зі слова

Section titled “Запит починається зі структури; пошук починається зі слова ”

SOQL чудовий, коли ми знаємо структуру: об’єкт, поле, умову. Робочі замовлення, де роздрібний партнер — Redrock, а запланована дата — сьогодні. Ми знаємо, де живе інформація, як вона подана і що ми перевіряємо, і база даних може використати все, що ми спроєктували в цьому розділі.

А тепер: «знайдіть запис із фразою зламаний холодильник». Який об’єкт? Звернення, робоче замовлення, нотатка? Тема, опис, інше текстове поле? Користувач не знає і не мусить знати. Ось тут з’являється SOSL, Salesforce Object Search Language. Замість «яке поле фільтрувати?» він починає з «знайди цей текст». Принципово інша задача отримання.

Я бачив, як розробники втискають пошук у SOQL. «Нехай користувач уведе якийсь текст і знайде клієнта», і запит росте: Name LIKE … OR Email LIKE … OR Phone LIKE … OR Description LIKE … OR ще одне поле, і ще одне. У якийсь момент зупиніться і спитайте: ми робимо запит чи шукаємо? Якщо вимога — знаходити текст у багатьох полях, SOSL може бути чистішим інструментом. Він для цього і створений. Не втискайте задачу пошуку у форму запиту лише тому, що SOQL — інструмент, яким ви користуєтеся найчастіше.

Remember the hardest case from module 3: contains. Description LIKE '%refrigerator%' has no way into the drawer, so the librarian walks every shelf. Search was built for exactly that question. Salesforce says it directly: “When a given search can use either language, SOSL is generally faster than SOQL if the search expression uses a CONTAINS term,” because “SOSL can tokenize multiple terms within a field (for example, multiple words separated by spaces) and builds a search index off this.” Looking for “John” in “Paul and John Company” is a search question (Using SOQL and SOSL (відкривається в новій вкладці), Best Practices for Deployments with Large Data Volumes, Winter ‘27). ⟲

Contains is a search question Three columns: the question, the language, the engine. First, someone asks for today's Redrock deliveries, knowing the object, the field and the condition, tagged fast; it is asked in SOQL, WHERE Retail_Partner__c = 'Redrock' AND date = TODAY, and answered by the database, straight in through the indexes. Second, someone asks for anything that mentions refrigerator, knowing the word but not where it is, tagged slow; it is forced into SOQL, Description LIKE '%refrigerator%', and answered by the database with no way into an index: a table scan, tagged slow. Third, the same question is asked in SOSL, FIND refrigerator, tagged fast, and answered by the search engine, with its own index of words, straight to the matches, tagged fast. Underneath: query knows the structure; search knows the term. THE QUESTION THE LANGUAGE THE ENGINE Today's Redrock deliveries I know the object, the field, the condition fast SOQL WHERE Retail_Partner__c = 'Redrock' AND date = TODAY The database straight in through the indexes Anything that mentions “refrigerator” I know the word, not where it is slow SOQL Description LIKE '%refrigerator%' The database no way into an index: a table scan slow asked in answered by forced into answered by Query knows the structure. Search knows the term. HOW TO READ IT someone asking a query: fields and conditions a search: words © 2026 Twinshark LLC · stevetecharc.com
Натисніть, щоб збільшити

“Contains” forced into a query: no way into an index. Slow. ⟲

Contains is a search question Three columns: the question, the language, the engine. First, someone asks for today's Redrock deliveries, knowing the object, the field and the condition, tagged fast; it is asked in SOQL, WHERE Retail_Partner__c = 'Redrock' AND date = TODAY, and answered by the database, straight in through the indexes. Second, someone asks for anything that mentions refrigerator, knowing the word but not where it is, tagged slow; it is forced into SOQL, Description LIKE '%refrigerator%', and answered by the database with no way into an index: a table scan, tagged slow. Third, the same question is asked in SOSL, FIND refrigerator, tagged fast, and answered by the search engine, with its own index of words, straight to the matches, tagged fast. Underneath: query knows the structure; search knows the term. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.41.0", "built": "2026-10-22", "id": "DGM-DA-QR-41", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "cells 0.1.0", "theme": "stevetecharc 1.4.0"} THE QUESTION THE LANGUAGE THE ENGINE Today's Redrock deliveries I know the object, the field, the condition fast SOQL WHERE Retail_Partner__c = 'Redrock' AND date = TODAY The database straight in through the indexes Anything that mentions “refrigerator” I know the word, not where it is fast SOSL FIND {refrigerator} The search engine its own index of words: straight to the matches fast asked in answered by asked in answered by Query knows the structure. Search knows the term. HOW TO READ IT someone asking a query: fields and conditions a search: words © 2026 Twinshark LLC · stevetecharc.com
Натисніть, щоб збільшити

The same words, asked as a search: straight to the matches. Query knows the structure. Search knows the term. ⟲

How Search Works: Tokens First, Then the Fetch

Section titled “How Search Works: Tokens First, Then the Fetch”

Back to the library. A database index is the catalog for “books by this author” or “books with this identifier.” Now I want every book containing the phrase “broken refrigerator.” Reading every page of every book for each search would be ridiculous, so search builds its own index over the words. “The Salesforce search architecture is based on its own data store, which is optimized for searching for that text” (Search Architecture (відкривається в новій вкладці), Winter ‘27): a different engine for a different kind of question. ⟲

How does it fill that store? “When you create a record, the search engine breaks up the searchable content into smaller pieces, called tokens. It stores the tokens in a search index. The search index is much like a book index—each token in the index has a link back to the record it came from” (How Einstein Search Works (відкривається в новій вкладці), Salesforce Help). When you search, your words are broken into tokens the same way and matched against that index. ⟲

And then comes a step people miss. “Salesforce performs indexed searches by first searching the indexes for appropriate records, then narrowing down the results based on access permissions, search limits, and other filters … The result set is then used to query the records from the database to retrieve the fields that a user sees” (Search Architecture (відкривається в новій вкладці)). In module 4’s four words: search finds which records in its own index, and then a regular fetch from the database brings back their fields. Two engines, one after the other. ⟲

And it’s not only the search box. Salesforce lists search behind “Advanced and global searches”, “Find boxes and lookup fields”, “Suggested Solutions and Knowledge Base”, “Web-to-Lead and Web-to-Case”, “Duplicate lead processing”, and SOSL from Apex and the API (same source). Like the librarian, search is working in places nobody thinks of as “search.” ⟲

Свіжість — частина проєкту

Section titled “Свіжість — частина проєкту ”

That index is asynchronous. New and changed records are queued and indexed by separate servers, and “it could take about 15 minutes or more for the updated text to become searchable” (Search Architecture (відкривається в новій вкладці)). Big loads take longer: “If a record is created or updated using bulk API, it may take more than 15 minutes for the record to be searchable … wait for a few hours for it to be indexed” (How Einstein Search Works (відкривається в новій вкладці)). So after a migration, the search index is behind for a while, just as module 4’s notebook of statistics is behind until the nightly run. ⟲

So search and query have different freshness. Steve Trucking creates a case at 10:00; at 10:01 a SOQL query returns it, while a text search for words in its description depends on whether the search index has caught up. That isn’t a defect. It’s a property of the mechanism. “The moment a delivery exception is created, our automation must find it.” Would I build that on text search? No. The process knows the work order, the exception type, the date and the status, so a structured query is the deterministic choice. “A care agent wants old cases where customers mentioned damaged refrigerators”? Search makes far more sense. Different requirement, different engine, different freshness. Choose the retrieval mechanism from the question, not from habit. ⟲

Пошук перетинає об’єкти і може знайти забагато

Section titled “Пошук перетинає об’єкти і може знайти забагато ”

Одна із сильних сторін SOSL — користувачеві не треба знати, який об’єкт містить відповідь. Координатор шукає «Henderson», і це може бути акаунт, контакт, робоче замовлення чи звернення. Користувач шукає річ, а не думає «спершу запит до Contact.LastName, потім Account.Name, потім отримувач робочого замовлення, потім описи звернень». Пошук відповідає тому, як люди справді шукають інформацію.

That creates another problem. Make everything searchable (every object, field, historical record, every bit of text) and then search “Smith,” and the user is overwhelmed. Search didn’t fail; it found too much. That’s search crowding, and at scale it matters as much as speed. ⟲

Salesforce defines it plainly: “Search crowding–having too many unhelpful search results–can overwhelm you with irrelevant records and slow down search. To avoid search crowding, the search engine limits the number of records it analyzes” (How Search Crowding Affects Search Results (відкривається в новій вкладці), Salesforce Help). The limit is there to protect search. The cost is that the record you wanted can fall outside it. ⟲

Let’s walk through one search. A Steve Trucking care agent is looking for a case about a damaged refrigerator for a customer named Henderson. She types Henderson into global search. Henderson is also a city, so the word appears on thousands of delivery addresses. Salesforce’s own example uses these numbers, so let’s use them too: ⟲

  1. Every record that matches. The search index finds 3,200 records with the word Henderson: accounts, contacts, cases, and a great many work orders. ⟲
  2. The limit. “Search limits the results to the first 2,000 records found, so 1,200 records aren’t included in your search results” (same source). If her case is among those 1,200, it’s gone before anything else happens. ⟲
  3. Permissions. Only now does search check what she can see. “Search analyzes only 2,000 records, which can include records you don’t have access to. Of the 2,000 analyzed, you don’t have access to 100 of them so you don’t see them in your results. You only see 1,900 records returned” (same source). Those 100 still took up room in the 2,000. Read that again: the cutoff comes before sharing, so records she will never see can take places in the 2,000 and push the record she needs past the line. ⟲
  4. Shared out across objects. When a search names several objects, the 2,000 are shared out. In Salesforce’s words: “If you query one object only, a maximum of 250 records are returned. To return up to 2,000 results, include either the WHERE clause or ORDER BY clause. If you query multiple objects, each object returns up to the minimum number between 2,000/n (where n=number of objects) and 250.” Search ten objects at once and each one gets at most 200. And the results aren’t the same for everyone: “Admins (users with the View All Data permission) see the full set of results returned”, while other users see only what they have access to, and “Results sets and order vary by the user issuing the search and can change throughout the day as records are added or removed from the index” (same source). The order varies too: Salesforce ranks results “based on search term frequency, order, uniqueness, record activity, and access permissions. Search result relevance can vary for each user” (How Einstein Search Works (відкривається в новій вкладці)). So when someone says “I searched and it wasn’t there,” the first questions are: how many records matched before the limit, and who were you? ⟲
  5. Ranked. What’s left is put in order of relevance, so even when her case survives, it may be far down the list under 1,900 other Hendersons. ⟲
Crowded out before sharing Four columns of small squares, each square 20 records, for a search for Henderson across every object, where 3,200 records match. First, the first pass: the 2,000 kept, blue matches she can see mixed with slate matches she can't see, still taking places; tagged the cutoff is full. Second, the discarded bucket: the other 1,200 matches, faded, and among them, in coral, her case; tagged her case is here. Third, after permissions: the 100 she can't see are removed, 1,900 shown, all blue; tagged not there. Fourth, Henderson refrigerator in Cases only: 40 match, two squares, one of them her case in coral; tagged found. Underneath: the cutoff comes first, sharing second; 100 records she'll never see took places in the 2,000 kept, and her case went into the discarded bucket; a specific search in one object never fills the 2,000. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.41.0", "built": "2026-10-22", "id": "DGM-DA-QR-45", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "units 0.3.0", "theme": "stevetecharc 1.4.0"} each square = 20 records 2,000 kept the cutoff is full First pass: the 2,000 kept “Henderson”, every object 1,200 discarded her case is here The discarded bucket the other 1,200 matches 1,900 shown not there After permissions the 100 she can't see are removed 40 shown found “Henderson refrigerator” Cases only: 40 match a match she can see a match she can't see, still taking a place discarded: past the cutoff her case The cutoff comes first, sharing second: 100 records she'll never see took places in the 2,000 kept, and her case went into the discarded bucket. A specific search in one object never fills the 2,000. © 2026 Twinshark LLC · stevetecharc.com
Натисніть, щоб збільшити

The cutoff comes first, sharing second. Records she can’t see take places in the 2,000, and her case lands in the discarded bucket. ⟲

Now push it to the worst case the mechanics allow. An object holds 100,000 records, and sharing lets this user see 1,000 of them. She’s looking for 10 specific records, and she can see all 10. Her search term matches 3,000 records. The first 2,000 found are all records she can’t see; her 10 are among the 1,000 past the cutoff, in the discarded bucket. Sharing removes all 2,000 that were kept, and she gets no results, for records she knows are there and is allowed to see. ⟲

Visible, and still not found Three columns of small squares, each square 10 records, for an object of 100,000 records of which she can see 1,000. First, the first pass: the 2,000 kept, every one a record she can't see, all slate; tagged the cutoff is full. Second, the discarded bucket: the other 1,000 matches, faded, and among them, in coral, her 10 records, visible to her and discarded; tagged her 10 are here. Third, what she sees: sharing removes all 2,000 kept, so 0 results, an empty column; tagged nothing found. Underneath: the worst case the mechanics allow; Salesforce says search gives priority to records a user can access, so real results are usually better, but when they aren't, this is why. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.41.0", "built": "2026-10-22", "id": "DGM-DA-QR-46", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "units 0.3.0", "theme": "stevetecharc 1.4.0"} each square = 10 records · an object of 100,000 records; she can see 1,000 of them 2,000 kept the cutoff is full First pass: the 2,000 kept every one a record she can't see 1,000 discarded her 10 are here The discarded bucket the other 1,000 matches, her 10 among them 0 results nothing found What she sees sharing removes all 2,000 kept a match she can't see discarded: past the cutoff her 10 records: visible to her, and discarded The worst case the mechanics allow. Salesforce says search gives priority to records a user can access, so real results are usually better, but when they aren't, this is why. © 2026 Twinshark LLC · stevetecharc.com
Натисніть, щоб збільшити

Visible to her, and still not found: the 2,000 places went to records she can’t see. ⟲

To be fair to Salesforce, this is the edge, not the everyday. The same Help article says: “The search engine’s priority is to return accessible records for users with limited access in an org” (How Search Crowding Affects Search Results (відкривається в новій вкладці)), and relevance takes access into account. Most of the time that keeps users with narrow access out of this trap. But when someone with limited access swears a record is missing from search and then finds it by opening a list view, this is why, and the fix is the same: a more specific search, fewer objects, fewer records that compete. ⟲

That’s the heart of it. “The search engine looks for matches to the search term across a maximum of 2,000 records”, and only then applies each user’s permissions, so the user sees only what they’re allowed to (SOSL Limits on Search Results (відкривається в новій вкладці), SOQL and SOSL Reference). So 2,000 irrelevant matches, including records this user can’t even see, can crowd out the one they wanted before sharing ever trims the list. The question isn’t only “how fast is search?” It’s did we design search so the useful answer can surface? ⟲

So when someone says “I searched and it wasn’t there,” the first questions are: how many records matched before the limit, how many objects were searched, and who was searching? ⟲

The fix is always the same idea: fewer, better matches before the limit. Here’s the playbook I’d hand an admin and an architect when someone says “I searched and it wasn’t there.” Work through it in order. ⟲

Is it search crowding? A decision flow read from top to bottom. It starts with a symptom: I searched and it wasn't there, for a record the user knows exists. First question: was it loaded or changed in the last few hours? If yes, wait for the index; bulk loads can take hours to be searchable. If no: is it hidden from this user? If yes, fix access, not search: profile, permissions, sharing. If no: is the object or field left out of search? If yes, make it searchable on purpose: Allow Search, Search Manager, the 120-day rule. If no, a dashed barrier: measure it, searching the term as that user, one object at a time. Then: does the term fill the limit? If yes, it's crowding: work the playbook, cutting the noise, fixing the searches and teaching the term. If no, try a more specific term: the record may be ranked low, not missing. Underneath: rule out freshness, access and searchability first, then measure. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.41.0", "built": "2026-10-22", "id": "DGM-DA-QR-47", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "flow/decision 0.1.0", "theme": "stevetecharc 1.4.0"} “I searched and it wasn't there” a record the user knows exists Was it loaded or changed in the last few hours? Wait for the index bulk loads can take hours to be searchable Is it hidden from this user? Fix access, not search profile, permissions, sharing Is the object or field left out of search? Make it searchable on purpose Allow Search, Search Manager, the 120-day rule Measure it: search the term as that user, one object at a time Does the term fill the limit? It's crowding: work the playbook cut the noise, fix the searches, teach the term Try a more specific term the record may be ranked low, not missing yes no yes no yes no yes no Rule out freshness, access and searchability first. Then measure. HOW TO READ IT a step a question an answer yes goes right to an answer; no goes down to the next question a barrier: nothing crosses until it holds © 2026 Twinshark LLC · stevetecharc.com
Натисніть, щоб збільшити

Rule out freshness, access and searchability first. Then measure. ⟲

Not every missing record is crowding. Check the simple causes first: ⟲

Search the broad term again, then search it in one object at a time. If a search comes back at the limit, 2,000 overall or 250 for a single object without a WHERE or ORDER BY, the results were cut off. Note which object supplies most of the matches. In the Henderson example, it’s the work orders, whose delivery addresses are full of the word. ⟲

Data can deserve to exist without deserving to appear in search. These are Setup changes, made in Search Manager (“To use Search Manager: Customize Application AND View Setup”). Do them in this order, from the cheapest to the most structural: ⟲

  1. Turn off objects these users don’t search, by profile. “You can manage searchable objects for each profile in global search.” From Setup, enter Search Manager, select Query Configurations, select the configuration, and “in the Objects List, select an object and turn searchability on or off” (Manage Searchable Objects and Fields (відкривається в новій вкладці)). If care agents never look for work order line items, their profile shouldn’t search them. ⟲
  2. Take noisy custom fields out of the index. From Setup, enter Search Manager, select Index Management, choose the object, and next to the field choose Remove from search index. “Removed fields don’t appear in search results and aren’t used to match results. You can’t remove standard fields,” and “Your changes can take a few hours” (Manage the Search Index (відкривається в новій вкладці)). A long description or address field that matches everything is a good candidate. ⟲
  3. For an object nobody should search, disable its search index. That stops “making its data searchable and stop[s] index credit consumption for that object” (Explore the Search Index with Search Manager (відкривається в новій вкладці)). ⟲
  4. Archive history that no longer needs to be found. Old completed work orders stay in the index and keep competing. Archiving (chapter 7 and module 4’s wrap-up) shrinks the crowd for search and for queries. ⟲
  5. Put identifiers where search looks first. A lookup searches only the record name, and a NAME search group only name fields. If people find a delivery by its partner reference, make sure that value lives in a field search treats as a name or identifier. ⟲

For every custom search, in Apex, in a component or in an agent’s tool: ⟲

Put three habits in the training and the help text: ⟲

  • A more specific term: “Use a more specific search term, such as Industrial Computing San Francisco” (How Search Crowding Affects Search Results (відкривається в новій вкладці)). For our agent, Henderson refrigerator, or the customer’s full name. ⟲
  • One kind of record: “if you’re looking for an account record, search for Industrial Computing in Accounts” (same source). ⟲
  • The complete name in a lookup: “A lookup search uses only the record name”, so “enter Jupiter Hotels instead of just Hotels” (same source). ⟲
The same search, done well A funnel, top to bottom, for the same search done well. At the top, 40 cases match Henderson refrigerator: one object, a specific term. Set aside first: nothing past the limit; 40 is far under 2,000, so every match is analyzed. Then 40 analyzed, all of them cases. Set aside next: 2 she can't see, permissions as before. At the bottom, in navy: 38 she sees, her case near the top, ranked by relevance. Underneath: illustrative numbers; fewer, better matches before the limit, and the case she wanted comes through. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.41.0", "built": "2026-10-22", "id": "DGM-DA-QR-43", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "funnel 0.2.0", "theme": "stevetecharc 1.4.0"} 40 cases match “Henderson refrigerator” one object, a specific term Set aside: nothing past the limit 40 is far under 2,000: every match is analyzed 40 analyzed all of them cases Set aside: 2 she can't see permissions, as before 38 she sees, her case near the top ranked by relevance Illustrative numbers. Fewer, better matches before the limit: the case she wanted comes through. © 2026 Twinshark LLC · stevetecharc.com
Натисніть, щоб збільшити

The same search, done well: a specific term in one object, and her case comes through. ⟲

Index changes “can take a few hours”, so check the next day, not the next minute. Repeat the original search as a user with that profile, not as an admin. An admin with View All Data sees results other users don’t, so an admin’s search proves nothing about crowding. ⟲

Searchability drifts as an org grows, so make it part of the regular review: ⟲

Three people can fix search crowding Three panels side by side. The person searching: a more specific term; one kind of record; the complete name in a lookup. The developer, writing SOSL: few objects, each with a WHERE; search groups, NAME, EMAIL, PHONE; specific terms, not wildcards. The architect and admin: searchable only if people search it; a smaller active population; identifiers where search looks first; check access when it's missing. Underneath: fewer, better matches before the 2,000-record limit. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.41.0", "built": "2026-10-22", "id": "DGM-DA-QR-44", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "comparison 0.4.0", "theme": "stevetecharc 1.4.0"} The person searching A more specific term One kind of record The complete name in a lookup The developer writing SOSL Few objects, each with a WHERE Search groups: NAME, EMAIL, PHONE Specific terms, not wildcards The architect and admin Searchable only if people search it A smaller active population Identifiers where search looks first Check access when it's missing Fewer, better matches before the 2,000-record limit. © 2026 Twinshark LLC · stevetecharc.com
Натисніть, щоб збільшити

Fewer, better matches before the limit. Three people can make that happen. ⟲

You don’t need to write SOSL to be an architect, but you should recognize the levers, because they’re how you keep the right answer from being crowded out: ⟲

  • Search groups. Search only the kinds of fields that matter: “Search groups include NAME, EMAIL, and PHONE fields. For example, FIND ‘Avery Smith’ IN NAME FIELDS RETURNING Account(Id,Name), Lead(Id,Name)” (same source). ⟲
  • RETURNING. Name the objects, and the fields to bring back, and add a WHERE or ORDER BY to get past the 250-record default for one object. ⟲
  • Specific terms. “Keep searches specific and avoid using wildcards, if possible. For example, search with Michael instead of Mi*.” And “Use single-object searches for greater speed and accuracy” (Searching (відкривається в новій вкладці), best practices, Winter ‘27). ⟲
  • Wildcards and operators. An asterisk matches “zero or more characters at the middle or end of your search term”, and a question mark exactly one. Quotes keep a phrase in order, and AND, OR and AND NOT combine terms (FIND {SearchQuery} (відкривається в новій вкладці), SOQL and SOSL Reference). Notice: the middle or the end. Like the index in module 3, search does best when it knows how a word starts. ⟲
  • Divisions. SOSL can be limited to one division (WITH DivisionFilter), the partitioning tool from module 4. ⟲

And a few limits worth knowing. A transaction in Apex can run “Total number of SOSL queries issued: 20”, and “Total number of records retrieved by a single SOSL query: 2,000” (Execution Governors and Limits (відкривається в новій вкладці), Apex Developer Guide, Winter ‘27). One quiet trap: “If SearchQuery is longer than 4,000 characters, any logical operators are removed. For example, the AND operator in a statement with a SearchQuery that’s 4,001 characters defaults to the OR operator, which could return more results than expected” (SOQL and SOSL Limits for Search Queries (відкривається в новій вкладці)). ⟲

Test knowledge. Know SOSL’s limits: at most 2,000 records searched, then permissions applied; 250 for one object unless you add WHERE or ORDER BY; up to 2,000 divided by the number of objects (and no more than 250 each) when you search several; 20 SOSL queries per Apex transaction. Know the levers: search groups (NAME, EMAIL, PHONE), RETURNING, specific terms over wildcards, and wildcards only in the middle or at the end. ⟲

Search reaches across many objects and returns text, so who it runs as matters. In Apex, that changed recently. “Apex database operations, such as SOSL and SOQL queries, DML statements, and Database methods, now run in user mode by default. In user mode, database operations enforce the sharing rules, field-level security, and object permissions of the current user. In earlier API versions, database operations default to system mode” (Database Operations Run in User Mode by Default (відкривається в новій вкладці), release notes, API version 67.0 and later). Code can still say which mode it wants: “To indicate an access mode for a SOQL or SOSL query, insert a WITH USER_MODE or WITH SYSTEM_MODE clause” (Set an Access Mode for Database Operations (відкривається в новій вкладці), Apex Developer Guide). ⟲

And because a search screen takes whatever the user types, it’s a door for injection. Salesforce’s Well-Architected guidance names it: “SOQL or SOSL injections are scoped to a reading that discloses records or fields that the caller shouldn’t be able to reach by widening query conditions”, and asks you to “Validate and sanitize all user input that prevents injection across SOQL, SOSL, and HTML contexts” (Trust (відкривається в новій вкладці)). ⟲

If your org works in more than one language, search doesn’t behave the same in all of them. “Search is available for Fully Supported Languages. However, not all features, including lemmatization and synonym groups, are available in all languages and for all objects. Only exact matches are returned for searches in End-User Languages” (How Einstein Search Works (відкривається в новій вкладці)). Lemmatization is what lets a search for “deliveries” find “delivery”; without it, only the exact word matches. And for languages written without spaces, the engine uses “morphological tokenization” to find the words, so a search for Kyoto (京都) doesn’t match Tokyo Prefecture (東京都) (FIND {SearchQuery} (відкривається в новій вкладці)). For a global care team, test search in each language people actually use. ⟲

Шукайте, щоб знаходити; робіть запити, щоб працювати

Section titled “Шукайте, щоб знаходити; робіть запити, щоб працювати ”

Це не «або–або». Агент пам’ятає «пошкоджений холодильник Henderson»; пошук знаходить звернення чи робоче замовлення; щойно ви маєте його ідентичність, далі працює структуроване отримання. Шукайте, щоб знаходити; робіть запити, щоб працювати.

Але пастки є з обох боків. Щойно пошук стає добрим, команди лінуються зі структурою: «нам не треба це моделювати, люди знайдуть пошуком». Ні. Якщо інформація керує автоматизацією, інтеграцією, безпекою, звітністю, бізнес-правилами, зіставленням чи детермінованим отриманням, дайте їй структуру. Якщо роздрібний партнер — значущий зв’язок, змоделюйте його; не ховайте його назву в описі з надією, що пошук її знайде. Пошук чудовий для знаходження; але це не модель даних. І навпаки: якщо людям справді треба знаходити текст у багатьох полях і об’єктах, не змушуйте їх продиратися крізь лабіринт структурованих фільтрів лише тому, що так простіше команді розробки.

Salesforce’s own case study shows the pattern for a custom search screen. A customer let users search on any of 20 fields, with wildcards, across several objects, and performance suffered. The fixes: “Use only essential search fields”, “De-normalize the data from the multiple objects into a single custom object”, and “Dynamically determine the use of SOQL or SOSL to perform the search based on both the number of fields searched and the types of values entered. For example, very specific values (i.e., no wild cards) used SOQL to query, which allowed indexes to enhance performance” (Custom Search Functionality (відкривається в новій вкладці)). Exact values go to the librarian; words go to search. ⟲

Роками я не бачив, щоб SOSL у проєктах Salesforce використовували хоч близько так часто, як SOQL; транзакційна розробка починається зі структурованих записів і структурованих запитів. ШІ знову робить архітектуру пошуку цікавою. Агент не завжди починає з WHERE Retail_Partner__c = 'Redrock'. Хтось питає: «які клієнти скаржилися на пошкоджену побутову техніку?» або «щось є про проблеми з доставкою в локації Henderson?» Тепер ми переходимо від точного структурованого отримання до пошуку за словами, а зрештою — за змістом.

And keyword search still isn’t semantic search. SOSL finds words. “Find customers unhappy because deliveries keep arriving late” may match records that say “missed window,” “driver arrived after closing,” “third reschedule” or “came two days later,” none of them using the words in the question. Now we’re asking about meaning, which brings in semantic retrieval, and, combined with structure, hybrid retrieval. The grounding chapter takes that up in Choosing How the Agent Gets the Data (coming soon). ⟲

Agents search too. Salesforce’s hosted MCP server gives AI agents a find tool alongside soqlQuery: it “Executes a text search across multiple Salesforce objects simultaneously … Returns a maximum of 2,000 records total. Use search groups to narrow scope” (SObject All (відкривається в новій вкладці), Hosted MCP Servers, checked 2026-10-22). The same limits, the same crowding, the same need for specific terms, now asked by a machine that doesn’t get tired of asking. ⟲

Steve Trucking: який інструмент?

Section titled “Steve Trucking: який інструмент? ”
  • «Дайте мені сьогоднішні доставки Redrock». Об’єкт, партнер, дата: структуровано. SOQL.
  • «Знайдіть запис, де хтось згадав пошкоджену вантажну рампу». Відомі слова, невідоме поле чи об’єкт: пошук тексту. SOSL.
  • «Знайдіть клієнтів, які, схоже, роздратовані повторними затримками». Схожий зміст, інші слова: семантичне отримання.
  • «Знайдіть роздратованих клієнтів Redrock з активними доставками цього тижня». Зміст плюс структуровані фільтри: гібридне отримання.

Що тут вирішує архітектор

Section titled “Що тут вирішує архітектор ”
  • Whether a requirement is structured retrieval, text discovery or something else, instead of defaulting to SOQL; and whether a “contains” belongs in search. ⟲
  • Які об’єкти й вміст заслуговують на доступність для пошуку, щоб шум великих обсягів не витісняв корисні результати.
  • Whether search-index freshness is acceptable, including after bulk loads, or the process needs deterministic structured retrieval. ⟲
  • How the 2,000-record limit, its split across objects, and permissions affect search quality at production volume. ⟲
  • Who search runs as, in code and for agents, and how user input is protected from injection. ⟲
  • How search behaves in each language the business uses. ⟲
  • Де пошук має знаходити записи, а де має вступати структурований запит.

Якщо просять робочі замовлення, де партнер — Redrock, а дата — сьогодні, це структуроване запитання: запит. Якщо просять запис, де хтось писав про зламаний холодильник, — це пошук. Не будуйте десять OR лише тому, що SOQL звичний, і не шукайте по всьому всесвіту лише тому, що ввімкнути пошук скрізь легко. Пошук — не запит. І наступне запитання стає простішим: я знаю структуру, слова чи зміст?