소매업용 등록정보 그룹

등록정보 그룹은 실적 최대화 소매업체 캠페인에서 각 애셋 그룹에 포함하거나 제외할 제품을 지정하는 데 사용됩니다. 따라서 등록정보 그룹은 AssetGroupListingGroupFilter 객체를 사용하여 AssetGroup 수준에서 적용됩니다. 이는 제품 그룹이 AdGroup 수준에서 적용되는 다른 유형의 소매 캠페인과 유사합니다.

실적 최대화 소매업체 소매업체 캠페인의 모든 애셋 그룹에는 AssetGroupListingGroupFilter 객체로 구성된 유효한 제품 파티션 트리가 필요합니다. 판매자 센터 계정의 모든 제품을 포함하는 단일 노드 트리를 사용하여 이 요구사항을 충족할 수 있습니다.

UI에서는 이를 제품 그룹이라고 합니다. 여러 측정기준을 사용하여 그룹화하여 제품을 포함하거나 제외할 수 있습니다.

아래 트리를 살펴보세요. 첫 번째 수준에서 제품이 상태별로 '새 상품', '중고품', '기타 제품 상태'로 분류되었습니다. 두 번째 수준에서는 다른 제품 조건의 제품을 브랜드별로 'CoolBrand' 제품, 'CheapBrand', 기타 브랜드로 나누었습니다.

트리의 각 노드는 ListingGroupType로 정의된 하위 그룹 또는 단위입니다. 하위 부문은 트리에 새로운 수준을 도입하고 단위는 트리의 잎입니다. 각 하위 부문은 항상 완전히 파티션되어야 하므로 기타를 나타내는 노드를 포함해야 합니다. 이 예에서 루트 및 Product Condition: (Other) 노드는 하위 부문입니다. 하위 그룹과 단위가 있는 이 트리 구조에서는 단위 수준에서 입찰가를 설정할 수 있으며 모든 제품이 트리에서 하나의 단위 노드에만 속하게 됩니다.

노드는 ListingGroupInfo 클래스의 객체이며, 여기에는 노드가 단위인지 하위 그룹인지 나타내는 ListingGroupType 필드가 포함됩니다. ListingGroupInfoAdGroupCriterionlisting_group로 설정하면 AdGroup에 연결됩니다.

트리를 유효하게 만들려면 단위 노드가 하나 이상 필요합니다. 이 단위는 루트 노드가 될 수 있으며, 루트 노드가 될 수 있으며, 루트 노드가 '모든 제품' 분할이 됩니다. 유효한 등록정보 그룹 트리를 만들어야 광고가 게재됩니다.

실적 최대화 캠페인 등록정보 그룹

실적 최대화 캠페인의 등록정보 그룹은 제품 그룹을 타겟팅할 때 가장 효과적이므로 항목 ID별로 개별 제품 타겟팅보다 이 것을 사용하는 것이 좋습니다. 제품 피드에서 맞춤 라벨 또는 브랜드와 같은 다양한 측정기준을 사용하여 제품을 그룹화할 수 있습니다.

코드 예시

Java

/**
 * Runs the example.
 *
 * @param googleAdsClient the Google Ads API client.
 * @param customerId the client customer ID.
 * @param assetGroupId the asset group id for the Performance Max campaign.
 * @param replaceExistingTree option to remove existing product tree from the passed in asset
 *     group.
 * @throws GoogleAdsException if an API request failed with one or more service errors.
 */
