I am using Google.Apis.AnalyticsReporting.v4 to download a view between two days. I would like to know where in my response can I see whether the data contains sampled data?
This is the code for my request and we catch the data in response object below:
using (var analytics = new AnalyticsReportingService(new BaseClientService.Initializer { HttpClientInitializer = credential }))
{
while (nextPageToken != null)
{
var reportRequest = new ReportRequest
{
ViewId = "123456",
DateRanges = new[] { new DateRange { StartDate = "2021-06-01", EndDate = "2021-11-30" } },
Dimensions = new List<Dimension>() {
new Dimension { Name = "ga:transactionId" },
new Dimension { Name = "ga:campaign" },
new Dimension { Name = "ga:sourceMedium" }
},
Metrics = new[] { new Metric { Expression = "ga:users" }, new Metric { Expression = "ga:sessions" } },
};
var requests = new List<ReportRequest>();
requests.Add(reportRequest);
// Create the GetReportsRequest object.
var getReport = new GetReportsRequest() { ReportRequests = requests };
// Call the batchGet method.
var response = analytics.Reports.BatchGet(getReport).Execute();
}
}
It does not sample the data requested through Google.Apis.AnalyticsReporting.v4. However, if your query is too complex, it will return a 5xx error. Looks like it prevents its backend from executing queries for too long to avoid high loads. In that case, you'd need to chop your request into a few.
Related
I'm using .NET 5 and the nuget package Google.Analytics.Data.V1Beta to query Google Analytics. But I need to query events using the event_category and the event_label and I get this error: "Field customEvent:event_category is not a valid dimension". This is my code:
var click = new FilterExpression
{
Filter = new Filter
{
FieldName = "ga:event_category",
StringFilter = new Filter.Types.StringFilter
{
CaseSensitive = false,
MatchType = Filter.Types.StringFilter.Types.MatchType.Exact,
Value = "click"
}
},
};
var request = new RunReportRequest
{
Property = $"properties/{_settings.GoogleAnalytics.PropertyId}",
Dimensions = {new Dimension {Name = "eventName"}, new Dimension {Name = "customEvent:event_category" } },
DimensionFilter = click,
Metrics = {new Metric {Name = "eventCount"}},
DateRanges =
{
new DateRange
{StartDate = startDate.ToString("yyyy-MM-dd"), EndDate = endDate.ToString("yyyy-MM-dd")}
}
};
var response = await _analyticsClient.GetClient().RunReportAsync(request);
How do I pass event_category and event_label to the query?
I am using Google.Apis.AnalyticsReporting.v4 library for old google analytics views. How do I convert this code to GA4? I can't find a line about switching View Id to something else in code.
I have checked this post "How do I get view id in GA4", but my properties already exist and I don't see option to modify them after creation.
using (var svc = new AnalyticsReportingService(authInitializer.CreateInitializer()))
{
var dateRange = new DateRange
{
StartDate = analyticsParams.From.ToString("yyyy-MM-dd"),
EndDate = analyticsParams.To.ToString("yyyy-MM-dd")
};
var sessions = new Metric
{
Expression = "ga:sessions",
Alias = "Sessions"
};
var date = new Dimension { Name = "ga:date" };
var reportRequest = new ReportRequest
{
DateRanges = new List<DateRange> { dateRange },
Dimensions = new List<Dimension> { date },
Metrics = new List<Metric> { sessions },
ViewId = analyticsParams.ViewId, // <------------------------- My view id
};
var getReportsRequest = new GetReportsRequest
{
ReportRequests = new List<ReportRequest> { reportRequest }
};
var batchRequest = svc.Reports.BatchGet(getReportsRequest);
var response = batchRequest.Execute();
var reports = response.Reports.First();
return reports.Data.Rows.Select(x => new DataEntry()
{
Date = DateTime.ParseExact(x.Dimensions[0], "yyyyMMdd", CultureInfo.InvariantCulture),
Value = int.Parse(x.Metrics[0].Values[0]),
}).ToList();
}
You need to use the Google Analytics Data API V1 (currently in alpha) in order to access your GA4 properties. Here is a quick start sample for .NET which seems similar to what you are trying to do.
using Google.Analytics.Data.V1Alpha;
using System;
namespace AnalyticsSamples
{
class QuickStart
{
static void SampleRunReport(string propertyId)
{
// Using a default constructor instructs the client to use the credentials
// specified in GOOGLE_APPLICATION_CREDENTIALS environment variable.
AlphaAnalyticsDataClient client = AlphaAnalyticsDataClient.Create();
// Initialize request argument(s)
RunReportRequest request = new RunReportRequest
{
Entity = new Entity{ PropertyId = propertyId },
Dimensions = { new Dimension{ Name="city"}, },
Metrics = { new Metric{ Name="activeUsers"}, },
DateRanges = { new DateRange{ StartDate="2020-03-31", EndDate="today"}, },
};
// Make the request
RunReportResponse response = client.RunReport(request);
Console.WriteLine("Report result:");
foreach( Row row in response.Rows )
{
Console.WriteLine("{0}, {1}", row.DimensionValues[0].Value, row.MetricValues[0].Value);
}
}
static int Main(string[] args)
{
if (args.Length == 0 || args.Length > 2)
{
Console.WriteLine("Arguments: <GA4 property ID>");
Console.WriteLine("A GA4 property id parameter is required to make a query to the Google Analytics Data API.");
return 1;
}
string propertyId = args[0];
SampleRunReport(propertyId);
return 0;
}
}
}
Currently there aren't API available for GA4 Property. Furthermore GA4 does not provide Views, you have to use BigQuery to get data programmatically.
Report
I have read this thread: Google Analytics API: Why is the API data different than what's being seen on the Analytics Dashboard? But still cannot figure out why my results differ so much from my Analytics Dashboard.
How can I check in .Net if my response contains sampleData? Here is the code I am using:
string[] s = new string[]{"https://www.googleapis.com/auth/analytics.readonly"};
var auth = GoogleAnalyticsServiceAccount.AuthenticateServiceAccount("XXXXX", "D:\\Spawtz\\Src\\client_id.json", s);
// Create the DateRange object.
//DateRange lastWeek = new DateRange() { StartDate = "2018-12-02", EndDate = "2018-12-09" };
DateRange lastMonth = new DateRange() { StartDate = "2018-11-09", EndDate = "2018-12-09" };
DateRange lastYear = new DateRange() { StartDate = "2017-12-09", EndDate = "2018-12-09" };
// Create the Metrics object.
Metric pageViews = new Metric { Expression = "ga:pageViews"};
//Create the Dimensions object.
Dimension pagePath = new Dimension { Name = "ga:pagePath" };
// Create the ReportRequest object.
// Create the ReportRequest object.
ReportRequest reportRequest = new ReportRequest
{
ViewId = "XXXXX",
DateRanges = new List<DateRange>() { lastMonth, lastYear},
Dimensions = new List<Dimension>() { pagePath },
Metrics = new List<Metric>() { pageViews },
FiltersExpression = "ga:pagePath==/cricket-player/t20/playerid=2348"
};
List<ReportRequest> requests = new List<ReportRequest>();
requests.Add(reportRequest);
// Create the GetReportsRequest object.
GetReportsRequest getReport = new GetReportsRequest() { ReportRequests = requests };
// Call the batchGet method.
GetReportsResponse response = auth.Reports.BatchGet(getReport).Execute();
Can I set the SamplingLevel and Max-Results in asp.Net?
Yes you can set up the Sampling level for your report. It should be something like this Let me know if it doesnt work i can test it.
ReportRequest reportRequest = new ReportRequest
{
ViewId = "XXXXX",
DateRanges = new List<DateRange>() { lastMonth, lastYear},
Dimensions = new List<Dimension>() { pagePath },
Metrics = new List<Metric>() { pageViews },
isDataGolden
The response data for each report should return a value called isDataGolden if the data is completed processing.
TIP
Remember that your request in the dashboard must be exactly the same as the request you are making to the API if you want the data to be the same. The exact same dimensions, metrics and dates. You cant look at a report in the dashbaord that contains five dimensions and then make a request to the api only looking at pageviews the numbers will not add up.
FiltersExpression = "ga:pagePath==/cricket-player/t20/playerid=2348"
Sampling = "SAMPLINGUNSPECIFIED"
};
Update
According to the picture you posted you are looking at a report with the following dimensions and metrics.
page
pageviews
uniquepageviews
avg time on page
Entrances
bournce rate
% Exit
page value
Your request to the api must make the exact same request which means you need to use the exact same dimensions and metrics.
I'm using the Google Anayltics Reporting API v4 to query page views on my site, ordered by most viewed. I discovered that I'm getting duplicate entries, where the path is the same but the capitalization is different
DateRange dateRange = new DateRange()
{
StartDate = startDate.ToString("yyyy-MM-dd"),
EndDate = DateTime.Now.ToString("yyyy-MM-dd")
};
// Create the Metrics object.
Metric pageviews = new Metric {Expression = "ga:pageviews", Alias = "Pageviews"};
//Create the Dimensions object.
Dimension path = new Dimension { Name = "ga:pagePath" };
OrderBy orderby = new OrderBy {FieldName = "ga:pageviews", SortOrder = "DESCENDING"};
// Create the ReportRequest object.
ReportRequest reportRequest = new ReportRequest
{
ViewId = viewId,
DateRanges = new List<DateRange>() { dateRange },
Dimensions = new List<Dimension>() { path },
Metrics = new List<Metric>() { pageviews },
OrderBys = new List<OrderBy>() { orderby }
};
List<ReportRequest> requests = new List<ReportRequest>();
requests.Add(reportRequest);
// Create the GetReportsRequest object.
GetReportsRequest getReport = new GetReportsRequest() { ReportRequests = requests };
// Call the batchGet method.
GetReportsResponse response = svc.Reports.BatchGet(getReport).Execute();
foreach (var report in response.Reports)
{
var data = report.Data.Rows.Select(x => new AnalyticsPage
{
Path = x.Dimensions[0],
Views = Convert.ToInt32(x.Metrics[0].Values[0])
});
pages.AddRange(data);
}
When I view my results, pages[41] is "/events/tech-knowledge" (3150 page views) and pages[429] is "/Events/Tech-Knowledge" (200 page views)
Is there something I can add to my query to make the API ignore case in the path field? I know I could modify my code to combine entries where the path.ToLower() is the same, but it would be better to get the API to return the data correctly
Checked the Analytics API reference, no such ready made filter. I suggest proceeding with your workaround.
I am trying to retrieve the data from Dynamo DB based on a search criteria using Scan request. I am following the steps mentioned in http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LowLevelDotNetScanning.html" page. My DynamoDB table contains more than 1 million records. I know that by using the do-while loop and ExclusiveStartKey we can fetch the records from dynamo DB. but in my case I can not wait till search process is complete as this will hang my angularJS UI. instead I want to progressively load the data with out waiting for the search process to complete. How we can do that.?
sample request:
var lastEvaluatedKey = new Dictionary<string, AttributeValue>(); ;
AmazonDynamoDBClient amazonDynamoDbClient= new AmazonDynamoDBClient()
var filterExpression = "#aws_s3_bucket = :v_aws_s3_bucket and contains(#aws_s3_key,:v_aws_s3_key)";
var projectExpression = "#aws_s3_key,filename,#region,aws_s3_bucket,#projecttype,folder,#siteid,locationname,createdon,modifiedon";
do
{
var request = new ScanRequest
{
TableName = "Test1",
ExclusiveStartKey=lastEvaluatedKey,
FilterExpression = filterExpression,
ExpressionAttributeNames = new Dictionary<string, string>
{
{ "#region", "region" },
{ "#siteid", "siteid" },
{ "#projecttype", "projecttype" },
{ "#aws_s3_key", "aws_s3_key" },
{ "#aws_s3_bucket", "aws_s3_bucket" }
},
ExpressionAttributeValues = new Dictionary<string, AttributeValue> {
{":v_aws_s3_bucket", new AttributeValue { S = "sampleBucket"}},
{":v_aws_s3_key", new AttributeValue { S = "92226"}}
},
ConsistentRead = true,
ProjectionExpression = projectExpression
};
response = amazonDynamoDbClient.Scan(request);
lastEvaluatedKey = response.LastEvaluatedKey;}while(lastEvaluatedKey!=null && lastEvaluatedKey.count()!=0)
I tried executing the above request with out using do-while loop and saved the ExclusiveStartKey for the next request it throws error the "The provided starting key is invalid: One or more parameter values were invalid: Null attribute value types must have the value of true".
any help on this issue will be helpful...
The error you're getting appears to be because you're setting ExclusiveStartKey on the request without setting any values for its parameters. Notice how you aren't updating request.ExclusiveStartKey after you get your response. Obviously, if you don't do that, the scan won't know where to pick up again when you hit your limit. See below.
AmazonDynamoDBClient amazonDynamoDbClient= new AmazonDynamoDBClient()
var filterExpression = "#aws_s3_bucket = :v_aws_s3_bucket and contains(#aws_s3_key,:v_aws_s3_key)";
var projectExpression = "#aws_s3_key,filename,#region,aws_s3_bucket,#projecttype,folder,#siteid,locationname,createdon,modifiedon";
ScanRequest request = new ScanRequest
{
TableName = "Test1",
FilterExpression = filterExpression,
ExpressionAttributeNames = new Dictionary<string, string>
{
{ "#region", "region" },
{ "#siteid", "siteid" },
{ "#projecttype", "projecttype" },
{ "#aws_s3_key", "aws_s3_key" },
{ "#aws_s3_bucket", "aws_s3_bucket" }
},
ExpressionAttributeValues = new Dictionary<string, AttributeValue> {
{":v_aws_s3_bucket", new AttributeValue { S = "sampleBucket"}},
{":v_aws_s3_key", new AttributeValue { S = "92226"}}
},
ConsistentRead = true,
ProjectionExpression = projectExpression
};
do
{
response = amazonDynamoDbClient.Scan(request);
request.ExclusiveStartKey = response.LastEvaluatedKey;
} while (response.lastEvaluatedKey.Count != 0);