Search
Saleor provides full-text search capabilities across key entities in the system, allowing you to find records by matching terms against multiple fields simultaneously.
Added in Saleor 3.23
Supported Modules​
| Module | Searchable Fields |
|---|---|
| Products | Name, description, variant SKU, variant name, attribute values |
| Orders | Order number, user email, customer name, customer note, external reference, billing/shipping address, line items, payments, transactions, discounts, invoices, order notes |
| Customers | First name, last name, email (including domain), addresses |
| Gift Cards | Code (last 4 digits), full code, tags, used by / created by email and name |
| Checkouts | Token, email, user name, billing/shipping address, line items, payments, transactions |
| Pages | Title, slug, content, page type name and slug, attribute values |
Field details
The following sections describe exactly which sub-fields are indexed for shared concepts like addresses, line items, and payments.
Address fields​
Applies to: Orders, Customers, Checkouts
firstNamelastNamestreetAddress1streetAddress2companyNamecitycityAreacountryAreacountryNamecountryCodepostalCodephone
Line item fields​
Applies to: Orders, Checkouts
Orders:
productSkuproductNamevariantNametranslatedProductNametranslatedVariantName
Checkouts:
variant.skuproduct.namevariant.name
Payment fields​
Applies to: Orders, Checkouts
paymentIdpspReference
Transaction fields​
Applies to: Orders, Checkouts
transaction.tokentransaction.pspReferencetransaction.events.pspReferences
Order-specific fields​
In addition to the shared fields above, orders also index:
Discounts:
discount.namediscount.translatedName
Invoices:
ID
Order notes:
- Messages from
NOTE_ADDEDandNOTE_UPDATEDevents
Search Access Points​
The enhanced search is available via two entry points:
- Root-level
searchargument — e.g.,orders(search: "coffee") filter.searchfield — e.g.,orders(filter: { search: "coffee" })
Both use the same underlying full-text search engine.
Search Operators​
Every search term uses prefix matching by default — the query coff will match
"coffee", "coffeehouse", etc. The only exception is when a term is wrapped in double
quotes ("…"), which switches to exact phrase matching where the full phrase must
appear as-is.
Multiple terms can be combined with the following operators:
| Operator | Syntax | Example | Description |
|---|---|---|---|
| Prefix matching | term | coff | Matches "coffee", "coffeehouse", etc. (default behavior) |
| AND (implicit) | term1 term2 | coffee shop | Both terms must match; each term is prefix-matched |
| AND (explicit) | term1 AND term2 | coffee AND shop | Same as implicit AND; both terms must match |
| OR | term1 OR term2 | coffee OR tea | Either term matches (uppercase OR required); each term is prefix-matched |
| NOT | -term | coffee -decaf | Excludes results containing prefix matches for "decaf" |
| Exact phrase | "phrase" | "green tea" | Matches the exact phrase only — no prefix matching |
| Combining | mixed | -"green tea" coffee | Exclude an exact phrase and require a prefix-matched term |
Search Behavior​
Case Sensitivity​
Search is case-insensitive. Searching for Coffee, coffee, or COFFEE will return the same results.
Accent-Insensitive Search​
Search is accent-insensitive. Accented characters are treated the same as their unaccented equivalents, so you can find items regardless of whether their names contain special diacritical marks.
For example, searching for Magnesium will also return items named Magnésium B6.
This works in both directions — a query with accents will match unaccented content, and a query without accents will match accented content.
Special Characters​
Certain special characters are automatically converted to spaces during search processing. This ensures search queries work reliably even when they contain punctuation or special symbols.
Characters converted to spaces: ( ) & | ! : < > ' *
For example:
- Searching for
22:20is treated as two separate terms:22and20 - Searching for
(coffee)searches for:coffee
Preserved characters: Letters, numbers, underscore (_), hyphen (-), at sign (@), and period (.)
Unclosed Quotes​
If you forget to close a quoted phrase, the search will treat everything after the opening quote as part of the phrase:
"green tea(missing closing quote) → searches for the phrase"green tea"
Empty or Invalid Queries​
- Empty search string — Returns no results
- Only special characters — If the query contains only special characters that get converted to spaces (e.g.,
::::), it returns no results - Whitespace only — Returns no results
Examples​
Simple product search​
Use the root-level search argument to find products:
- Query
- Variables
- Result
query SearchProducts($search: String) {
products(first: 10, search: $search) {
edges {
node {
id
name
}
}
}
}
{
"search": "coffee"
}
{
"data": {
"products": {
"edges": [
{
"node": {
"id": "UHJvZHVjdDox",
"name": "Premium Coffee Beans"
}
},
{
"node": {
"id": "UHJvZHVjdDoy",
"name": "Coffee Maker"
}
},
{
"node": {
"id": "UHJvZHVjdDoz",
"name": "Coffeehouse Blend"
}
}
]
}
}
}
Search with operators on checkouts​
Use filter.search with operators to refine results:
- Query
- Variables
- Result
query SearchCheckouts($filter: CheckoutFilterInput) {
checkouts(first: 10, filter: $filter) {
edges {
node {
id
email
}
}
}
}
{
"filter": {
"search": "coffee -decaf"
}
}
{
"data": {
"checkouts": {
"edges": [
{
"node": {
"id": "Q2hlY2tvdXQ6MQ==",
"email": "customer@example.com"
}
},
{
"node": {
"id": "Q2hlY2tvdXQ6Mg==",
"email": "buyer@example.com"
}
}
]
}
}
}
Explicit relevance sorting​
Use the RANK sort field to explicitly sort by relevance:
- Query
- Variables
- Result
query SearchCustomers($filter: CustomerFilterInput, $sortBy: UserSortingInput) {
customers(
first: 10
filter: $filter
sortBy: $sortBy
) {
edges {
node {
id
firstName
lastName
email
}
}
}
}
{
"filter": {
"search": "john"
},
"sortBy": {
"field": "RANK",
"direction": "DESC"
}
}
{
"data": {
"customers": {
"edges": [
{
"node": {
"id": "VXNlcjox",
"firstName": "John",
"lastName": "Smith",
"email": "john.smith@example.com"
}
},
{
"node": {
"id": "VXNlcjoy",
"firstName": "Johnny",
"lastName": "Doe",
"email": "johnny.doe@example.com"
}
},
{
"node": {
"id": "VXNlcjoz",
"firstName": "Johnson",
"lastName": "Williams",
"email": "johnson.w@example.com"
}
}
]
}
}
}
Overriding the default sort order​
By default, search results are sorted by relevance. You can override this
with any other supported sortBy field:
- Query
- Variables
- Result
query SearchProductsSorted($search: String, $sortBy: ProductOrder) {
products(
first: 10
search: $search
sortBy: $sortBy
) {
edges {
node {
id
name
}
}
}
}
{
"search": "coffee",
"sortBy": {
"field": "NAME",
"direction": "ASC"
}
}
{
"data": {
"products": {
"edges": [
{
"node": {
"id": "UHJvZHVjdDoy",
"name": "Coffee Maker"
}
},
{
"node": {
"id": "UHJvZHVjdDoz",
"name": "Coffeehouse Blend"
}
},
{
"node": {
"id": "UHJvZHVjdDox",
"name": "Premium Coffee Beans"
}
}
]
}
}
}
Relevance Ranking​
- By default, results are sorted by relevance (
RANK) when a search query is provided. - Scoring algorithm:
- Exact matches receive 2x weight in relevance scoring
- Prefix matches receive 1x weight in relevance scoring
- For example, searching for "coffee" will rank products with the exact word "coffee" higher than products containing "coffeehouse"
- The default
RANKsorting can be overridden using thesortByparameter. - A
RANKsort field is available for explicit relevance sorting. - Using
RANKsort without a search query will result in an error.