private void runExample(
    GoogleAdsClient googleAdsClient,
    long customerId,
    long assetGroupId,
    boolean replaceExistingTree)
    throws Exception {
  String assetGroupResourceName = ResourceNames.assetGroup(customerId, assetGroupId);

  List<MutateOperation> operations = new ArrayList<>();

  if (replaceExistingTree) {
    List<AssetGroupListingGroupFilter> existingListingGroupFilters =
        getAllExistingListingGroupFilterAssetsInAssetGroup(
            googleAdsClient, customerId, assetGroupResourceName);

    if (!existingListingGroupFilters.isEmpty()) {
      // A special factory object that ensures the creation of remove operations in the
      // correct order (child listing group filters must be removed before their parents).
      AssetGroupListingGroupFilterRemoveOperationFactory removeOperationFactory =
          new AssetGroupListingGroupFilterRemoveOperationFactory(existingListingGroupFilters);

      operations.addAll(removeOperationFactory.removeAll());
    }
  }

  // Uses a factory to create all the MutateOperations that manipulate a specific
  // AssetGroup for a specific customer. The operations returned by the factory's methods
  // are used to construct a new tree of filters. These filters can have parent-child
  // relationships, and also include a special root that includes all children.
  //
  // When creating these filters, temporary IDs are used to create the hierarchy between
  // each of the nodes in the tree, beginning with the root listing group filter.
  //
  // The factory created below is specific to a customerId and assetGroupId.
  AssetGroupListingGroupFilterCreateOperationFactory createOperationFactory =
      new AssetGroupListingGroupFilterCreateOperationFactory(
          customerId, assetGroupId, TEMPORARY_ID_LISTING_GROUP_ROOT);

  // Creates the operation to add the root node of the tree.
  operations.add(createOperationFactory.createRoot());

  // Creates an operation to add a leaf node for new products.
  ListingGroupFilterDimension newProductDimension =
      ListingGroupFilterDimension.newBuilder()
          .setProductCondition(
              ProductCondition.newBuilder()
                  .setCondition(ListingGroupFilterProductCondition.NEW)
                  .build())
          .build();
  operations.add(
      createOperationFactory.createUnit(
          TEMPORARY_ID_LISTING_GROUP_ROOT, createOperationFactory.nextId(), newProductDimension));

  // Creates an operation to add a leaf node for used products.
  ListingGroupFilterDimension usedProductDimension =
      ListingGroupFilterDimension.newBuilder()
          .setProductCondition(
              ProductCondition.newBuilder()
                  .setCondition(ListingGroupFilterProductCondition.USED)
                  .build())
          .build();
  operations.add(
      createOperationFactory.createUnit(
          TEMPORARY_ID_LISTING_GROUP_ROOT,
          createOperationFactory.nextId(),
          usedProductDimension));

  // This represents the ID of the "other" category in the ProductCondition subdivision. This ID
  // is saved because the node with this ID will be further partitioned, and this ID will serve as
  // the parent ID for subsequent child nodes of the "other" category.
  long otherSubdivisionId = createOperationFactory.nextId();

  // Creates an operation to add a subdivision node for other products in the ProductCondition
  // subdivision.
  ListingGroupFilterDimension otherProductDimension =
      ListingGroupFilterDimension.newBuilder()
          .setProductCondition(ProductCondition.newBuilder().build())
          .build();
  operations.add(
      // Calls createSubdivision because this listing group will have children.
      createOperationFactory.createSubdivision(
          TEMPORARY_ID_LISTING_GROUP_ROOT, otherSubdivisionId, otherProductDimension));

  // Creates an operation to add a leaf node for products with the brand "CoolBrand".
  ListingGroupFilterDimension coolBrandProductDimension =
      ListingGroupFilterDimension.newBuilder()
          .setProductBrand(ProductBrand.newBuilder().setValue("CoolBrand").build())
          .build();
  operations.add(
      createOperationFactory.createUnit(
          otherSubdivisionId, createOperationFactory.nextId(), coolBrandProductDimension));

  // Creates an operation to add a leaf node for products with the brand "CheapBrand".
  ListingGroupFilterDimension cheapBrandProductDimension =
      ListingGroupFilterDimension.newBuilder()
          .setProductBrand(ProductBrand.newBuilder().setValue("CheapBrand").build())
          .build();
  operations.add(
      createOperationFactory.createUnit(
          otherSubdivisionId, createOperationFactory.nextId(), cheapBrandProductDimension));

  // Creates an operation to add a leaf node for other products in the ProductBrand subdivision.
  ListingGroupFilterDimension otherBrandProductDimension =
      ListingGroupFilterDimension.newBuilder()
          .setProductBrand(ProductBrand.newBuilder().build())
          .build();
  operations.add(
      createOperationFactory.createUnit(
          otherSubdivisionId, createOperationFactory.nextId(), otherBrandProductDimension));

  try (GoogleAdsServiceClient googleAdsServiceClient =
      googleAdsClient.getLatestVersion().createGoogleAdsServiceClient()) {
    MutateGoogleAdsRequest request =
        MutateGoogleAdsRequest.newBuilder()
            .setCustomerId(Long.toString(customerId))
            .addAllMutateOperations(operations)
            .build();
    MutateGoogleAdsResponse response = googleAdsServiceClient.mutate(request);
    printResponseDetails(request, response);
  }
}

      

