A space to discuss GraphQL queries, mutations, troubleshooting, throttling, and best practices.
Hello!
Right now, I'm building an application with both frontend and backend where the user can bring products from a specific Shopify Collection and interact with them. Besides this, we'll also provide the user with the ability to filter the products from this collection based on the following product fields: product type, tags, variants, and vendor. As I was searching around, I noticed that there's no way to filter products based on tags by using the Admin REST API (which is the one I've been using to bring all the products from the collection), but this seems to be possible by using the GraphQL API. My question is, is there a way by which I could filter the products of a collection based on the criteria mentioned above using GraphQL? From what I've read so far, this doesn't seem possible, but still wanted to try it and ask the question here.
What I'm trying to do is the following, e.g. : bring a product with a specific size, available in two specific colors, from a specific product type, and under the $50 price belonging to a specific collection. The size and the color would be the variants here.
Could that kind of filtering be possible by using the GraphQL API, or even the REST Admin API? Or if it's not possible with neither of those, do you have any recommendations or workarounds I could try out?
Thanks in advance!
Solved! Go to the solution
This is an accepted solution.
https://www.shopify.com/partners/blog/query-argument-graphql
https://shopify.dev/api/usage/search-syntax
NOTE: the query syntax is presented stupidly in graphiql/grapql there is not an equal sign to start the query string:
So it's # query: "price:<51 AND product_type:* AND has_only_default_variant:true"
NOT # query= "price:<51 AND product_type:* AND has_only_default_variant:true"
Install the graphiql app https://shopify.dev/apps/tools/graphiql-admin-api and explore the documentation of the nodes to identify properties you can use in query parameters.
product with a specific size, available in two specific colors, from a specific product type, and under the $50 price belonging to a specific collection. The size and the color would be the variants here
Please lead with and unwind your descriptions when seeking help with API structure , yes provide background but avoid burying the lead.
There is no way to query by product|variant option AND also filter it with a querystring
If you try to go down through collections to products to variants, filter querying along the way you may hit this error:
Cannot filter by query if the collection is a custom collection
Here sample queries I threw together
query productVariants{
# , query: "collection:'Home page' AND price:<51 AND product_type:* AND managed:true"
# use managed true , inventory_quantity:<0 for inventory you care about
productVariants(first:10, , query: "price:<51 AND managed:true") {
edges{
node{
title
price
inventoryItem {
tracked
}
selectedOptions {
name
value
}
}
}
}
}
query collections {
collections(first: 10, query: "title:'Home page'") {
edges {
node {
title
id
}
}
}
}
You'll want to change has_only_default_variant:true to false has_only_default_variant:false
query products{
products(
first: 10
query: "price:<51 AND product_type:* AND has_only_default_variant:true"
) {
edges {
node {
id
hasOnlyDefaultVariant
title
collections(first: 10) {
edges {
node {
id
title
}
}
}
inCollection(id: "gid://shopify/Collection/70598819862")
priceRangeV2 {
minVariantPrice {
amount
}
}
productType
options {
values
name
id
}
variants(first: 10) {
edges {
node {
id
}
}
}
}
}
}
}
And a combine example that cannot use query argument on a ProductConnection
query MyQuery {
collection(id: "gid://shopify/Collection/70598819862") {
id
title
ruleSet {
rules {
column
relation
condition
}
}
products(
first: 10
# if you try to use the below query you hit this problem:"" Cannot filter by query if the collection is a custom collection "
# query: "price:<51 AND product_type:* AND has_only_default_variant:true"
) {
edges {
node {
id
hasOnlyDefaultVariant
title
collections(first: 10) {
edges {
node {
id
title
}
}
}
inCollection(id: "gid://shopify/Collection/70598819862")
priceRangeV2 {
minVariantPrice {
amount
}
}
productType
options {
values
name
id
}
variants(first: 10) {
edges {
node {
id
selectedOptions {
name
value
}
}
}
}
}
}
}
}
}
Contact paull.newton+shopifyforum@gmail.com for the solutions you need
Save time & money ,Ask Questions The Smart Way
Problem Solved? ✔Accept and Like solutions to help future merchants
Answers powered by coffee Thank Paul with a ☕ Coffee for more answers or donate to eff.org
This is an accepted solution.
https://www.shopify.com/partners/blog/query-argument-graphql
https://shopify.dev/api/usage/search-syntax
NOTE: the query syntax is presented stupidly in graphiql/grapql there is not an equal sign to start the query string:
So it's # query: "price:<51 AND product_type:* AND has_only_default_variant:true"
NOT # query= "price:<51 AND product_type:* AND has_only_default_variant:true"
Install the graphiql app https://shopify.dev/apps/tools/graphiql-admin-api and explore the documentation of the nodes to identify properties you can use in query parameters.
product with a specific size, available in two specific colors, from a specific product type, and under the $50 price belonging to a specific collection. The size and the color would be the variants here
Please lead with and unwind your descriptions when seeking help with API structure , yes provide background but avoid burying the lead.
There is no way to query by product|variant option AND also filter it with a querystring
If you try to go down through collections to products to variants, filter querying along the way you may hit this error:
Cannot filter by query if the collection is a custom collection
Here sample queries I threw together
query productVariants{
# , query: "collection:'Home page' AND price:<51 AND product_type:* AND managed:true"
# use managed true , inventory_quantity:<0 for inventory you care about
productVariants(first:10, , query: "price:<51 AND managed:true") {
edges{
node{
title
price
inventoryItem {
tracked
}
selectedOptions {
name
value
}
}
}
}
}
query collections {
collections(first: 10, query: "title:'Home page'") {
edges {
node {
title
id
}
}
}
}
You'll want to change has_only_default_variant:true to false has_only_default_variant:false
query products{
products(
first: 10
query: "price:<51 AND product_type:* AND has_only_default_variant:true"
) {
edges {
node {
id
hasOnlyDefaultVariant
title
collections(first: 10) {
edges {
node {
id
title
}
}
}
inCollection(id: "gid://shopify/Collection/70598819862")
priceRangeV2 {
minVariantPrice {
amount
}
}
productType
options {
values
name
id
}
variants(first: 10) {
edges {
node {
id
}
}
}
}
}
}
}
And a combine example that cannot use query argument on a ProductConnection
query MyQuery {
collection(id: "gid://shopify/Collection/70598819862") {
id
title
ruleSet {
rules {
column
relation
condition
}
}
products(
first: 10
# if you try to use the below query you hit this problem:"" Cannot filter by query if the collection is a custom collection "
# query: "price:<51 AND product_type:* AND has_only_default_variant:true"
) {
edges {
node {
id
hasOnlyDefaultVariant
title
collections(first: 10) {
edges {
node {
id
title
}
}
}
inCollection(id: "gid://shopify/Collection/70598819862")
priceRangeV2 {
minVariantPrice {
amount
}
}
productType
options {
values
name
id
}
variants(first: 10) {
edges {
node {
id
selectedOptions {
name
value
}
}
}
}
}
}
}
}
}
Contact paull.newton+shopifyforum@gmail.com for the solutions you need
Save time & money ,Ask Questions The Smart Way
Problem Solved? ✔Accept and Like solutions to help future merchants
Answers powered by coffee Thank Paul with a ☕ Coffee for more answers or donate to eff.org
Thank you very much @PaulNewton for the solution, the samples, and the tips as well. Your solution guided me through the right path.
@AleKiller21 No problem could you elaborate on the right path you found for future readers?
Contact paull.newton+shopifyforum@gmail.com for the solutions you need
Save time & money ,Ask Questions The Smart Way
Problem Solved? ✔Accept and Like solutions to help future merchants
Answers powered by coffee Thank Paul with a ☕ Coffee for more answers or donate to eff.org
Sure! What I needed to do was to provide the ability to filter products by the following options: prodcut_type, price, tags, vendor, and by a variant option known as size. The initial problem was that Shopify GraphQL API doesn't allow you to filter by variants. Therefore, what I did was to first fetch from the Shopify GraphQL API the products that would match all the other filters except for the size filter. For example, let's say that someone using my application (which is not a custom online store) decides to filter the products based on the vendor, price, and size (variant). In that case I would first run the following query to bring the first 25 products that match the vendor and price filter:
{
products(first: 25, query: "(price:>=1 AND price:<=75) AND vendor:test") {
edges {
cursor
node {
id
title
priceRangeV2 {
minVariantPrice {
amount
}
maxVariantPrice {
amount
}
}
featuredImage {
originalSrc
altText
}
}
}
}
}
The important part there is the query argument sent which contains the filtering for the vendor and price. After receiving the products from Shopify, I would then run the following GraphQL query to bring the variants associated to the products I received from the query above.
{
productVariants(first: 225, query: "product_id:343534534 OR product_id:5345435345 OR product_id:545556656 OR product_id:23245665456") {
edges {
cursor
node {
id
selectedOptions {
name
value
}
product {
id
title
}
}
}
pageInfo {
hasNextPage
}
}
}
Once I have the variants in memory, I will check which of them have the size variant I'm looking for, E.j. XL. I will then grab the product.id from the variants that matched the size value specified and with that I'll be able to send back to the client side all the products that matched all the filter options sent (price, vendor, and size variant).
The product_ids specified in the second GraphQL query are the ones that I will receive from the response of the first query sent to Shopify. Also, the reason I'm sending first:225 is to bring all the variants of those product ids through a single request (even though there might still be the need to go into the next page of variants). I tried running the second query with a lower limit, but that meant running the second query multiple times which ended up making the client side wait longer for the whole product filtering to finish. Besides that, running the second query with a lower limit number didn't make that much of a difference in the amount of cost points consumed.
I updated the productVariants query to bring a lower number of variants: 225 => 50. This because the requestedQueryCost ended up being too high when specifying the query to bring the first 225 product variants. This was causing Throttled issues when moving between the different productVariants pages as well as in the product pages.