Bulk operation to retrieve all inventory for a large list of product IDs

Bulk operation to retrieve all inventory for a large list of product IDs

aveshopstech
Shopify Partner
33 1 28

Hey all,

Our app syncs inventory for our products to shops, but the target shops have products from multiple sources, not just our system. I want to periodically check the shop's inventory levels at a certain location against the stock in the source warehouse in order to update the shop, if necessary. (There are already mechanisms in place to keep inventory up-to-date in a near-real-time fashion, but every once in a while something gets out of whack.) Because we only want to check our own products on the shop, I need to query shop products based on the Product ID that we store on our side. A query to get all products and related inventory looks like this:

 

 

query($ids: [ID!]!, $locationId: ID!) {
  nodes(ids: $ids) {
    ... on Product {
      id
      variants(first: 100) {
        edges {
          node {
            id
            legacyResourceId
            inventoryItem {
              id
              legacyResourceId
              inventoryLevel(locationId: $locationId) {
                available
              }
            }
          }
        }
      }
    }
  }
}

#Query Variables:
{
    "locationId": "gid://shopify/Location/12345",
    "ids": [
        "gid://shopify/Product/12345",
        "gid://shopify/Product/12346",
        "gid://shopify/Product/12347"
    ]
}

 

 

 

However, some of these shops might have hundreds or thousands of products. Not only would a query like this take a long time, but in many cases the query would fail due to MAX_INPUT_SIZE_EXCEEDED when the `ids` array gets too big. So, there are two main problems:

1. The above query is too slow -- This problem can likely be solved with a bulk operation.

2. How do I query for a specific, LARGE list of products on a shop all at once?

Regarding speed, unfortunately the query above can't be nicely wrapped in a bulk operation. The first issue is that, according to the docs, a bulk operation query can't use the top-level `node` and `nodes` fields. Also, a maximum of only two nested connection levels can be queried. The query above breaks both of those rules. I attempted to accomplish the same goal above, but without using the root `node` field, and with a max of two nested connections. The resulting query looks like this:

 

 

query($search: String!, $locationId: ID!) {
  productVariants(first: 1000, query: $search) {
    edges {
      node {
        id
        legacyResourceId
        product {
          id
          legacyResourceId
        }
        inventoryItem {
          id
          legacyResourceId
          inventoryLevel(locationId: $locationId) {
            available
          }
        }
      }
    }
  }
}

#Query Vars
{
	"locationId": "gid://shopify/Location/12345",
	"search": "product_id:12345 OR product_id:12346 OR product_id:12347"
}

 

 

 

Once again, trouble in paradise. The query works fine up to a certain point, but once the concatenated query "search" string reaches a certain length, the returned data is empty, like this:

 

 

"data": {
  "productVariants": {
    "edges": []
  }
}

 

 

 

So... back to the drawing board. How can I get all inventory levels for a list of items for a specific location on a shop in a manner that is friendly to bulk operations? Any and all help is much appreciated!

Replies 2 (2)

ozzyonfire
Shopify Partner
49 2 17

Sorry to revive an old thread; but this is how we accomplish a similar task. 

 

First you could just ignore that you only want to retrieve specific products and just retrieve them all; then when you parse the returned JSONL only worry about the products in your list. I'm aware that there's some overhead here, but I'm not sure how to only query for specific products. 

 

Secondly, we use the inventoryItems query to get back stock information. So the query would look something like

{
      inventoryItems {
        edges {
          node {
            variant {
              id
              price
              inventoryQuantity
              compareAtPrice
              availableForSale
              barcode
              product {
                id
              }
            }
            id
            sku
            tracked
          }
        }
      }
    }

 

Send that in as a bulk query and you should get the information you need in one level. So you don't have to keep track of parent objects or do any mapping. 

 

However, if someone knows how to do a bulk query and only query specific ids, please share! That's how I stumbled upon this thread.

Elrendio
Shopify Partner
14 0 5

Is this still as broken?

 

I need to query products in large batches following receiving tons of update webhooks.

 

Querying everything is too costly because there are still far more products in store than webhooks.

 

Doing that directly through the API doesn't work as the rate-limiting of the API is too constraining for the rate at which Shopify sends webhooks, which means I can never catch up and end up freezing the whole app as all of its queries pile up.

 

So I want to do that through batch querying, but the bug where if I query too many IDs it gets empty seems like it would prevent that approach as well.

 

What would be the way to do that?