C#

/// <summary>
/// Runs the code example.
/// </summary>
/// <param name="client">The Google Ads client.</param>
/// <param name="customerId">The Google Ads customer ID.</param>
/// <param name="assetGroupId">The asset group id for the Performance Max campaign.</param>
/// <param name="replaceExistingTree">Option to remove existing product tree
/// from the passed in asset group.</param>
public void Run(
    GoogleAdsClient client,
    long customerId,
    long assetGroupId,
    bool replaceExistingTree)
{
    GoogleAdsServiceClient googleAdsServiceClient =
        client.GetService(Services.V16.GoogleAdsService);

    string assetGroupResourceName = ResourceNames.AssetGroup(customerId, assetGroupId);

    // We use a factory to create all the MutateOperations that manipulate a specific
    // AssetGroup for a specific customer. The operations returned by the factory's methods
    // are used to optionally remove all AssetGroupListingGroupFilters from the tree, and
    // then to construct a new tree of filters. These filters can have a parent-child
    // relationship, and also include a special root that includes all children.
    //
    // When creating these filters, we use temporary IDs to create the hierarchy between
    // the root listing group filter, and the subdivisions and leave nodes beneath that.
    //
    // The factory specific to a customerId and assetGroupId is created below.
    AssetGroupListingGroupFilterCreateOperationFactory createOperationFactory =
        new AssetGroupListingGroupFilterCreateOperationFactory(
            customerId,
            assetGroupId,
            TEMPORARY_ID_LISTING_GROUP_ROOT
        );

    MutateGoogleAdsRequest request = new MutateGoogleAdsRequest
    {
        CustomerId = customerId.ToString()
    };

    if (replaceExistingTree)
    {
        List<AssetGroupListingGroupFilter> existingListingGroupFilters =
            GetAllExistingListingGroupFilterAssetsInAssetGroup(
                client,
                customerId,
                assetGroupResourceName
            );

        if (existingListingGroupFilters.Count > 0)
        {
            // A special factory object that ensures the creation of remove operations in the
            // correct order (child listing group filters must be removed before their parents).
            AssetGroupListingGroupFilterRemoveOperationFactory removeOperationFactory =
                new AssetGroupListingGroupFilterRemoveOperationFactory(
                    existingListingGroupFilters
                );

            request.MutateOperations.AddRange(removeOperationFactory.RemoveAll());
        }
    }

    request.MutateOperations.Add(createOperationFactory.CreateRoot());

    request.MutateOperations.Add(
        createOperationFactory.CreateUnit(
            TEMPORARY_ID_LISTING_GROUP_ROOT,
            createOperationFactory.NextId(),
            new ListingGroupFilterDimension()
            {
                ProductCondition = new ListingGroupFilterDimension.Types.ProductCondition()
                {
                    Condition = ListingGroupFilterProductCondition.New
                }
            }
        )
    );

    request.MutateOperations.Add(
        createOperationFactory.CreateUnit(
            TEMPORARY_ID_LISTING_GROUP_ROOT,
            createOperationFactory.NextId(),
            new ListingGroupFilterDimension()
            {
                ProductCondition = new ListingGroupFilterDimension.Types.ProductCondition()
                {
                    Condition = ListingGroupFilterProductCondition.Used
                }
            }
        )
    );

    // We save this ID because create child nodes underneath it.
    long subdivisionIdConditionOther = createOperationFactory.NextId();

    request.MutateOperations.Add(
        // We're calling CreateSubdivision because this listing group will have children.
        createOperationFactory.CreateSubdivision(
            TEMPORARY_ID_LISTING_GROUP_ROOT,
            subdivisionIdConditionOther,
            new ListingGroupFilterDimension()
            {
                // All sibling nodes must have the same dimension type. We use an empty
                // ProductCondition to indicate that this is an "Other" partition.
                ProductCondition = new ListingGroupFilterDimension.Types.ProductCondition()
            }
        )
    );

    request.MutateOperations.Add(
        createOperationFactory.CreateUnit(
            subdivisionIdConditionOther,
            createOperationFactory.NextId(),
            new ListingGroupFilterDimension()
            {
                ProductBrand = new ProductBrand()
                {
                    Value = "CoolBrand"
                }
            }
        )
    );

    request.MutateOperations.Add(
        createOperationFactory.CreateUnit(
            subdivisionIdConditionOther,
            createOperationFactory.NextId(),
            new ListingGroupFilterDimension()
            {
                ProductBrand = new ProductBrand()
                {
                    Value = "CheapBrand"
                }
            }
        )
    );

    request.MutateOperations.Add(
        createOperationFactory.CreateUnit(
            subdivisionIdConditionOther,
            createOperationFactory.NextId(),
            new ListingGroupFilterDimension()
            {
                ProductBrand = new ProductBrand()
            }
        )
    );

    MutateGoogleAdsResponse response = googleAdsServiceClient.Mutate(request);

    PrintResponseDetails(request, response);
}

      

