OK, I've manage to migrate our application from v13 to v2009. We've
got some serious speed issues in keyword generation with the Bulk
Processing. So I'm wondering if someone could take a look and tell me
if I could construct the Bulk jobs more efficiently. Thanks.
Test Campaign Run
-----------------------
single campaign
15 ad groups
3 ads per adgroup
65 keywords per adgroup
Test Results
----------------------
v13 Run Time = 265.396441936s = 4.41 minutes
v2009 Run Time = 7939.71670389 = 132 minutes!!!
Our application code for v13 keyword function was was pretty much just
wrapping Apility like this:
public function createMultipleKeywords($keywordArray){
$criterionObjects = addKeywordCriterionList($keywordArray);
return $criterionObjects;
}
We'd batch create all keywords from one ad group at a time, which on
average was about 50 keywords at a time. Any keyword failures causing
the group to fail, our system would go back and reprocess that group
one at a time.
Now in converting to v2009, our new keywords function based off the
Google Example code looks like this:
public function createMultipleKeywords($keywordArray, $campaignId){
$result = null;
$operations = array();
$adGroupCriteriaService = $this->adWordsUser-
>GetAdGroupCriterionService('v200909');
$count = 0;
if(!empty($keywordArray)){
foreach($keywordArray as $key=>$keywordRecord){
// Create keyword.
$keyword[$count] = new Keyword();
$keyword[$count]->text = $keywordRecord['text'];
$keyword[$count]->matchType =
$keywordRecord['type'];
// Create ad group bid.
$bids[$count] = new
ManualCPCAdGroupCriterionBids();
$keyMaxCpc = $keywordRecord['maxCpc'] *
self::GOOGLE_MICROS_PER_CURRENCY_UNIT;
$bids[$count]->maxCpc = new Bid(new
Money($keyMaxCpc));
// Create biddable ad group criterion.
$keywordAdGroupCriterion[$count] = new
BiddableAdGroupCriterion();
$keywordAdGroupCriterion[$count]->adGroupId =
(float)
$keywordRecord['belongsToAdGroupId'];
$keywordAdGroupCriterion[$count]->criterion =
new Keyword();
$keywordAdGroupCriterion[$count]->criterion->text =
$keywordRecord['text'];
$keywordAdGroupCriterion[$count]->criterion->matchType =
$keywordRecord['type'];
$keywordAdGroupCriterion[$count]->destinationUrl =
$keywordRecord['destinationUrl'];
$keywordAdGroupCriterion[$count]->bids =
$bids[$count];
// Create operations.
$operations[$count] = new
AdGroupCriterionOperation();
$operations[$count]->operand =
$keywordAdGroupCriterion[$count];
$operations[$count]->operator = 'ADD';
$count++;
}
$bulkMutateJobService = $this->adWordsUser-
>GetBulkMutateJobService();
$scopingEntityId = new EntityId('CAMPAIGN_ID',
$campaignId);
//Start Jobs
$jobId = $this->createAndBeginBulkJob($scopingEntityId,
$operations);
// Monitor and retrieve results from job.
$operationResultsByPart = $this-
>retrieveResultsFromBulkJob($jobId);
//Process results
$results = $this-
>processResultsFromBulkJob($operationResultsByPart,
'AdGroupCriterion');
}
return $results;
}
function createAndBeginBulkJob($scopingEntityId, $operationsByPart)
{
$bulkMutateJobService = $this->adWordsUser-
>GetBulkMutateJobService();
// Initialize the bulk mutate job id.
$jobId = NULL;
// Note: A job may have no more than 100 Request Parts. Each
Part
may have
// no more than 25 operation streams and no more than 10,000
operations
for ($partCounter = 0; $partCounter < count($operationsByPart);
$partCounter++) {
// Create operation stream.
$opStream = new OperationStream();
$opStream->scopingEntityId = $scopingEntityId;
$opStream->operations = $operationsByPart[$partCounter];
// Create bulk mutate request part.
$part = new BulkMutateRequest();
$part->partIndex = $partCounter;
$part->operationStreams = array($opStream);
// Create bulk mutate job.
$job = new BulkMutateJob();
$job->id = $jobId;
$job->numRequestParts = sizeof($operationsByPart);
$job->request = $part;
// Create operation.
$operation = new JobOperation();
$operation->operand = $job;
// If this is our first part, then the job must be
added, not set.
if ($partCounter == 0) {
$operation->operator = 'ADD';
} else {
$operation->operator = 'SET';
}
try{
// Add/set the job. The job will not start
until all parts are
added.
$job =
$bulkMutateJobService->mutate($operation);
$jobId = $job->id;
//echo "Job Id = $jobId\n";
}catch (SoapFault $fault) {
print_r($fault);
//Extract error and place on fault stack
$this->checkFault($fault);
}
// Store job id.
$jobId = $job->id;
}
return $jobId;
}
function retrieveResultsFromBulkJob($jobId) {
$bulkMutateJobService = $this->adWordsUser-
>GetBulkMutateJobService();
$operationResultsByPart = array();
// Create selector.
$selector = new BulkMutateJobSelector();
$selector->jobIds = array($jobId);
// Loop while waiting for the job to complete.
do {
$jobs = $bulkMutateJobService->get($selector);
$job = $jobs[0];
print 'Bulk mutate job with id "' . $job->id . '" has
status "' .
$job->status . "\".\n";
if (($job->status == 'PENDING') || ($job->status ==
'PROCESSING'))
{
sleep(10);
}
} while (($job->status == 'PENDING') || ($job->status ==
'PROCESSING'));
if ($job->status == 'FAILED') {
throw new ApiException(NULL, 'Job failed.');
}
for ($i = 0; $i < $job->numRequestParts; $i++) {
// Set selector to retrieve results for part.
$selector->resultPartIndex = $i;
$jobsWithResult = $bulkMutateJobService->get($selector);
// Get the operation results.
$index = $jobWithResult->result->partIndex;
$operationResultsByPart[$index] = $jobsWithResult[0];
}
return $operationResultsByPart;
}
--
You received this message because you are subscribed to the Google Groups
"AdWords API Forum" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/adwords-api?hl=en.