Google Ads API迁移技术问题:generateHistoricalMetrics的getMetrics返回结果数量与传入关键词不符及关键词匹配难题
Let's break down your questions with practical, actionable insights based on working with the Google Ads PHP SDK:
Why does getMetrics() return fewer results than the number of keywords passed?
From your test data (higher loss rate with larger batches) and typical Google Ads API behavior, these are the most likely culprits:
- Silently rejected keywords: Even after filtering for
KEYWORD_HAS_INVALID_CHARSandKEYWORD_TEXT_TOO_LONG, some keywords get quietly dropped by the API. This includes policy-violating terms (sensitive, infringing content), nonsensical strings, or terms the system can't semantically parse. These won't trigger an error—they just won't appear in results. - Implicit batch limits: While the docs don't explicitly state it, large batches (like 10k keywords) can hit internal API thresholds. Overloaded requests may have partial entries discarded without warning, which aligns with your observation that smaller batches have lower loss rates.
- Duplicate keywords: If your input list has identical terms with the same
EXACTmatch type, the API automatically deduplicates them and returns only one set of metrics per unique keyword, reducing the result count.
How to identify missing keywords?
Since results are returned in the exact order of your input (per protobuf rules), even without keyword IDs in the response, you can map and track missing entries with these steps:
Keep an ordered, annotated input list
Before sending the request, store your keywords with unique identifiers (like your client's internal keyword ID or just the raw text) to reference later:$inputKeywords = [ ['text' => 'best running shoes', 'match_type' => KeywordMatchType::EXACT, 'client_key_id' => 'ck_1001'], ['text' => 'wireless headphones', 'match_type' => KeywordMatchType::EXACT, 'client_key_id' => 'ck_1002'], // ... more keywords ];Map results to input by index
Use the consistent order to match results back to your input list, then flag entries that have no corresponding result:$apiResults = $response->getMetrics(); $matched = []; $missing = []; foreach ($inputKeywords as $index => $keyData) { if (isset($apiResults[$index])) { $matched[] = [ 'client_id' => $keyData['client_key_id'], 'keyword' => $keyData['text'], 'metrics' => $apiResults[$index] ]; } else { $missing[] = $keyData; } }Pro tip: Dedup your input list first (by text + match type) to avoid marking duplicates as "missing" when the API collapses them into one result.
Validate order with marker keywords
To confirm the order consistency is reliable, add a few unique "marker" keywords (e.g.,my_test_marker_9876) to each batch. These are terms you know will return valid metrics. After the request, check that their position in the results matches their position in the input—this ensures your index-based mapping is accurate.
Additional Practical Tips
- Optimize batch size: Based on your tests, stick to batches of 200-500 keywords. It balances efficiency and low loss rates, without having to query each keyword individually.
- Pre-filter aggressively: Beyond the official error codes, add checks for obvious red flags (all-numeric strings, overly jumbled characters, known policy-violating terms) to reduce the number of silently rejected keywords.
- Analyze missing terms: Collect and review the missing keywords to spot patterns (e.g., common phrases, special characters) and refine your pre-processing rules over time.
内容的提问来源于stack exchange,提问作者Evgeniy