2,399필리핀

/**
 * Runs the example.
 *
 * @param GoogleAdsClient $googleAdsClient the Google Ads API client
 * @param int $customerId the customer ID
 * @param int $assetGroupId the asset group ID
 * @param bool $replaceExistingTree true if it should replace the existing listing group
 *     tree on the asset group
 */
public static function runExample(
    GoogleAdsClient $googleAdsClient,
    int $customerId,
    int $assetGroupId,
    bool $replaceExistingTree
) {
    // We create all the mutate operations that manipulate a specific asset group for a specific
    // customer. The operations are used to optionally remove all asset group listing group
    // filters from the tree, and then to construct a new tree of filters. These filters can
    // have a parent-child relationship, and also include a special root that includes all
    // children.
    //
    // When creating these filters, we use temporary IDs to create the hierarchy between
    // the root listing group filter, and the subdivisions and leave nodes beneath that.
    $mutateOperations = [];
    if ($replaceExistingTree === true) {
        $existingListingGroupFilters = self::getAllExistingListingGroupFilterAssetsInAssetGroup(
            $googleAdsClient,
            $customerId,
            ResourceNames::forAssetGroup($customerId, $assetGroupId)
        );
        if (count($existingListingGroupFilters) > 0) {
            $mutateOperations = array_merge(
                $mutateOperations,
                // Ensures the creation of remove operations in the correct order (child listing
                // group filters must be removed before their parents).
                self::createMutateOperationsForRemovingListingGroupFiltersTree(
                    $existingListingGroupFilters
                )
            );
        }
    }

    $mutateOperations[] = self::createMutateOperationForRoot(
        $customerId,
        $assetGroupId,
        self::LISTING_GROUP_ROOT_TEMPORARY_ID
    );

    // The temporary ID to be used for creating subdivisions and units.
    static $tempId = self::LISTING_GROUP_ROOT_TEMPORARY_ID - 1;

    $mutateOperations[] = self::createMutateOperationForUnit(
        $customerId,
        $assetGroupId,
        $tempId--,
        self::LISTING_GROUP_ROOT_TEMPORARY_ID,
        new ListingGroupFilterDimension([
            'product_condition' => new ProductCondition([
                'condition' => ListingGroupFilterProductCondition::PBNEW
            ])
        ])
    );

    $mutateOperations[] = self::createMutateOperationForUnit(
        $customerId,
        $assetGroupId,
        $tempId--,
        self::LISTING_GROUP_ROOT_TEMPORARY_ID,
        new ListingGroupFilterDimension([
            'product_condition' => new ProductCondition([
                'condition' => ListingGroupFilterProductCondition::USED
            ])
        ])
    );

    // We save this ID to create child nodes underneath it.
    $conditionOtherSubdivisionId = $tempId--;

    // We're calling createMutateOperationForSubdivision() because this listing group will
    // have children.
    $mutateOperations[] = self::createMutateOperationForSubdivision(
        $customerId,
        $assetGroupId,
        $conditionOtherSubdivisionId,
        self::LISTING_GROUP_ROOT_TEMPORARY_ID,
        new ListingGroupFilterDimension([
            // All sibling nodes must have the same dimension type. We use an empty
            // ProductCondition to indicate that this is an "Other" partition.
            'product_condition' => new ProductCondition()
        ])
    );

    $mutateOperations[] = self::createMutateOperationForUnit(
        $customerId,
        $assetGroupId,
        $tempId--,
        $conditionOtherSubdivisionId,
        new ListingGroupFilterDimension(
            ['product_brand' => new ProductBrand(['value' => 'CoolBrand'])]
        )
    );

    $mutateOperations[] = self::createMutateOperationForUnit(
        $customerId,
        $assetGroupId,
        $tempId--,
        $conditionOtherSubdivisionId,
        new ListingGroupFilterDimension([
            'product_brand' => new ProductBrand(['value' => 'CheapBrand'])
        ])
    );

    $mutateOperations[] = self::createMutateOperationForUnit(
        $customerId,
        $assetGroupId,
        $tempId--,
        $conditionOtherSubdivisionId,
        // All other product brands.
        new ListingGroupFilterDimension(['product_brand' => new ProductBrand()])
    );

    // Issues a mutate request to create everything and prints its information.
    $googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient();
    $response = $googleAdsServiceClient->mutate(
        MutateGoogleAdsRequest::build($customerId, $mutateOperations)
    );

    self::printResponseDetails($mutateOperations, $response);
}
      

