This page is an operator-first reference for building queries against Search Profiles and Search Companies. If you’re looking for full end-to-end scenarios instead, see Search endpoint examples.
Every JSON block below is copy-pasteable into the API Query Tester. If you’re not sure which operator you need, start with the decision table.
Choosing the right operator
Text vs. keyword: why “General Manager” is tricky
Most string fields in the Swarm index are mapped as both text (analyzed — lowercased, tokenized into words) and keyword under a .raw subfield (stored verbatim). Which one you query changes what “match” means.
Many fields in the mappings are aliases (e.g. current_title → job_title, current_company_name → job_company_name). Aliases work for match, but for term/terms you should target the underlying field’s .raw — for example profile_info.job_title.raw, not profile_info.current_title.raw.
Take profile_info.job_title (aliased as current_title) and the value "General Manager":
match — full-text search on the analyzed field. Matches any profile whose title contains the words general or manager (default OR). “Assistant General Manager”, “General Counsel”, and “Product Manager” all match.
match_phrase — full-text with word order preserved. Matches titles containing the words general then manager adjacent to each other. “Senior General Manager” and “General Manager, EMEA” both match; “Manager of General Affairs” does not.
term on .raw — exact keyword match. Only titles that are literally "General Manager" match. Case-sensitive against the stored value.
match — any of the words
match with operator AND — all of the words, any order
match_phrase — exact phrase, adjacent, in order
term on .raw — strict exact match
term on a text field almost always returns zero results. Always target the .raw subfield for exact matches.
AND vs. OR inside one field
All words required
Use match with "operator": "AND" when every token in the query must appear in the field.
At least N of the words
minimum_should_match lets you require a fraction of the tokens instead of all-or-nothing.
AND vs. OR across multiple fields
Use bool to combine clauses. The four clause types:
must — AND. Contributes to score.
filter — AND. Does not contribute to score; faster and cacheable.
should — OR. If used alongside must, it only boosts score; on its own it acts as OR (at least one must match).
must_not — NOT.
AND across fields (data scientists in the US)
Because bool with only should requires at least one to match, this behaves like OR.
For a list of exact values, terms is shorter than multiple should clauses:
filter vs. must
must and filter both combine clauses with AND. The difference is scoring: must clauses contribute to a relevance score, filter clauses don’t (and are faster + cacheable).
Rule of thumb: put the clauses that decide relevance in must, and the clauses that just narrow the set (locations, dates, seniorities, exists checks) in filter.
Same query, two shapes — take the earlier “data scientists in the US” example. The location doesn’t need scoring, so moving it into filter is more efficient:
Both queries return the same profiles; the second is faster because the location clause is not scored.
job_title_role and job_seniorities accept a fixed set of lowercase values — see Canonical values. job_company_industry is free-form (e.g. "Software Development", "Computer Software"); values vary by source, so term matches can miss unless you know the exact string.
Negation and existence
Exclude a value (must_not)
Product managers not currently at Google:
Field must be present (exists)
Profiles with at least one email on file:
Ranges and dates
range supports gte, gt, lte, lt. Dates accept either YYYY-MM-DD or relative expressions like now-30d, now-1y, now.
Profiles whose current job was updated in the last year:
Combine a range with a text search — profiles that changed to a “Head of” role in the last 90 days:
When you combine a range with a specific canonical value (like job_seniorities: "director"), the intersection can be small or empty depending on your team’s network. If a compound query returns zero, test each clause on its own first to isolate which one is over-filtering.
Multi-field text search
multi_match runs the same query text across several fields at once.
Nested fields (work experience)
Anything under profile_info.experience.* is a nested document — you can’t match it with a flat clause. Wrap the query in nested with the correct path.
Anyone who has ever worked at Google
Held a “Product Manager” role at Google in the past (not necessarily current)
For a more complete “worked there but not currently” pattern, see Search endpoint examples.
Common pitfalls
term on a text field returns nothing. Use .raw on the underlying field (e.g. job_title.raw, job_company_name.raw) for exact matches. Aliased names like current_title.raw do not resolve — always target the real field.
- Keyword fields with a lowercase normalizer. Fields like
job_seniorities, job_title_role, and job_company_industry are stored lowercased, so term values must be lowercase (e.g. "senior", "marketing & product management").
- Free-form vs. canonical values.
job_seniorities and job_title_role accept a fixed set of values (Canonical values); job_company_industry is enrichment-source data with varying strings — match on the text form is safer than term unless you know the exact value.
match_phrase is not case-sensitive. The analyzer lowercases both the query and the indexed value. If you need case-sensitivity, use term on .raw.
- Forgetting
nested. Any field path starting with profile_info.experience., profile_info.education., or profile_info.certifications. needs a nested wrapper with the matching path.
should without minimum_should_match when mixed with must. Once you add a must clause, should clauses only boost scoring — they no longer require any match. Set "minimum_should_match": 1 when you want OR behavior.
- Using
must for non-scored filters. Move seniorities, industries, date ranges, and exists checks into filter for a faster query.
Next steps