This library provides a search query builder for Shopify's API search syntax. It provides functions to programmatically build complex search queries with connectives, comparators, and modifiers.
Important
This library has been tested on the official examples from the Shopify documentation. If you use complex search queries, please verify if the built search query is correct.
If you find any issues, please open an issue or submit a pull request.
npm install shopify-search-queryThe following examples are taken from the Shopify documentation.
import { buildSearchQuery, eq, and, or, not, gt, lte, prefix, exists } from 'shopify-search-query';
/* Field search */
buildSearchQuery(eq('first_name', 'Bob')); // first_name:Bob
buildSearchQuery(and(eq('first_name', 'Bob'), eq('age', '27'))); // first_name:Bob AND age:27
/* Default search */
buildSearchQuery(eq('Bob')); // Bob
buildSearchQuery(and(eq('Bob'), eq('Norman'))); // Bob AND Norman
/* Range search */
buildSearchQuery(gt('orders_count', '16')); // orders_count:>16
buildSearchQuery(and(gt('orders_count', '16'), lte('orders_count', '30'))); // orders_count:>16 AND orders_count:<=30
/* NOT query */
buildSearchQuery(not(eq('Bob'))); // NOT Bob
buildSearchQuery(not(eq('first_name', 'Bob'))); // NOT first_name:Bob
/* Boolean operators */
buildSearchQuery(and(or(eq('bob'), eq('norman')), eq('Shopify'))); // bob OR norman AND Shopify
/* Grouping */
buildSearchQuery(and(eq('state', 'disabled'), or([eq('sale shopper'), eq('VIP')]))); // state:disabled AND ("sale shopper" OR VIP)
/* Phrase query */
buildSearchQuery(eq('first_name', 'Bob Norman')); // first_name:"Bob Norman"
/* Prefix query */
buildSearchQuery(prefix('norm')); // norm*
/* Exists query */
buildSearchQuery(exists('published_at')); // published_at:*More examples can be found in the tests.
The library provides exports for the comparators, connectives, and modifiers.
Shopify supports the following comparators:
:equality<less-than>greater-than<=less-than-or-equal-to>=greater-than-or-equal-to
import { eq, gt, gte, lte, lt } from 'shopify-search-query';
buildSearchQuery(eq('first_name', 'Bob')); // first_name:Bob
buildSearchQuery(gt('orders_count', '16')); // orders_count:>16
buildSearchQuery(gte('orders_count', '16')); // orders_count:>=16
buildSearchQuery(lt('orders_count', '30')); // orders_count:<30
buildSearchQuery(lte('orders_count', '30')); // orders_count:<=30 If the exported functions collide with your codebase, you can use the sub-exports from shopify-search-query/comparators.
import * as comparators from 'shopify-search-query/comparators';
buildSearchQuery(comparators.eq('first_name', 'Bob')); // first_name:BobShopify supports the following connectives:
ANDOR
Shopify supports a whitespace between two terms as an implicit AND connective. For better readability, this library always uses the explicit AND connective.
import { and, or } from 'shopify-search-query';
buildSearchQuery(and(eq('first_name', 'Bob'), eq('age', '27'))); // first_name:Bob AND age:27
buildSearchQuery(or(eq('first_name', 'Bob'), eq('age', '27'))); // first_name:Bob OR age:27If the exported functions collide with your codebase, you can use the sub-exports from shopify-search-query/connectives.
import * as connectives from 'shopify-search-query/connectives';
buildSearchQuery(connectives.and(eq('first_name', 'Bob'), eq('age', '27'))); // first_name:Bob AND age:27Shopify supports the following modifiers:
NOTnegation
Shopify supports the alternative syntax - for negation. For better readability, this library always uses the explicit NOT syntax for negation.
import { not } from 'shopify-search-query';
buildSearchQuery(not(eq('Bob'))); // NOT Bob
buildSearchQuery(not(eq('first_name', 'Bob'))); // NOT first_name:BobIf the exported functions collide with your codebase, you can use the sub-exports from shopify-search-query/modifiers.
import * as modifiers from 'shopify-search-query/modifiers';
buildSearchQuery(modifiers.not(eq('Bob'))); // NOT BobThe equality comparator (eq) can be used without a field to perform a default search.
buildSearchQuery(eq('Bob')); // BobSquare brackets are used to group multiple clauses to form subqueries. The terms inside the square brackets will be surrounded with parentheses.
// (title:"Caramel Apple") OR (inventory_total:>500 AND inventory_total:<=1000)
buildSearchQuery(
or(
[eq('title', 'Caramel Apple')],
and(
[gt('inventory_total', '500'), lte('inventory_total', '1000')]
)
),
);A whitespace is interpreted by Shopify as an AND connective, therefore values with whitespaces will always be surrounded by double quotes.
buildSearchQuery(eq('first_name', 'Bob Norman')); // first_name:"Bob Norman"Special characters like : \ ( ) in values will be escaped with a backslash.
buildSearchQuery(eq('first_name', 'Bob:Norman')); // first_name:Bob\:NormanDate values will be surrounded by double quotes.
buildSearchQuery(gt('created_at', '2020-10-21')); // created_at:>"2020-10-21"
buildSearchQuery(gt('created_at', '2020-10-21T23:39:20Z')); // created_at:>"2020-10-21T23:39:20Z"