Python

def main(client, customer_id, asset_group_id, replace_existing_tree):
    """The main method that creates all necessary entities for the example.

    Args:
        client: an initialized GoogleAdsClient instance.
        customer_id: a client customer ID.
        asset_group_id: the asset group id for the Performance Max campaign.
        replace_existing_tree: option to remove existing product tree from the
            passed in asset group.
    """
    googleads_service = client.get_service("GoogleAdsService")
    asset_group_resource_name = googleads_service.asset_group_path(
        customer_id, asset_group_id
    )
    operations = []

    if replace_existing_tree:
        # Retrieve a list of existing AssetGroupListingGroupFilters
        existing_listing_group_filters = (
            get_all_existing_listing_group_filter_assets_in_asset_group(
                client, customer_id, asset_group_resource_name
            )
        )

        # If present, create MutateOperations to remove each
        # AssetGroupListingGroupFilter and add them to the list of operations.
        if existing_listing_group_filters:
            remove_operation_factory = (
                AssetGroupListingGroupFilterRemoveOperationFactory(
                    client, existing_listing_group_filters
                )
            )
            operations.extend(remove_operation_factory.remove_all())

    create_operation_factory = (
        AssetGroupListingGroupFilterCreateOperationFactory(
            client,
            customer_id,
            asset_group_id,
            _TEMPORARY_ID_LISTING_GROUP_ROOT,
        )
    )

    operations.append(create_operation_factory.create_root())

    new_dimension = client.get_type("ListingGroupFilterDimension")
    new_dimension.product_condition.condition = (
        client.enums.ListingGroupFilterProductConditionEnum.NEW
    )
    operations.append(
        create_operation_factory.create_unit(
            _TEMPORARY_ID_LISTING_GROUP_ROOT,
            create_operation_factory.next_id(),
            new_dimension,
        )
    )

    used_dimension = client.get_type("ListingGroupFilterDimension")
    used_dimension.product_condition.condition = (
        client.enums.ListingGroupFilterProductConditionEnum.USED
    )
    operations.append(
        create_operation_factory.create_unit(
            _TEMPORARY_ID_LISTING_GROUP_ROOT,
            create_operation_factory.next_id(),
            used_dimension,
        )
    )

    # We save this ID because create child nodes underneath it.
    subdivision_id_condition_other = create_operation_factory.next_id()

    # All sibling nodes must have the same dimension type. We use an empty
    # product_condition to indicate that this is an "Other" partition.
    other_dimension = client.get_type("ListingGroupFilterDimension")
    # This triggers the presence of the product_condition field without
    # specifying any field values. This is important in order to tell the API
    # that this is an "other" node.
    other_dimension.product_condition._pb.SetInParent()
    # We're calling create_subdivision because this listing group will have
    # children.
    operations.append(
        create_operation_factory.create_subdivision(
            _TEMPORARY_ID_LISTING_GROUP_ROOT,
            subdivision_id_condition_other,
            other_dimension,
        )
    )

    cool_dimension = client.get_type("ListingGroupFilterDimension")
    cool_dimension.product_brand.value = "CoolBrand"
    operations.append(
        create_operation_factory.create_unit(
            subdivision_id_condition_other,
            create_operation_factory.next_id(),
            cool_dimension,
        )
    )

    cheap_dimension = client.get_type("ListingGroupFilterDimension")
    cheap_dimension.product_brand.value = "CheapBrand"
    operations.append(
        create_operation_factory.create_unit(
            subdivision_id_condition_other,
            create_operation_factory.next_id(),
            cheap_dimension,
        )
    )

    empty_dimension = client.get_type("ListingGroupFilterDimension")
    # This triggers the presence of the product_brand field without specifying
    # any field values. This is important in order to tell the API
    # that this is an "other" node.
    empty_dimension.product_brand._pb.SetInParent()
    operations.append(
        create_operation_factory.create_unit(
            subdivision_id_condition_other,
            create_operation_factory.next_id(),
            empty_dimension,
        )
    )

    response = googleads_service.mutate(
        customer_id=customer_id, mutate_operations=operations
    )

    print_response_details(operations, response)
      

