Filtering products by collection_id not working properly

  1. We should be able to exclude products with the collection by using the negation filters (“-collection_id” or “NOT collection_id”). However, this causes extremely unexpected behavior where it returns the same products multiple times, and the products still are in the collection.

  2. We should be able to mix and match this query with other fields. The way the documentation is worded sounds like it’s only supported to match along with specific other fields, which should be documented more clearly if that’s true. But this limitation should be removed if possible. But I’m seeing issues even when filtering along with supported fields. For example, adding the title field it only matches if the title exactly matches. And if you separate the two filters with “OR” it doesn’t match anything. Also matching multiple collections doesn’t seem to work.

Upon further testing, it seems connectives are not supported when using “collection_id”, as adding “AND” or “OR” matches nothing, but taking away the “AND” allows multiple fields to be included. But even that only works in some cases.

Overall it behaves very strangely and doesn’t follow the other rules of the Shopify query syntax, which is very disappointing. It basically only works correctly if you only want to filter by a single collection and nothing else.

@Liam-Shopify I hate to ping you, but this isn’t getting any attention :frowning:

Hi David,

These could be intentional limitations - let me dig into this to find out more.

I too am getting this issue, the graphql app gives me the following error

I have a work around this by adding the collection handle as a value in the tags so I add a tag with the value collection_{handle} so my query now will be

{tag:prodType_Handle String AND tag:Size_100}

I’ve just run into this as well. Apparently for ID fields or numerical fields we can only use the standard comparators

  • :: equality
  • :<: less-than
  • :>: greater-than
  • :<=: less-than-or-equal-to
  • :>=: greater-than-or-equal-to

but there is no way to use a negation, apparently negation only works for text fields.

“warnings”: [
{
“field”: “id”,
“message”: “Expected field to be a positive integer or UUID, received -9833428025658.”
}
]

It would be super helpful to be able to create a query and like tag_not have the ability to say "“give me all products not in the “sale” collection”. This would be a huge help Instead of having the merchant first create a “not sale” collection.

Cheers,
Gary

Facing a similiar issue here:

I am noticing that while using the Product GraphQL APIs, the AND filter isn’t working as expected (or so I think?). In the default dataset for dev stores, there’s a product called The Collection Snowboard: Liquid
Success and it belongs to Automated Collection and Hydrogen collections. When I am building the query variables for looking up the product WITHIN a collection like this:

{ “query”: “(title:liquid) AND (collection_id:one_of_the_collection_ids_here)” }

It’s returning me no products!
Clearly if I remove either the title or collection filters, I am getting the product/products so what am I missing here? Am I making a mistake understanding the purpose of AND?

If there are thousands of products under multiple collections and I want to drill down and filter out products within that collection, how would I achieve that? The OR condition is working as expected.

Shopify Devs, this is a huge and unfortunate limitation to the Products query. There are countless use cases where a developer would want to search products scoped to a collection.

The announcement of the collection_id as a filter to the Products query specifically includes title as a product attribute that can be combined with the collection_id filter. However, as the OP pointed out, it doesn’t work.

Please consider increasing the priority of this ability. Thanks!

Hi everyone,

I’m using the Shopify Admin GraphQL API to retrieve all products within a collection. The query works fine for most stores, but for some of my customers, it doesn’t return all product IDs, even though the collections clearly contain more products in the Shopify admin.

Here’s the query I’m using:

