AnalyticsReporting V4: Can I combine a DynamicSegment and a segmentId as logical AND? - google-analytics-api

I'm trying to migrate a few queries from Core Reporting V3 to V4 (AnalyticsReporting V4 in PHP to be specific). In one case I'd like to combine a custom segment with one of the "predefined" segments.
Expected result:
I receive a response where BOTH segments are applied to the response (logical AND)
Actual result:
I receive a response where each row is listed individually for each segment.
My question
How do I apply BOTH segments to receive ONE row per result? In this case - get all users that came via Tablet or Desktop and have had more than three sessions.
In V3 I did this by combining multiple user::condition:somethingSomething.
I guess one way would be to first get the segment definition of the predefined segment that I need, and then use it to build a SegmentDimensionFilter - but it would be nice to avoid that.
Here is my (test) query, with segmentId: 'gaid::-15' being "Tablet and Desktop Traffic". In my real query I'm using a SequenceSegment, but the response is the same here:
+"dateRanges": array:1 [▼
0 => {#542 ▼
+"endDate": "2016-05-18"
+"startDate": "2016-04-18"
}
]
+"dimensions": array:1 [▼
0 => {#545 ▼
+"name": "ga:segment"
}
]
+"metrics": array:1 [▼
0 => {#546 ▼
+"expression": "ga:users"
}
]
+"segments": array:2 [▼
0 => {#548 ▼
+"dynamicSegment": {#549 ▼
+"name": "AK: Loyal Visitors"
+"userSegment": {#553 ▼
+"segmentFilters": array:1 [▼
0 => {#556 ▼
+"simpleSegment": {#560 ▼
+"orFiltersForSegment": {#563 ▼
+"segmentFilterClauses": array:1 [▼
0 => {#566 ▼
+"dimensionFilter": {#570 ▼
+"dimensionName": "ga:sessionCount"
+"expressions": "3"
+"operator": "NUMERIC_GREATER_THAN"
}
}
]
}
}
}
]
}
}
}
1 => {#543 ▼
+"segmentId": "gaid::-15"
}
]
+"orderBys": array:1 [▼
0 => {#547 ▼
+"fieldName": "ga:users"
+"sortOrder": "DESCENDING"
}
]
And here is the response, notice how each segment is listed individually as its own dimension:
"columnHeader" => array:2 [▼
"dimensions" => array:1 [▼
0 => "ga:segment"
]
"metricHeader" => array:1 [▼
"metricHeaderEntries" => array:1 [▼
0 => array:2 [▼
"name" => "ga:users"
"type" => "INTEGER"
]
]
]
]
"data" => array:6 [▼
"rows" => array:2 [▼
0 => array:2 [▼
"dimensions" => array:1 [▼
0 => "Tablet and Desktop Traffic"
]
"metrics" => array:1 [▼
0 => array:1 [▼
"values" => array:1 [▼
0 => "74309"
]
]
]
]
1 => array:2 [▼
"dimensions" => array:1 [▼
0 => "AK: Loyal Visitors"
]
"metrics" => array:1 [▼
0 => array:1 [▼
"values" => array:1 [▼
0 => "10740"
]
]
]
]
]
"totals" => array:1 [▼
0 => array:1 [▼
"values" => array:1 [▼
0 => "85049"
]
]
]
"rowCount" => 2
Would appreciate any help on this! Please let me know if I should clarify something.

Multiple Segments
As your query results prove an Analytics Reporting API V4 ReportRequest can have multiple segments, and each segment shows up in the ga:segment dimension in the results.
Logical AND segment filters
To answer your question No you cannot OR/AND together a segment id with your own clauses, because a given segment Id can be composed up of several individual filter clauses.
In fact the segment Id you requested has two segmentFilterClauses:
gaid::-5 == sessions::condition::ga:deviceCategory==tablet,ga:deviceCategory==desktop
But all is not lost
As you surmised you will need to create your own set of segment Filters:
{
"reportRequests":
[
{
"viewId": "XXXX",
"dimensions":
[
{
"name": "ga:segment"
}
],
"metrics":
[
{
"expression": "ga:users"
}
],
"segments":
[
{
"dynamicSegment":
{
"userSegment":
{
"segmentFilters":
[
{
"simpleSegment":
{
"orFiltersForSegment":
[
{
"segmentFilterClauses":
[
{
"dimensionFilter":
{
"dimensionName": "ga:sessionCount",
"operator": "NUMERIC_GREATER_THAN",
"expressions":
["3"
]
}
}
]
}
]
}
},
{
"simpleSegment":
{
"orFiltersForSegment":
[
{
"segmentFilterClauses":
[
{
"dimensionFilter":
{
"dimensionName": "ga:deviceCategory",
"expressions":
["tablet","desktop"
],
"operator": "IN_LIST"
}
}
]
}
]
}
}
]
},
"name": "AK: Loyal mobile users"
}
}
]
}
]
}
Checkout the above example in the API Explorer
Segment Id is backwards compatible
On top of being able to logically AND or OR segment Filters, the Analytics Reporting API V4 is backwards compatible with the V3 segment syntax:
{
"reportRequests":
[
{
"viewId": "XXXX",
"dimensions":
[
{
"name": "ga:segment"
}
],
"metrics":
[
{
"expression": "ga:users"
}
],
"segments":
[
{
"segmentId": "users::condition::ga:deviceCategory==tablet,ga:deviceCategory==desktop,ga:sessionCount>3"
}
]
}
]
}

I think there is error in the line
"users::condition::ga:deviceCategory==tablet,ga:deviceCategory==desktop,ga:sessionCount>3"
Instead ",", we must write ";"
"users::condition::ga:deviceCategory==tablet,ga:deviceCategory==desktop;ga:sessionCount>3"
^

Related

mongodb aggregation match date

I have data like
{
"_id" : ObjectId("5b63e593f033ab66fa25a142"),
"percent_change_1h" : 0.37,
"percent_change_24h" : -3.91,
"percent_change_7d" : -7.08,
"last_updated" : 1533273443,
"created_at" : "2018-08-03 05:18:11",
"updated_at" : "2018-08-03 05:18:11"
}
its have created_at date like this "2018-08-03 05:18:11"
but i can pass date in aggregation function like "2018-08-03"
data not get in this match
I can not use $gte or $lte becouse get only given date data
query is here
$date = "2018-08-15";
$filters = ['$match'=>[
'quotes'=>$quotes,
'created_at' => $date]
];
$join = ['$lookup'=>[
'from' => "cryptocurrencies_list",
'localField'=> "crypto_list_id",
'foreignField'=> "_id",
'as'=>"listdata"]
];
$limits = ['$limit'=>10];
$query = $detailscollection->aggregate([$filters,$join,$limits]);
You can try below aggregation
$detailscollection->aggregate([
[
'$addFields' => [
'date' => [
'$dateToString' => [
'date' => [
'$dateFromString' => [
'dateString' => '$created_at',
'timezone' => 'America/New_York'
]
],
'format' => '%Y-%m-%d'
]
]
]
],
[
'$match' => [
'date' => $date, 'quotes' => $quotes
]
]
])

MongoDB whereIn cannot be used with other queries in Laravel

I am working on laravel 5.2, MongoDb (jenssegers/laravel-mongodb).
I have this code:
$query = $query->where('av_time_from', '<', $request->get('available_time'))->where('av_time_to', '>', $request->get('available_time'))->whereIn('location',$request->get('locations'))->get();
I run this query and dump out the query before paginated(dump($query);).
But that query consists of whereIn:
wheres: array:1 [
0 => array:4 [
"type" => "In"
"column" => "location"
"values" => array:2 [
0 => "58087de0d5ae4108ac40c412"
1 => "5809d754d5ae4108ac40c419"
]
"boolean" => "and"
]
]
Please help me solve this problem.

Product with tags with pivot how can i access relationship

The following $product returns Product object.
But how can i access the relations:array "tags" by foreach?
When i do $tags->tags i get the tags of the product table.
Foreach:
foreach ($product as $tags) {
}
Instance:
$product = Product::with('tags')->where('id',$id)->get();
Output:
Product {#371 ▼
#table: "products"
#connection: null
#primaryKey: "id"
#keyType: "int"
#perPage: 15
+incrementing: true
+timestamps: true
#attributes: array:10 [▶]
#original: array:10 [▶]
#relations: array:1 [▼
"tags" => Collection {#399 ▼
#items: array:2 [▼
0 => Tag {#397 ▼
#connection: null
#table: null
#primaryKey: "id"
#keyType: "int"
#perPage: 15
+incrementing: true
+timestamps: true
#attributes: array:4 [▶]
#original: array:6 [▶]
#relations: array:1 [▶]
#hidden: []
#visible: []
#appends: []
#fillable: []
#guarded: array:1 [▶]
#dates: []
#dateFormat: null
#casts: []
#touches: []
#observables: []
#with: []
#morphClass: null
+exists: true
+wasRecentlyCreated: false
}
Use first instead of get to get a model instance instead of collection.
$product = Product::with('tags')->where('id', $id)->first();
Then you can loop through each tag.
foreach ($product->tags as $tag) {
// do something
}

How to apply correctly $limit and $skip in subfields?

I'm starting with mongodb and I'm finding many difficulties with the following scheme.
{
"_id" : "AAA",
"events" : [
{
"event" : "001",
"time" : 1456823333
},
{
"event" : "002",
"time" : 1456828888
},
{
"event" : "003",
"time" : 1456825555
},...
]
}
I want to get the events sorted by date and apply limit and skip.
I'm using the following query:
$op = array(
array('$match' => array('_id' => $userId)),
array('$unwind' => '$events'),
array('$sort' => array('events.time' => -1)),
array('$group' => array('_id' => '$_id',
'events' => array('$push' => '$events')))
//,array('$project' => array('_id' => 1, 'events' => array('$events', 0, 3)))
//,array('$limit' => 4)
//,array('$skip' => 3)
);
$result= Mongo->aggregate('mycollection', $op);
I have tried everything to filter $project or $limit and $skip but none of it works.
How should I apply the limit and skyp conditions in events?
If I do not apply the conditions of "limit" above the result is ordered correctly.
Result:
{ "waitedMS":0,
"result":[
{
"_id":"AAA",
"events":[
{
"event":"002",
"time":1456828888,
},
{
"event":"003",
"time":1456825555,
},
{
"event":"001",
"time":1456823333,
},...
}
],
"ok":1
}
Order correctly but I can not limit the number of results for paging.

Facebook pictures of comments, comment

I need to get the picture of the replies to comments i've used this so far to get the pictures of the first level comments it looks like this.
$reso = $this->getFB()->get("$id/comments?fields=likes,message,comments,from{
likes,comments,name,picture
}", $pageToken);
This returns the picture with no problems but only for the first level of comments i have no idea how to get the picture for the replies to a comment?
Current Array Returned
array:2 [▼
"data" => array:13 [▼
0 => array:4 [▼
"message" => "OOh nice!"
"from" => array:4 [▼
"likes" => array:2 [▶]
"name" => "McKenzie Flavius"
"picture" => array:1 [▶]
"id" => "186894038315206"
]
"id" => "1687724354827858_1687724421494518"
"comments" => array:2 [▼
"data" => array:1 [▼
0 => array:2 [▼
"message" => "replied ooh nice"
"id" => "1687724354827858_1687769078156719" //I need to get picture in this array here!
]
]
"paging" => array:1 [▶]
]
]
1 => array:4 [▶]
2 => array:4 [▶]
3 => array:4 [▶]
4 => array:4 [▶]
5 => array:3 [▶]
6 => array:4 [▶]
7 => array:4 [▶]
8 => array:4 [▶]
9 => array:4 [▶]
10 => array:4 [▶]
11 => array:4 [▶]
12 => array:4 [▶]
]
"paging" => array:1 [▶]
]
As always all help appreciated
I figured it out, so when passing the following argument as part of the url to facebook.
COMMENT-ID/comments?fields=likes,message,comments,$accessToken;
I needed to use this {'Sub-Field Info Here'} with the argument to get the subfields that i want, so to get the pictures from the comments i did the following:
COMMENT-ID/comments?fields=likes,message,comments{from{picture,name}}, $accessToken;
Notice I put the {from{picture,name}} immediately besides the comments argument that has been passed this means that the data pulled back will be related to the comments field. So ultimately here i have retrieved the 'picture' and the 'name' From the comments giving me something like the following:
"comments" => "from"[
"picture" => "PICTURE-LINK",
"name" => "NAME"
]