Ruby

def add_performance_max_product_listing_group_tree(
    customer_id,
    asset_group_id,
    replace_existing_tree)
  # GoogleAdsClient will read a config file from
  # ENV['HOME']/google_ads_config.rb when called without parameters
  client = Google::Ads::GoogleAds::GoogleAdsClient.new

  asset_group_resource_name = client.path.asset_group(
    customer_id,
    asset_group_id,
  )

  # We use a factory to create all the MutateOperations that manipulate a
  # specific AssetGroup for a specific customer. The operations returned by the
  # factory's methods are used to optionally remove all
  # AssetGroupListingGroupFilters from the tree, and then to construct a new
  # tree of filters. These filters can have a parent-child relationship, and
  # also include a special root that includes all children.
  #
  # When creating these filters, we use temporary IDs to create the hierarchy
  # between the root listing group filter, and the subdivisions and leave nodes
  # beneath that.
  #
  # The factory specific to a customerId and assetGroupId is created below.
  create_operation_factory = AssetGroupListingGroupFilterCreateOperationFactory.new(
    customer_id,
    asset_group_id,
    TEMPORARY_ID_LISTING_GROUP_ROOT,
  )

  operations = []

  if replace_existing_tree
    existing_listing_group_filters = get_existing_listing_group_filters_in_asset_group(
      client,
      customer_id,
      asset_group_resource_name,
    )

    if existing_listing_group_filters.length > 0
      # A special factory object that ensures the creation of remove operations
      # in the correct order (child listing group filters must be removed
      # before their parents).
      remove_operation_factory = AssetGroupListingGroupFilterRemoveOperationFactory.new(
        existing_listing_group_filters
      )

      operations += remove_operation_factory.remove_all(client)
    end
  end

  operations << create_operation_factory.create_root(client)

  operations << create_operation_factory.create_unit(
    client,
    TEMPORARY_ID_LISTING_GROUP_ROOT,
    create_operation_factory.next_id,
    client.resource.listing_group_filter_dimension do |dimension|
      dimension.product_condition = client.resource.product_condition do |condition|
        condition.condition = :NEW
      end
    end,
  )
  operations << create_operation_factory.create_unit(
    client,
    TEMPORARY_ID_LISTING_GROUP_ROOT,
    create_operation_factory.next_id,
    client.resource.listing_group_filter_dimension do |dimension|
      dimension.product_condition = client.resource.product_condition do |condition|
        condition.condition = :USED
      end
    end,
  )

  # We save this ID because we create child nodes underneath it.
  subdivision_id_condition_other = create_operation_factory.next_id

  operations << create_operation_factory.create_subdivision(
    client,
    TEMPORARY_ID_LISTING_GROUP_ROOT,
    subdivision_id_condition_other,
    client.resource.listing_group_filter_dimension do |dimension|
      dimension.product_condition = client.resource.product_condition do |condition|
        # All sibling nodes must have the same dimension type. We use an empty
        # ProductCondition to indicate that this is an "Other" partition.
      end
    end,
  )

  operations << create_operation_factory.create_unit(
    client,
    subdivision_id_condition_other,
    create_operation_factory.next_id,
    client.resource.listing_group_filter_dimension do |dimension|
      dimension.product_brand = client.resource.product_brand do |brand|
        brand.value = 'CoolBrand'
      end
    end,
  )
  operations << create_operation_factory.create_unit(
    client,
    subdivision_id_condition_other,
    create_operation_factory.next_id,
    client.resource.listing_group_filter_dimension do |dimension|
      dimension.product_brand = client.resource.product_brand do |brand|
        brand.value = 'CheapBrand'
      end
    end,
  )
  operations << create_operation_factory.create_unit(
    client,
    subdivision_id_condition_other,
    create_operation_factory.next_id,
    client.resource.listing_group_filter_dimension do |dimension|
      dimension.product_brand = client.resource.product_brand do |brand|
      end
    end,
  )

  response = client.service.google_ads.mutate(
    customer_id: customer_id,
    mutate_operations: operations,
  )

  print_response_details(operations, response)
