Order Search
The Order Search feature is intended for merchants to perform searches on a large number of Orders in a Project.
Order Search is available only in the Google Cloud and AWS Regions.
The retention period for Orders returned by this API is 3 months. This feature is not intended for searching through a customer's order history in a storefront application. The Order Search API does not return the resource data of the matching Orders. Instead, it returns a list of Order IDs, which can then be used to fetch the Orders by their ID.
Since the response also contains the version of the matching Order, it allows you to:
- maintain a cache of Orders,
- compare version numbers to detect outdated Orders,
- detect if the search index for an Order is out of date and react accordingly (for example display a warning, or initiate an update of the Order search index).
Activation of the API
The Order Search API is not active for the Project by default. If the API is deactivated for your Project, the Search Orders endpoint returns a 404 Not Found error.
To activate the API for your Projects, please choose one of the following options:
- using the Change Order Search Status update action on the Project API.
- contacting the Composable Commerce support team and provide the region, project key(s), and use case(s).
Once the Project setting has been changed, the indexing of all Orders existing in the Project will start and the Search Orders endpoint will become fully functional soon after.
Automatic deactivation
The Order Search API is automatically deactivated for a Project if there have been no calls to the Search Orders endpoint in the last 30 days. The API can be reactivated again using any of the options listed in Activation of the API.
Representations
OrderSearchRequest
query | The Order search query. |
sort Array of OrderSearchSorting | Controls how results to your query are sorted. If not provided, the results are sorted by relevance in descending order. |
limit Int | The maximum number of search results to be returned on one page. Default:10 Maximum: 100 |
offset Int | The number of search results to be skipped in the response for pagination. Default:0 Maximum: 10 000 |
{"query": {"and": [{"fullText": {"field": "customLineItems.name","language": "en","value": "banana"}},{"filter": [{"exact": {"field": "store.name","language": "en","value": "fruit_store"}}]}]},"sort": [{"field": "customLineItems.name","language": "en","order": "desc"}],"limit": 50,"offset": 0}
OrderPagedSearchResponse
total Int | Total number of results matching the query. |
offset Int | Number of elements skipped. |
limit Int | Number of results requested. Maximum:100 |
hits Array of Hit | Actual results. |
Hit
id String | Unique identifier of the Order. |
version Int | Current version of the Order. |
relevance Float | The higher the value is, the more relevant the hit is for the search request. Maximum:1 |
Search Orders
If this endpoint responds with 404 Not Found error, the feature has been deactivated due to inactivity and must be reactivated before API requests will succeed.
Use the Check if Order Search index exists endpoint to see if there is an index available.
view_orders:{projectKey}
region String | Region in which the Project is hosted. |
projectKey String |
|
application/json
application/json
{"total": 3,"offset": 0,"limit": 50,"hits": [{"id": "c2d430e8-1ccf-44c8-8976-36763b572f3e","version": 12,"relevance": 0.9871},{"id": "ee8e3533-00d2-43c2-a2f4-57b1eee0f5b4","version": 2,"relevance": 0.735654},{"id": "9a9e129c-2ed1-436d-90d9-af60d83490ed","version": 44,"relevance": 0.42415}]}
Check if Order Search index exists
Checks whether a search index for the Project's Orders exists.
Returns a 200 OK
status if the index exists or a 404 Not Found
error otherwise.
view_orders:{projectKey}
region String | Region in which the Project is hosted. |
projectKey String |
|
The index exists and the Search Orders endpoint can be used.
curl --head https://api.{region}.commercetools.com/{projectKey}/orders/search -i \--header 'Authorization: Bearer ${BEARER_TOKEN}'
On the GraphQL endpoint you can use following query:
query FetchIndicesExists {ordersIndicesExist {searchableIndexExistsnewInProgress}}
The query response contains the following fields indicating the status of the search index:
searchableIndexExists
- the index exists and Orders can be searched.newInProgress
- the index is being created by a job. Use thereIndexAllOrders
mutation to get the job ID.
Find below an example for a FetchIndicesExists
query to be executed as cURL command:
$ curl -X POST https://api.{region}.commercetools.com/{projectKey}/orders/indexer/graphql \-H "Content-Type:application/json" \-H "Authorization:Bearer ..." \-d '{"query": "{ ordersIndicesExist { searchableIndexExists } }" }'
Searchable Order fields
The following list contains the Order fields that are supported in query expressions.
Some fields containing data of referenced resources are not updated automatically. Their values are kept in the their original state, even if the referenced resource was changed. You need to initiate an update to get the most recent values for those fields.
Number and date fields
Use the following fields in exact, exists, and range query expressions. Data type indicates the type of field for the field.
Standard field | Data type | Query for Orders |
---|---|---|
completedAt | dateTime | completed at a certain date and time. |
createdAt | dateTime | created at a certain date and time. |
lastModifiedAt | dateTime | last modified at any of its fields at a certain date and time. |
version | long | with a certain version of the resource. |
customLineItems.state.quantity | long | with Custom Line Item's ItemState of a certain quantity. You may need to initiate an update to get the latest state of this field. |
lineItems.state.quantity | long | with Line Item's ItemState of a certain quantity. |
returnInfo.items.createdAt | dateTime | with ReturnItems created at a certain date and time. |
returnInfo.items.lastModifiedAt | dateTime | with ReturnItems last modified at a certain date and time. |
returnInfo.returnDate | dateTime | with ReturnInfo of a certain date and time. |
totalPrice.centAmount | long | with a total price of a certain amount. |
Phone fields
Use the following text type fields in exact, fullText, prefix, and exists query expressions.
On these fields all non numeric characters are ignored in search requests.
For example, a query of type fullText for (783) 627-3740
will also match (783) 6273740
.
The same applies to prefix queries.
Special characters are only taken into account when performing queries of type exact.
Standard field | Query for Orders with |
---|---|
billingAddress.mobile | a billing address of a certain mobile number. |
billingAddress.phone | a billing address of a certain phone number. |
itemShippingAddresses.mobile | a Line Item shipping address of a certain mobile number. |
itemShippingAddresses.phone | a Line Item shipping address of a certain phone number. |
shippingAddress.mobile | a shipping address of a certain mobile number. |
shippingAddress.phone | a shipping address of a certain phone number. |
Text fields
Use the following text type fields in exact, fullText, prefix, wildcard, and exists query expressions.
Standard field on Order | Query for Orders |
---|---|
all | with a certain string in the combination of all fields. |
country | with a certain country. |
createdBy.clientId | created by an API Client with a certain client ID. |
customerEmail | with a certain Customer email address. |
customerGroup.key | from Customers of a certain Customer Group specified by its key .You may need to initiate an update to get the latest state of this field. |
customerGroup.name | from Customers of a certain Customer Group specified by its name .You may need to initiate an update to get the latest state of this field. |
lastModifiedBy.clientId | last modified by an API Client with a certain client ID. |
orderState | with a certain OrderState. |
paymentState | with a certain PaymentState. |
shipmentState | with a certain ShipmentState. |
state.name | with a State of a certain name for the language specified in the query expression..You may need to initiate an update to get the latest state of this field. |
store.name | with a Store of a certain name for the language specified in the query expression..You may need to initiate an update to get the latest state of this field. |
Standard field on Billing Address | Query for Orders with a billing address of |
---|---|
billingAddress.city | a certain city. |
billingAddress.company | a certain company. |
billingAddress.country | a certain country. |
billingAddress.firstName | a certain first name. |
billingAddress.lastName | a certain last name. |
billingAddress.postalCode | a certain post code. |
Standard field on Item Shipping Address | Query for Orders with a Line Item Shipping address of |
---|---|
itemShippingAddresses.city | a certain city. |
itemShippingAddresses.company | a certain company. |
itemShippingAddresses.country | a certain country. |
itemShippingAddresses.firstName | a certain first name. |
itemShippingAddresses.lastName | a certain last name. |
itemShippingAddresses.postalCode | a certain post code. |
Standard field on Shipping Address | Query for Orders with a Shipping address of |
---|---|
shippingAddress.city | a certain city. |
shippingAddress.company | a certain company. |
shippingAddress.country | a certain country. |
shippingAddress.firstName | a certain first name. |
shippingAddress.lastName | a certain last name. |
shippingAddress.postalCode | a certain post code. |
Standard field on Line Items and Custom Line Items | Query for Orders with |
---|---|
lineItems.productId | Line Items of a certain Product with a specified id . |
lineItems.variant.sku | Line Items of a certain Product Variant with a specified sku . |
lineItems.name | Line Items of a certain Product name for the language specified in the query expression.. |
lineItems.state.state.name | Line Items of a certain State name for the language specified in the query expression..You may need to initiate an update to get the latest state of this field. |
customLineItems.name | Custom Line Items of a certain name for the language specified in the query expression..You may need to initiate an update to get the latest state of this field. |
customLineItems.state.state.name | Custom Line Items of a certain State name for the language specified in the query expression..You may need to initiate an update to get the latest state of this field. |
Standard field on Payment, Return, or Shipping Info | Query for Orders with |
---|---|
paymentInfo.payments.paymentMethodInfo.method | a certain payment method. You may need to initiate an update to get the latest state of this field. |
returnInfo.items.shipmentState | return items in a certain shipment state. |
returnInfo.items.paymentState | return items with a certain payment state. |
shippingInfo.shippingMethodName | a certain Shipping Method. |
Keyword fields
Use the following keyword type fields, containing unique IDs or keys, in exact, prefix, wildcard, and exists query expressions. To query for multiple values of the same field or for several fields in the same request, combine the query expressions with a compound expression.
Standard field on Order | Query for |
---|---|
id | an Order with a specific id . |
orderNumber | an Order with a specific orderNumber . |
createdBy.anonymousId | Orders created by anonymous session with a specific ID. |
createdBy.externalUserId | Orders created by a Customer using external OAuth with a specific user ID. |
lastModifiedBy.anonymousId | Orders last modified by anonymous session with a specific ID. |
lastModifiedBy.externalUserId | Orders last modified by a Customer using external OAuth with a specific user ID. |
origin | Orders with a specific origin . |
customerGroup.id | Orders from Customers of a certain Customer Group specified by its id . |
customLineItems.state.state.key | Custom Line Items with a certain State specified by its key .You may need to initiate an update to get the latest state of this field. |
lineItems.state.state.key | Line Items with a certain State specified by its key .You may need to initiate an update to get the latest state of this field. |
paymentInfo.payments.interfaceId | a Payment of a certain inferfaceId .You may need to initiate an update to get the latest state of this field. |
paymentInfo.payments.transactions.id | a Payment Transaction of a certain id .You may need to initiate an update to get the latest state of this field. |
paymentInfo.payments.transactions.interactionId | a Payment Transaction of a certain inferactionId .You may need to initiate an update to get the latest state of this field. |
returnInfo.returnTrackingId | a certain returnTrackingId on the ReturnInfo.You may need to initiate an update to get the latest state of this field. |
shippingInfo.deliveries.parcels.trackingData.trackingId | a certain trackingId on a Parcel's TrackingData.You may need to initiate an update to get the latest state of this field. |
state.key | Orders with a certain State specified by its key .You may need to initiate an update to get the latest state of this field. |
store.key | Orders with a certain Store specified by its key .You may need to initiate an update to get the latest state of this field. |
totalPrice.currencyCode | Orders with a total price of a certain CurrencyCode. |
Custom Fields
In addition to the standard fields on an Order, you can also search for its Custom Fields, if any.
Custom Field on Order, Payment, and Transaction | Query for Orders |
---|---|
custom.<field-name> | with a Custom Field of a specific name . |
paymentInfo.payments.custom.<field-name> | with Payments with a Custom Field of a specific name .You may need to initiate an update to get the latest state of this field. |
paymentInfo.payments.transactions.custom.<field-name> | with Payment Transactions with a Custom Field of a specific name .You may need to initiate an update to get the latest state of this field. |
To determine the data type of the Custom Field, you must provide the customType
in query expressions.
CustomType
Possible values for the customType
property on query expressions indicating the data type of the field
.
BooleanType
For CustomFieldBooleanType Custom Fields.
StringType
For CustomFieldStringType Custom Fields.
LocalizedStringType
For CustomFieldLocalizedStringType Custom Fields.
EnumType
For CustomFieldEnumType Custom Fields.
LocalizedEnumType
For CustomFieldLocalizedEnumType Custom Fields.
NumberType
For CustomFieldNumberType Custom Fields.
DateType
For CustomFieldDateType Custom Fields.
TimeType
For CustomFieldTimeType Custom Fields.
DateTimeType
For CustomFieldDateTimeType Custom Fields.
SetType.StringType
For CustomFieldSetType of
StringType
Custom Fields.SetType.LocalizedStringType
For CustomFieldSetType of
LocalizedStringType
Custom Fields.SetType.EnumType
For CustomFieldSetType of
EnumType
Custom Fields.SetType.LocalizedEnumType
For CustomFieldSetType of
LocalizedEnumType
Custom Fields.SetType.NumberType
For CustomFieldSetType of
NumberType
Custom Fields.SetType.DateType
For CustomFieldSetType of
DateType
Custom Fields.SetType.TimeType
For CustomFieldSetType of
TimeType
Custom Fields.SetType.DateTimeType
For CustomFieldSetType of
DateTimeType
Custom Fields.
Query expression supported for which CustomType
A checkmark indicates which query expression you can use for which CustomType of field.
You can apply the same expressions for the SetType
of the CustomType as for the individual CustomType itself.
CustomType | exact | fullText | prefix | range | wildcard | exists |
---|---|---|---|---|---|---|
BooleanType | ✓ | ✓ | ||||
NumberType | ✓ | ✓ | ✓ | |||
StringType , EnumType , DateType , TimeType , DateTimeType | ✓ | ✓ | ✓ | ✓ | ✓ | |
LocalizedStringType , LocalizedEnumType | ✓ | ✓ | ✓ | ✓ | ✓ |
Examples
An exact query on a StringType
Custom Field.
{"query": {"exact": {"field": "custom.myOrderField","value": "special order","customType": "StringType"}}}
An exists query on a SetType
of DateType
Custom Field searching through all values for the Custom Field:
{"query": {"exists": {"field": "custom.myDateField","value": "2021-05-10","customType": "SetType.DateType"}}}
Order Search Query
The query expressions to be used for the query
field on OrderSearchRequest, as well as for the Advanced Order Search in the Merchant Center, are documented for multiple Search APIs on the Search query language page.
Search query language terms specific to Order Search are documented on this page.
Query expressions
The field
in query expressions can have any of the searchable Order fields, like orderNumber
, createdAt
, country
including fields of nested objects like LineItems (lineItems.productId
) or ShippingMethods (shippingAddress.firstName
).
For Order Search query expressions with Custom Fields, the customType
field must be used instead of the fieldType
field that is documented for the generic search query language.
Compound expressions
For compound expressions, the following restriction applies to Order Search:
A compound expression can only be used one time on the same level of composition.
For example, this composition of two and
expressions is not supported: Z = (A and
B and
C),
using only one and
expression, like: X = (A and
B), is allowed.
Using a different compound expression is allowed too, like for: Y = (A and
B or
C).
Z can still be specified by (X and
C) since X is a compound expression on a different level then.
Example queries
fullText
A fulltext query for Orders that have "yellow car" as the English name
for any Custom Line Item in the Order.
{"query": {"fullText": {"field": "customLineItems.name","language": "en","value": "yellow car","mustMatch": "any"}}}
exact
An exact query for Orders that have the SKU "chiquita_yellow_123" in any of the Line Items in the Order. The case of the SKU is ignored.
{"query": {"exact": {"field": "lineItems.variant.sku","value": "chiquita_yellow_123","caseInsensitive": true}}}
prefix
A prefix query for Orders with customer emails starting with "commercetoo". The case of the email address is ignored.
{"query": {"prefix": {"field": "customerEmail","value": "commerceto","caseInsensitive": true}}}
range
A range query for Orders last modified between two specific dates:
{"query": {"range": {"field": "lastModifiedAt","gte": "2018-08-25T12:00:00.000Z","lte": "2018-08-26T12:00:00.000Z"}}}
wildcard
A wildcard query for Orders with customer emails that start with "ab" and may or may not contain any additional characters.
{"query": {"wildcard": {"field": "customerEmail","value": "ab*@commercetools.com"}}}
A wildcard query for Orders with customer emails that start with "ab" and have exactly one additional character after that. Case is ignored.
{"query": {"wildcard": {"field": "customerEmail","value": "ab?@commercetools.com","caseInsensitive": true}}}
The similar wildcard query as before, but now with another wildcard in the same value
. The email domain can be any as long as it ends with ".com".
{"query": {"wildcard": {"field": "customerEmail","value": "ab?@*.com","caseInsensitive": true}}}
exists
An exists query for Orders that have the field customerEmail
set:
{"query": {"exists": {"field": "customerEmail"}}}
Compound expression AND
Example of a query with compound expression finding orders with a specific price:
{"query": {"and": [{"exact": {"field": "totalPrice.currencyCode","value": "EUR"}},{"exact": {"field": "totalPrice.centAmount","value": 2222}}]}}
Compound expression OR with boost
Orders that have butter
in the lineItems.name
field are scored as more relevant than those that have butter
in their customLineItems.name
field.
{"query": {"or": [{"fullText": {"field": "lineItems.name","language": "en","value": "butter","boost": 2}},{"fullText": {"field": "customLineItems.name","language": "en","value": "butter"}}]}}
Sorting
Sorting allows you to control how the results of your search query are sorted. If no sort is specified, the results are sorted by relevance in descending order. For more information about sorting the Order Search result, see the search query language documentation.
Example:
The following expression sorts the results ascending by the English Line Item name, but filtered on a specific Product ID:
{"sort": [{"field": "lineItems.name","language": "en","order": "asc","filter": {"exact": {"field": "lineItems.productId","value": "4054a159-7f3e-4fe9-a30c-8db80ca7d665"}}}]}
Note that you can only filter on the same parent field you sort by. In this case on the root of the Order.
Pagination
Pagination allows you to retrieve a large number of search results by requesting them page by page.
For the OrderSearchRequest, the default limit
for a page is 10
, all other parameters of this feature behave as described in the documentation for the search query language.
Search Index updates
As the number of Orders in the Project grows over time and Order States change on the existing Orders, the Order Search index has to be kept in sync with the changes.
Automatic updates
The Order Search index is automatically updated whenever there is a change to an Order. However, this update mechanism only applies to changes to the Order resource itself. Data for resources referenced by an Order, such as Payments, States, or Stores, are initially indexed if they exist when the Order is created, but subsequent changes to these resources will not trigger an update to the Order Search index. You can update the information in these searchable Order fields by initiating an update as described in the next section.
Initiate update
If you notice that the Search Orders endpoint is not returning the most recent Orders, you can initiate a search index rebuild. When a Project is re-indexed, all existing Orders from the last 3 months are re-processed to update the search index. This ensures that any changes made to the Orders, including state transitions or updates to Order details, are accurately reflected in search results.
Re-indexing can take several hours, depending on the volume of Orders.
This service is provided on a GraphQL endpoint by submitting a specific reindex mutation.
Reindex mutation
OAuth 2.0 Scopes: manage_project_settings:{projectKey}
, view_orders:{projectKey}
mutation ReindexAllOrders {reIndexAllOrders {indexingJobIdexistingIndexingJobId}}
This mutation returns following indexing job IDs:
indexingJobId
is the ID of a new indexing job.existingIndexingJobId
is the ID of an already running job making progress.
Check indexing progress
For each indexing job ID you can check the status of the respective jobs like so:
OAuth 2.0 Scopes: manage_project_settings:{projectKey}
, view_orders:{projectKey}
query GetReindexingStatus($jobId: String!) {getReindexingStatus(id: $jobId) {nbrOfIndexedDocumentsnbrOfFailedDocumentstotalNbrOfDocumentspercentCompletedcompleted}}
Stop indexing jobs
You can stop the indexing of all Orders with following mutation:
OAuth 2.0 Scopes: manage_project_settings:{projectKey}
mutation StopIndexingOrders {stopOrdersIndexing {status}}
The response contains the status
of the indexing job.
GraphQL endpoint
You can access the GraphQL endpoint with following URL:
https://api.{region}.commercetools.com/{projectKey}/orders/indexer/graphql
The endpoint accepts HTTP POST requests with following fields in a JSON body:
query
- String - GraphQL query as a stringvariables
- Object - Optional - containing JSON object that defines variables for your queryoperationName
- String - Optional - the name of the operation, in case you defined several of them in the query
GraphiQL
To explore the GraphQL endpoint, you can use an interactive GraphiQL environment with a web browser, accessible through the following URL:
https://api.{region}.commercetools.com/{projectKey}/orders/indexer/graphiql?token={access_token}