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.
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.