end
      

Perl

sub add_performance_max_product_listing_group_tree {
  my ($api_client, $customer_id, $asset_group_id, $replace_existing_tree) = @_;

  # We create all the mutate operations that manipulate a specific asset group for
  # a specific customer. The operations are used to optionally remove all asset
  # group listing group filters from the tree, and then to construct a new tree
  # of filters. These filters can have a parent-child relationship, and also include
  # a special root that includes all children.
  #
  # When creating these filters, we use temporary IDs to create the hierarchy between
  # the root listing group filter, and the subdivisions and leave nodes beneath that.
  my $mutate_operations = [];
  if (defined $replace_existing_tree) {
    my $existing_listing_group_filters =
      get_all_existing_listing_group_filter_assets_in_asset_group(
      $api_client,
      $customer_id,
      Google::Ads::GoogleAds::V16::Utils::ResourceNames::asset_group(
        $customer_id, $asset_group_id
      ));

    if (scalar @$existing_listing_group_filters > 0) {
      push @$mutate_operations,
        # Ensure the creation of remove operations in the correct order (child
        # listing group filters must be removed before their parents).
        @{
        create_mutate_operations_for_removing_listing_group_filters_tree(
          $existing_listing_group_filters)};
    }
  }

  push @$mutate_operations,
    create_mutate_operation_for_root($customer_id, $asset_group_id,
    LISTING_GROUP_ROOT_TEMPORARY_ID);

  # The temporary ID to be used for creating subdivisions and units.
  my $temp_id = LISTING_GROUP_ROOT_TEMPORARY_ID - 1;

  push @$mutate_operations,
    create_mutate_operation_for_unit(
    $customer_id,
    $asset_group_id,
    $temp_id--,
    LISTING_GROUP_ROOT_TEMPORARY_ID,
    Google::Ads::GoogleAds::V16::Resources::ListingGroupFilterDimension->new({
        productCondition =>
          Google::Ads::GoogleAds::V16::Resources::ProductCondition->new({
            condition => NEW
          })}));

  push @$mutate_operations,
    create_mutate_operation_for_unit(
    $customer_id,
    $asset_group_id,
    $temp_id--,
    LISTING_GROUP_ROOT_TEMPORARY_ID,
    Google::Ads::GoogleAds::V16::Resources::ListingGroupFilterDimension->new({
        productCondition =>
          Google::Ads::GoogleAds::V16::Resources::ProductCondition->new({
            condition => USED
          })}));

  # We save this ID to create child nodes underneath it.
  my $condition_other_subdivision_id = $temp_id--;

  # We're calling create_mutate_operation_for_subdivision() because this listing
  # group will have children.
  push @$mutate_operations, create_mutate_operation_for_subdivision(
    $customer_id,
    $asset_group_id,
    $condition_other_subdivision_id,
    LISTING_GROUP_ROOT_TEMPORARY_ID,
    Google::Ads::GoogleAds::V16::Resources::ListingGroupFilterDimension->new({
        # All sibling nodes must have the same dimension type. We use an empty
        # ProductCondition to indicate that this is an "Other" partition.
        productCondition =>
          Google::Ads::GoogleAds::V16::Resources::ProductCondition->new({})}));

  push @$mutate_operations,
    create_mutate_operation_for_unit(
    $customer_id,
    $asset_group_id,
    $temp_id--,
    $condition_other_subdivision_id,
    Google::Ads::GoogleAds::V16::Resources::ListingGroupFilterDimension->new({
        productBrand =>
          Google::Ads::GoogleAds::V16::Resources::ProductBrand->new({
            value => "CoolBrand"
          })}));

  push @$mutate_operations,
    create_mutate_operation_for_unit(
    $customer_id,
    $asset_group_id,
    $temp_id--,
    $condition_other_subdivision_id,
    Google::Ads::GoogleAds::V16::Resources::ListingGroupFilterDimension->new({
        productBrand =>
          Google::Ads::GoogleAds::V16::Resources::ProductBrand->new({
            value => "CheapBrand"
          })}));

  push @$mutate_operations, create_mutate_operation_for_unit(
    $customer_id,
    $asset_group_id,
    $temp_id--,
    $condition_other_subdivision_id,
    # All other product brands.
    Google::Ads::GoogleAds::V16::Resources::ListingGroupFilterDimension->new({
        productBrand =>
          Google::Ads::GoogleAds::V16::Resources::ProductBrand->new({})}));

  # Issue a mutate request to create everything and print its information.
  my $response = $api_client->GoogleAdsService()->mutate({
    customerId       => $customer_id,
    mutateOperations => $mutate_operations
  });

  print_response_details($mutate_operations, $response);

  return 1;
}
      

ListingDimensionInfo에 사용할 수 있는 측정기준

실적 최대화 등록정보 그룹에 포함될 수 있는 여러 등록정보 측정기준이 있습니다. 실적 최대화 소매업체 캠페인에는 다음 ListingDimensionInfo 유형을 사용할 수 있습니다.

ListingDimensionInfo 유형의 빈 객체를 ListingGroupInfo에 전달하여 기타 단위 노드를 만들 수 있습니다.

임시 ID

애셋 그룹 기준을 생성하는 변경 요청이 서버에서 처리될 때까지는 애셋 그룹 기준에 ID가 할당되지 않습니다. 그러나 ListingGroupInfo는 완료될 때까지 유효하지 않으므로 하위 부문을 만들 때마다 동일한 요청에서 하나 이상의 하위 노드와 Other 노드도 만들어야 합니다.

상위 요소와 동일한 요청에서 생성된 하위 노드에 ListingGroupInfoparent_criterion_id를 설정하려면 임시 기준 ID를 사용하면 됩니다. 이러한 ID는 단일 변경 요청의 컨텍스트 내에서만 적용됩니다. 모든 음의 정수를 임시 ID로 사용할 수 있습니다.