query (
  $first: Int,
  $query: String,
  $after: String,
  $productcursor: String,
  $firstproduct: Int
) {
  collections(first: $first, query: $query, after: $after) {
    edges {
      node {
        id
        products(first: $firstproduct, after: $productcursor) {
          edges {
            node {
              id
            }
            cursor
          }
          pageInfo {
            hasNextPage
            endCursor
          }
        }
      }
      cursor
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}

I’m paginating both the collections and the products inside each collection. However, for some stores, the product list seems incomplete. missing several product IDs that should be there.

Has anyone run into this issue before? Could it be related to:

  • Collection visibility or publication status?

  • Product availability across sales channels?

  • API permissions or rate limits?

  • Smart collections vs. manual collections?

Any insights or suggestions would be greatly appreciated!

Thanks in advance.

Hey Everyone! I’ve been looking in to the issues reported here to better understand what’s happening with the collection_id filter, and wanted to provide you with an update.

  • Combining collection_id filters with wildcard searches (like collection_id:123 AND title:*keyword*) is a known limitation our team is tracking. I previously addressed this in another thread here, and unfortunately there’s no timeline for a fix at this time. This is documented internally and being considered for future improvements.

  • The issues with negation (-collection_id or NOT collection_id) returning duplicate products and unexpected results is similar to the wildcard issue above. We are looking in to this as well

You’re right that the changelog announcement doesn’t adequately explain these limitations. We’re working to improve the documentation to better reflect the actual behavior and constraints of the collection_id filter.

For workarounds, see if any of these will help:

  • For filtering by collection with additional criteria, consider using the collection query instead and applying filters to its products connection
  • For negation scenarios, as Gary suggested, you may need to create tag-based workarounds
  • For exact title matches, use quotes: collection_id:123 AND title:"exact product name"

@Shahram_Foroozan, Your issue is a bit different since you’re already using the collection query approach. When you’re seeing missing products from the collection.products connection, this is most likely related to product visibility or publication status. I’d recommend checking one of the products that isn’t returning by querying it directly (using its product ID) to verify whether it’s available to your app.

2 Likes

Hey everyone,
I came across an some inconsistency while working with product search queries using collection filters and wanted to share the findings here for clarity and discussion.


:gear: Query Example 1 — Using collection_ids (Works, but shows warnings)

{
  "query": "NOT collection_ids:298210197552 NOT collection_ids:298210164784 NOT collection_ids:298210230320 AND status:ACTIVE"
}

Result:

"search": [
  {
    "path": ["products"],
    "query": "NOT collection_ids:298210197552 NOT collection_ids:298210164784 NOT collection_ids:298210230320 AND status:ACTIVE",
    "parsed": {
      "and": [
        { "not": { "field": "collection_ids", "match_all": "298210197552" }},
        { "not": { "field": "collection_ids", "match_all": "298210164784" }},
        { "not": { "field": "collection_ids", "match_all": "298210230320" }},
        { "field": "status", "match_all": "ACTIVE" }
      ]
    },
    "warnings": [
      { "field": "collection_ids", "message": "Invalid search field for this query." },
      { "field": "collection_ids", "message": "Invalid search field for this query." },
      { "field": "collection_ids", "message": "Invalid search field for this query." }
    ]
  }
]

:white_check_mark: Observation:
Even though the system returns warnings saying "Invalid search field for this query", the collection_ids query still not executes correctly or not filters out the products as expected.


:gear: Query Example 2 — Using collection_id (Does Not Work)

{
  "query": "NOT collection_id:298210197552 NOT collection_id:298210164784 NOT collection_id:298210230320 AND status:ACTIVE"
}

Result:

"search": [
  {
    "path": ["products"],
    "query": "NOT collection_id:298210197552 NOT collection_id:298210164784 NOT collection_id:298210230320 AND status:ACTIVE",
    "parsed": {
      "and": [
        { "not": {} },
        { "not": {} },
        { "not": {} },
        { "field": "status", "match_all": "ACTIVE" }
      ]
    }
  }
]

:cross_mark: Observation:
When using collection_id (singular), the parser fails to recognize the field entirely — each not clause is empty, and the filter logic does not apply.


:magnifying_glass_tilted_left: Analysis

  • collection_ids (plural) appears to be the recognized field, but not fully supported in this query context — hence the warnings.

  • collection_id (singular) is completely ignored by the parser, suggesting it’s not a valid field at all for this search endpoint.

  • The warning messages with collection_ids seem misleading


However, collection_id (singular) does not work

Would love to hear if anyone else has run into the same behavior or found a workaround for the warnings.

Hey Karunambika, thanks for sharing your examples. What you are seeing does align with the issues already reported.

1 Like