Google’s recent tyrannical announcement to force AdWords advertisers to accept close variants with exact and phrase match has caused many sophisticated advertisers quite a bit of heartburn. For one, I’m concerned that with large and detailed accounts the loss of control can result in a major reduction in efficiency. It’s great (for Google) that the account might generate more clicks, but it’s not necessarily going to have the same intent or sophistication (read: conversion rate) as the traffic my clients intended to bid on. Conversions pay the bills and any loss in that rate can hurt.
After all this is a close variant:
It didn’t help my mood when I read the announcement blog post and noticed that all three cases talked about cheaper clicks and/or higher volume. Zero mentions of improved advertiser ROI or conversion rate.
After calming myself down with some orange slices, I remembered that data settles arguments among rationalists. At the very least we can take a look at how often close variant is triggered in our accounts.
All we have to do is check a single exact match keyword, then run a search query report on it and look at the data. The data tells the story.
But what if we have hundreds or thousands of exact match keywords?
We could spend weeks pulling the data, which is obviously not an option.
We could use some fancy excel trickery on a campaign export.
Or we could write an AdWords script to do a lot of that for us. Thanks in particular to my business partner Nathan who is far better than I am at structured queries. (and programming in general as well)
The script works by using an AdWords Query to pull the data that we care about. Once the data’s been pulled, we manipulate it a bit to output to a Google document. Unfortunately “group by” isn’t part of the AdWords query language, so we’re ordering instead. The output is pushed together in places the keyword matches. It does include terms that get exact match searches even if they aren’t set to broad match. It does not include matches that have gotten zero impressions.
To use the script, create a blank Google doc spreadsheet and paste the link to it in the first variable between the single quotes. It’s best if the doc is named, and the url should include the /edit at the end.
Feel free to add any other metrics to the “columns” part as well. It can also be expanded to include phrase and near_phrase match types by changing the match type variable. Yes it does expect all caps, and yes they actually do call it “near exact”
We’re working on a revision that will include a bit more math and excludes non-exact match types that did “hit” an exact match.
Also a warning. There’s a limit on the number of results that are returned. Particularly large accounts can add additional “where” clauses to output the results by specific campaigns.
/************************************************ * Exact Match Monitor * Version 1.0 * Created By: Nathan Byloff * www.rankhammer.com ************************************************/ function main() { var SPREADSHEET_URL = ''; var DATE_RANGE = 'LAST_7_DAYS'; var MATCH_TYPE = '[EXACT, NEAR_EXACT]'; var columns = ['CampaignName', 'AdGroupName', 'KeywordTextMatchingQuery', 'MatchType', 'Query', 'Impressions', 'Clicks', 'Cost', 'Conversions']; var columnsStr = columns.join(',') + " "; var reportIter = AdWordsApp.report( 'SELECT ' + columnsStr + 'FROM SEARCH_QUERY_PERFORMANCE_REPORT ' + 'WHERE MatchTypeWithVariant IN ' + MATCH_TYPE + ' DURING ' + DATE_RANGE, { includeZeroImpressions: false }).rows(); var data = {}; while(reportIter.hasNext()) { var row = reportIter.next(); if ( !data.hasOwnProperty( row['KeywordTextMatchingQuery'] ) ) { data[ row['KeywordTextMatchingQuery'] ] = []; } data[row['KeywordTextMatchingQuery']].push(row); } var spreadsheet = SpreadsheetApp.openByUrl(SPREADSHEET_URL); var firstSheet = spreadsheet.getSheets()[0]; var rowCnt = 1; var colCnt = 1; for(row in data) { for(i in data[row]) { var newRow = data[row][i]; if (rowCnt == 1) { firstSheet.getRange(rowCnt, 1, 1, columns.length).setValues([columns]); rowCnt++; } colCnt = 1; for(col in columns) { firstSheet.getRange(rowCnt, colCnt, 1, 1).setValue(newRow[columns[col]]); colCnt++; } rowCnt++; } } }
Also available on github here
Feel free to share your experiences with the script as well as improvements we could make to it. We might not be able to change minds by rabble-rousing, but data might tell a more compelling story.
Steve Hammer
Latest posts by Steve Hammer (see all)
- Overcoming AdWords Conversion Data Discrepancies - February 12, 2015
- Near Exact Match Monitoring AdWords Script - August 15, 2014
- Why the Advanced AdWords Certification Exam Made Me Write An AdWords Happy Hour Script - August 4, 2014