Products are usually organized in a tree, which is part of a DistirbutionChannel. For both you have IDs, let's say it is a 100 for the DistributionCHannel and a 1 for the tree.
 
When you run a query like this you will get back all products that are assigned to the tree/channel combination:
  query q1 {
  productsearch(treeInfo:{productTreeId:1 distributionChannelId: 100}) {
    content {
      id
      tree {
        nodes {
          treeDistributionChannelId
          treeStaticId
          staticId
          name
        }
      }
    }
  }
}
As you can see, we requested the tree property of every product. Insinde a tree, products can be assigned to 1 or more nodes. Per node, you have the object consisting of 
  • treeDistributionChannelId
    • distributionChannelId from the search parameters
  • treeStaticId
    • productTreeId from the search parameters
  • staticId
    • The Id of the assigned node
  • name
    • The name of the assigned node
 
When you want to request products of a certain node, you can do it like this:
  query q2 {
  productsearch(treeInfo:{
productTreeId:1
distributionChannelId: 100
staticIds:[118]
}) { content { id tree { nodes { treeDistributionChannelId treeStaticId staticId name } } } } }
This will only return products, that are assigned directly to this node. When you also want products that are assigned to the child nodes, you can do it like this:
  query q2 {
  productsearch(treeInfo:{
    productTreeId:1 
    distributionChannelId: 100 
    staticIds:[118] 
    includeProductsOfSubNodes:true }
) {
    content {
      id
      tree {
        nodes {
          treeDistributionChannelId
          treeStaticId
          staticId
          name
        }
      }
    }
  }
}
When you want to know, which products are assigned to which tree nodes, you have to use the productgroupsearch. It provides information about how many products are assigned to which node:
query q4 {
  productgroupsearch(treeInfo: {productTreeId:2 distributionChannelId:114}) {
    content {
      staticId
      nodeName
      numberOfProducts
      nodes {
        content {
          staticId
          nodeName
          numberOfProducts
        }
      }
    }
  }
}
In this example, I requested two levels in the tree. You can nest it as deep as you want to.
 
The query will not return nodes to which no products are assigned. As for the productsearch, you also have the parameter includeProductsOfSubNodes which defaults to false.
 
Let's assume you have such a tree:
  • tree (id 1)
    • Node 1
      • Subnode 2
        • Product A
        • Product B
      • Subnode 3
And this is your query:
query q5 {
  productgroupsearch(treeInfo: {productTreeId:2 distributionChannelId:114}) {
    content {
      staticId
      nodeName
      numberOfProducts
    }
  }
}
In this case, the response will be empty, because you only request the first level and includeProductsOfSubNodes is not sent.
 
When you request like this:
query q6 {
  productgroupsearch(treeInfo: {
    productTreeId:2 
    distributionChannelId:114 
    includeProductsOfSubNodes:true
  }) {
    content {
      staticId
      nodeName
      numberOfProducts
    }
  }
}
or like in the example query q4 you will get a response. For q6 you will get a response, because includeProductsOfSubNodes is set to true, for q4 you will get it because you explicitly requested a level that contains products