Our Partner & Developer boards on the community are moving to a brand new home: the .dev community forums! While you can still access past discussions here, for all your future app and storefront building questions, head over to the new forums.

Shopify API Product Filtering

Solved

Shopify API Product Filtering

AleKiller21
Tourist
5 0 2

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!

Accepted Solution (1)

PaulNewton
Shopify Partner
7450 657 1562

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.

  1. In specific collection
  2. specific product type under the $50 price
    1. product VARIANT with OPTION a specific size 
    2. that is available
    3. in two specific colors

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


View solution in original post

Replies 5 (5)

PaulNewton
Shopify Partner
7450 657 1562

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.

  1. In specific collection
  2. specific product type under the $50 price
    1. product VARIANT with OPTION a specific size 
    2. that is available
    3. in two specific colors

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


AleKiller21
Tourist
5 0 2

Thank you very much @PaulNewton for the solution, the samples, and the tips as well. Your solution guided me through the right path.

PaulNewton
Shopify Partner
7450 657 1562

@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


AleKiller21
Tourist
5 0 2

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 (pricevendor, 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.

AleKiller21
Tourist
5 0 2

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.