-
Notifications
You must be signed in to change notification settings - Fork 199
Working with Product Partition Trees
AdWords API .NET library provides a set of shopping utility classes to simplify working with product partitions (also known as product groups) in shopping campaigns. These utility classes provides two broad set of functionality:
- Ability to work with product partition as a single tree instead of a list of independent adgroup criteria
- Factory methods for creating various criteria types.
This guide shows you how to work with the shopping utility classes.
Shopping utilities consists of three main classes.
Class name | Description |
---|---|
ProductPartitionTree | Represents the product partition tree in a shopping ad group. It is a container for a root ProductPartitionNode, and also handles applying changes made to the tree under the root. |
ProductPartitionNode | Represents a node within the product partition tree. A product partition node wraps a shopping product partition criterion, and has functionality for setting bids, excluding criteria, as well as working with child nodes. |
ProductDimensions | A class that provides factory methods for constructing various product dimension nodes. |
There are two ways of creating a product partition tree.
You can use the DownloadAdGroupTree
method to download a product partition tree from a given ad group as follows:
ProductPartitionTree partitionTree =
ProductPartitionTree.DownloadAdGroupTree(user, adGroupId);
If you have a list of existing ProductPartition criteria, then you may create a ProductPartitionTree
as follows:
List<AdGroupCriterion> existingAdGroupCriteria = new List<AdGroupCriterion>();
long adGroupId = INSERT_ADGROUP_ID_HERE;
…
ProductPartitionTree partitionTree = ProductPartitionTree.CreateAdGroupTree(
adGroupId, existingAdGroupCriteria);
Note that this method will ignore the adgroup ID in individual AdGroupCriterion objects and the ID specified in adGroupId
parameter will be used.
You may also construct a ProductPartitionTree
from a list of fresh criteria that doesn’t belong to any ad group as follows:
List<AdGroupCriterion> newAdGroupCriteria = new List<AdGroupCriterion>();
…
ProductPartitionTree partitionTree = ProductPartitionTree.CreateAdGroupTree(
newAdGroupCriteria);
To navigate the tree, you need to start with the root node of the ProductPartitionTree
. You can then walk the tree recursively as follows:
ProductPartitionTree tree = ...;
ProductPartitionNode rootNode = tree.Root;
WalkTree(rootNode);
void WalkTree(ProductPartitionNode root) {
ProductDimension dimension = root.Dimension;
// Process the node or the underlying dimension.
// ...
if (root.IsSubdivision) {
foreach (ProductPartitionNode childNode in root.Children) {
WalkTree(childNode);
}
}
}
To add a new child node, you need to create a product dimension (or a ProductPartitionNode
) and use the AddChild
method to add it as a child node of the desired parent node. Also, keep in mind that you can add a child node to an existing node only if it is a subdivision node. It it isn’t, you need to convert the node first into a subdivision node using the AsSubdivision()
method. The code snippet below shows the details:
ProductPartitionNode rootNode = tree.Root;
// Ensure that root node is a subdivision.
rootNode.AsSubdivision();
// Add a unit node under root node for brand = "CoolBrand".
ProductPartitionNode coolBrandNode = rootNode.AddChild(
ProductDimensions.CreateBrand("CoolBrand"));
The ProductDimensions
class provides factory methods to help create various ProductDimension
types. The table below lists the details:
Method | Description |
---|---|
CreateType(ProductDimensionType productDimensionType, string productTypeValue) CreateType(ProductDimensionType productDimensionType)
|
Creates a new ProductType node. |
CreateCanonicalCondition( ProductCanonicalConditionCondition condition) CreateCanonicalCondition()
|
Creates a new ProductCanonicalCondition node. |
CreateBiddingCategory(ProductDimensionType productDimensionType, long biddingCategoryId) CreateBiddingCategory(ProductDimensionType productDimensionType)
|
Creates a ProductBiddingCategory node. |
CreateOfferId(string offerId) CreateOfferId()
|
Creates a ProductOfferId node. |
CreateBrand(string brand) CreateBrand()
|
Creates a ProductBrand node. |
CreateCustomAttribute(ProductDimensionType productDimensionType, string attributeValue) CreateCustomAttribute(ProductDimensionType productDimensionType)
|
Creates a ProductCustomAttribute node |
CreateChannel(ShoppingProductChannel channel) CreateChannel()
|
Creates a ProductChannel node. |
CreateChannelExclusivity( ShoppingProductChannelExclusivity channelExclusivity) CreateChannelExclusivity()
|
Creates a ProductChannelExclusivity node. |
Every Subdivision
node should have a catch-all node called the Everything else node. In the table above, the second function in each row creates an Everything else node for the corresponding product dimension.
You may remove a child node using the RemoveChild
method. This method will throw an error if the desired child node is not found under the parent node. You may use the HasChild
method to check if a given parent node has a child node that matches a given dimension, then use the GetChild
method to get the corresponding ProductPartitionNode
, and finally remove the node using RemoveChild
method as shown below:
ProductPartitionNode rootNode = tree.Root;
// Create a product brand node for “CoolBrand”.
ProductBrand coolBrand = ProductDimensions.CreateBrand("CoolBrand");
// Search and remove “CoolBrand” from the root.
if (rootNode.HasChild(coolBrand)) {
ProductPartitionNode childNode = rootNode.GetChild(coolBrand);
childNode.RemoveChild(coolBrand);
}
You may exclude or bid on a leaf node (also called a Unit
node), but not on a subdivision node. ProductPartitionNode
has utility methods to check if a given node is a unit not. If a node isn’t of the correct type, you may change the node type by using AsBiddableUnit
or AsExcludedUnit
respectively. Keep in mind that if either of these methods is invoked for a subdivision node, then all its child nodes will be removed automatically.
The following code snippet shows the usage of these methods:
// Select your root node.
ProductPartitionNode parentNode = partitionTree.Root;
// Ensure that parentNode is a subdivision.
parentNode = parentNode.AsSubdivision();
// Add a unit node for condition = NEW.
ProductPartitionNode newConditionNode = parentNode.AddChild(
ProductDimensions.CreateCanonicalCondition(
ProductCanonicalConditionCondition.NEW));
newConditionNode.AsBiddableUnit().CpcBid = 200000;
// Exclude everything else.
ProductPartitionNode everythingElseNode = parentNode.AddChild(
ProductDimensions.CreateCanonicalCondition()).AsExCludedUnit();
Once you have made all the tree transformations, you can generate a list of operations corresponding to the changes you made using the GetMutateOperations
method of the product partition tree, and then use AdGroupCriterionService.mutate method to push the changes to AdWords. The following code snippet shows how this may be done.
// Make the mutate request, using the operations returned by
// the ProductPartitionTree.
AdGroupCriterionOperation[] mutateOperations =
partitionTree.GetMutateOperations();
if (mutateOperations.Length == 0) {
Console.WriteLine("Skipping the mutate call because the original " +
"tree and the current tree are logically identical.");
} else {
adGroupCriterionService.mutate(mutateOperations);
}
// The request was successful, so create a new ProductPartitionTree
// based on the updated state of the ad group.
partitionTree = ProductPartitionTree.DownloadAdGroupTree(user, adGroupId);
You can refer to the AddProductPartitionTree
code example under ShoppingCampaigns
category for an end-to-end code example.
While ProductPartitionTree
class simplifies product partition management, it doesn’t protect you from building a tree that is syntactically correct, but logically invalid. E.g. It doesn’t validate that the tree can only be 7 levels deep, you cannot partition by the same criteria more than once in a tree hierarchy, etc. It is the developer’s responsibility to ensure these conditions are met when building the tree. If you try to upload a tree that is logically invalid, then AdGroupCriterionService.mutate
call will fail, and you may examine the response to figure out what went wrong.