I want to find the average time a client visit at particular location. My data structure is as follows:
{
"_id": ObjectId("5aea9f9a83b391f80e00a1b1"),
"Client": "ABC",
"Timestamp": "2018-05-03 10:47:42"
},
{
"_id": ObjectId("5aea9f9a83b391f80e00c1a1"),
"Client": "ABC",
"Timestamp": "2018-05-03 11:05:04"
} ,
{
"_id": ObjectId("5aea9f9a83b391f80e00a1e1"),
"Client": "ABC",
"Timestamp": "2018-05-03 13:05:04"
} ,
{
"_id": ObjectId("5aea9f9a83b391f80eaea1e1"),
"Client": "DEF",
"Timestamp": "2018-05-03 11:20:44"
}
I have just tried code so far in codeigniter
$optn = array(
array('$group' => array( '_id' => '$Client', 'date1' => array('$min' => '$Timestamp'), 'date2' => array('$max' => '$Timestamp'), 'avg_time' => array('$avg' => array('$subtract' => array('$date2', '$date1')))))
);
$repeatdata = $this->mongo_db->aggregate("logsdata", $optn);
echo '<pre>'; print_r($repeatdata);
It gives me result as:
Array
(
[waitedMS] => 0
[result] => Array
(
[0] => Array
(
[_id] => ABC
[date1] => 2018-05-03 10:47:42
[date2] => 2018-05-03 13:05:04
[avg_time] =>
)
[1] => Array
(
[_id] => DEF
[date1] => 2018-05-03 11:20:44
[date2] => 2018-05-03 11:20:44
[avg_time] =>
)
)
)
Related
In perl I can push $hashref into #array and have this data for next foreach and possible encode_json (HTTP POST).
I can't figure out how to recreate the same login in golang?
$VAR1 = [
{
'address' => 'test.com',
'id' => 101,
'hostgroups' => [
zero
'one',
'or many'
],
'host_name' => 'test.com',
'alias' => 'test.com',
'template' => 'generic',
'file_id' => 'etc/config'
},
{
'address' => 'test2.com',
'id' => 102,
'hostgroups' => [
zero
'one',
'or many'
],
'host_name' => 'test2.com',
'alias' => 'test2.com',
'template' => 'generic',
'file_id' => 'etc/config'
},
(..)
var array = []map[string]interface{}{
{"address": "test.com", "hostgroups": []string{"zero", "one", "or many"}, "id": 101},
{"address": "test2.com", "hostgroups": []string{"zero", "one", "or many"}, "id": 102},
}
This is the answer.
type host map[string]interface{}
var hosts []host
h := host{
"id": id,
"file_id": "etc/config/hosts.cfg",
"host_name": host_name,
"alias": host_name,
"address": host_name,
"hostgroups": hg,
"template": "generic-host",
}
hosts = append(hosts, h)
I have three collections with following feilds
productTbl
-- productId
-- productName
-- categoryId
-- vendorId
.... so on
categoryTbl
-- categoryId
-- categoryName
VendorTbl
-- VendorID
-- VendorName
I have written below mongodb aggregrate lookup query
$pipeline = array(
array(
'$lookup' => array(
'from' => 'VendorTbl',
'localField' => 'vendorId',
'foreignField' => 'VendorID',
'as' => 'vendordetails'
)
),
array(
'$lookup' => array(
'from' => 'categoryTbl',
'localField' => 'categoryId',
'foreignField' => 'categoryId',
'as' => 'categorydetails'
)
),
);
$output = $this->db->productTbl->aggregate($pipeline);
Now the above query is fetching all the feilds from product table but categorydetails and vendordetails are empty. I am not able to trace this issue.
Please help!!!
The output is like
{"$id":"59941ea11d78596801000029"},"productId":14,"productName":"Pencils","vendorId":"2","categoryId":"5","quantity":"122","sellingPrice":"122","vendordetails":[],"categorydetails":[]
The actual document for category table is like
{
"categoryId": 18,
"categoryName": "swdgvqaedeadsgsgdf",
}
The actual document for vendor table is like
{
"_id": ObjectId("599413e01d78596409000029"),
"VendorID": 3,
"VendorName": "hydfyugjgfu",
}
The actual document for product table is like
{
"_id": ObjectId("59941ec11d7859680100002a"),
"productId": 15,
"productName": "Pens",
"vendorId": "3",
"categoryId": "7",
...
...
}
I have an array of hashes. Each element in the array is a node in a hierarchical tree and has referential data for who the parent is. I will have thousands and hundreds of thousands of nodes in the tree... essentially an unknown set of nodes has to be converted to JSON (shown below) for use with http://bl.ocks.org/robschmuecker/7880033
UPDATE: position_id is a node in the heretical tree. placement_id is the parent's position_id (adjacency referential tree).
UPDATE: Here's the full AoH Data::Dumper result with Nested Set and Adjacency result from a modified version of DBIx::Tree::NestedSet (custom).
$VAR1 = [
{
'lft' => '673',
'id' => '109',
'date_created' => '2015-08-15',
'level' => '7',
'user_id' => '13',
'placement_id' => '11',
'position_id' => '13',
'status' => '1',
'structure_id' => '1',
'rght' => '684'
},
{
'placement_id' => '13',
'position_id' => '22',
'status' => '1',
'structure_id' => '1',
'rght' => '679',
'lft' => '674',
'date_created' => '2015-08-15',
'id' => '116',
'level' => '8',
'user_id' => '22'
},
{
'user_id' => '101',
'level' => '9',
'id' => '200',
'date_created' => '2015-08-15',
'lft' => '675',
'rght' => '676',
'structure_id' => '1',
'status' => '1',
'position_id' => '101',
'placement_id' => '22'
},
{
'date_created' => '2015-08-15',
'id' => '201',
'level' => '9',
'user_id' => '374',
'lft' => '677',
'structure_id' => '1',
'rght' => '678',
'placement_id' => '22',
'position_id' => '374',
'status' => '1'
},
{
'lft' => '680',
'user_id' => '95',
'level' => '8',
'id' => '117',
'date_created' => '2015-08-15',
'status' => '1',
'position_id' => '95',
'placement_id' => '13',
'rght' => '681',
'structure_id' => '1'
}
];
THIS IS THE GOAL, For this example I need to end up with:
{
"name": "13",
"children": [
{
"name": "22",
"children": [
{
"name": "101"
},
{
"name": "374"
}
]
},
{
"name": "95"
}
]
}
You can also see the format I am trying to arrive at here (minus size):
http://bl.ocks.org/robschmuecker/7880033#flare.json
My failed approach(es) included various attempts at looping through the array of hashes to create a recursive Hash of Hashes that can then be used with the JSON Perl module to create the actual JSON I need.
my $data = [
{ position_id => 123, placement_id => undef },
{ position_id => 456, placement_id => 123 },
{ position_id => 789, placement_id => 123 },
# ...
];
my $roots;
{
my %recs_by_name;
my %children_by_parent_name;
for my $row (#$data) {
my $name = $row->{position_id};
my $parent_name = $row->{placement_id};
my $rec = {
name => $name,
};
push #{ $children_by_parent_name{$parent_name // 'root'} }, $rec;
$recs_by_name{$name} = $rec;
}
$roots = delete($children_by_parent_name{root}) || [];
for my $name (keys(%children_by_parent_name)) {
my $children = $children_by_parent_name{$name};
if ( my $rec = $recs_by_name{$name} ) {
$rec->{children} = $children;
} else {
die("Parent $name doesn't exist.\n");
push #$roots, #$children;
}
}
}
print(Dumper($roots));
Tested.
You appear to have the depth of each node available to you (level). Simpler code could be used if your data was sorted by increasing depths.
While it was #ikegami who ultimately answered the question that led to the solution. I believe the following adaptation adds 4 important elements/clarifications I found helpful, and thought others reading this question and answer would also find useful.
1- Clear addition of all key,value pairs from the originating AoH to the resulting HOH. See while loop.
2- A Child node counter.
3- Inclusion and use of the encode_json function from JSON
4- The result is also an Array with a Hash as the first element. Newbies (like me) might find the explicit #{$roots}[0] passed to encode_json as helpful.
At first I had a similar adapted solution posted as an UPDATE within my question, but was admonished that it was bad etiquette and instructed to post an answer.
#ikegami's deserves the credit for the core of the solution.
sub get_jsonTree {
my ($array_of_hashes_ref) = #_;
my $roots;
my %recs_by_name;
my %children_by_parent_name;
my %count;
for my $row (#$array_of_hashes_ref) {
my $name = $row->{position_id};
my $parent_name = $row->{placement_id};
my $rec = {
name => $name,
};
## Added to loop through all key,value pairs and add them to $rec
while ( my ($key, $value) = each(%$row) ) {
$rec->{$key} = $value;
}
##Added To Count Child Nodes
$count{$parent_name} = 0 if (!$count{$parent_name});
$rec->{'child_count'} = $count{$parent_name};
$count{$parent_name}++;
push #{ $children_by_parent_name{$parent_name // 'root'} }, $rec;
$recs_by_name{$name} = $rec;
}
$roots = delete($children_by_parent_name{root}) || [];
for my $name (keys(%children_by_parent_name)) {
my $children = $children_by_parent_name{$name};
if ( my $rec = $recs_by_name{$name} ) {
$rec->{children} = $children;
} else {
$util{'test'} .= "Parent $name doesn't exist.\n<BR>";
push #$roots, #$children;
}
}
use JSON;
my $json_str = encode_json(#{$roots}[0]);
return $json_str;
}
my $array_of_hashes_ref = [
{ position_id => 123, placement_id => undef },
{ position_id => 456, placement_id => 123 },
{ position_id => 789, placement_id => 123 },
# ...
];
my $json_str = &get_jsonTree($array_of_hashes_ref);
I have the following query:
$aggregate = [
['$unwind' => '$positions'],
['$match' => ['positions.banner_params.project_location_id' => (int)$projectId]],
[
'$project' => [
'page_id' => '$_id',
'position_id' => '$positions.id',
'page' => [
'website_id' => '$website_id',
'rate_tic' => '$rate_tic',
],
'banner_params' => [
'title' => '$positions.banner_params.title',
'tmpl_id' => '$positions.banner_params.tmpl_id'
],
'tmpl' => '$positions.tmpls',
'_id' => 0
]
],
];
$rows = $collection->aggregate($aggregate);
It returns such result:
[0] => Array
(
[page_id] => MongoId Object
(
[$id] => 5527a3a276098d86ae9aa3aa
)
[position_id] => 1
[page] => Array
(
[website_id] => 41
[rate_tic] => 10
)
[banner_params] => Array
(
[title] => My Title
[tmpl_id] => 2
)
[tmpl] => Array
(
[0] => Array
(
[id] => 1
[width] => 500
[height] => 100
)
[1] => Array
(
[id] => 2
[width] => 160
[height] => 400
)
[2] => Array
(
[id] => 7
[width] => 384
[height] => 115
)
)
)
How do I get into the tmpl only the template that match the banner_params.tmpl_id?
first let me sure if i understand it correctly. you want to filter items in the [tmpl] => Array by [id].
you cannot do that directly as the [tmpl] is an embedded object however as the aggregate is a pipeline function you can convert the current output the way you can filter and with $unwind then filter it again with $match and finally get the document as you wanted with $group. Something like below code should achieve what you want;
$aggregate = [
['$unwind' => '$positions'],
['$match' => ['positions.banner_params.project_location_id' => (int)$projectId]],
[
'$project' => [
'page_id' => '$_id',
'position_id' => '$positions.id',
'page' => [
'website_id' => '$website_id',
'rate_tic' => '$rate_tic',
],
'banner_params' => [
'title' => '$positions.banner_params.title',
'tmpl_id' => '$positions.banner_params.tmpl_id'
],
'tmpl' => '$positions.tmpls',
'_id' => 0
]
],
['$unwind' => '$tmpl'], // makes every item as a colection
['$match' => ['tmpl.id' => (int)$your id]], //filter the records
['$group' => ['_id' => '$page_id', tmpl:{$push:"$tmpl"} ]] // rebuild collection as you wanted you can use a compound _id if this is not enough
//if you don t want to see _id apply another projections to change it.
];
$rows = $collection->aggregate($aggregate);
Might have some errors but this is the logic you should implement.
EDIT:
There is also $redact DOC to remove items in sub documents please see the example.
Restricts the contents of the documents based on information stored in
the documents themselves.
Well, thanks to Onur TOPAL's advice I found the solution. One more $unvind followed by $redact did the job.
$aggregate = [
['$unwind' => '$positions'],
['$match' => ['positions.banner_params.project_location_id' => (int)$projectId]],
[
'$project' => [
'page_id' => '$_id',
'position_id' => '$positions.id',
'page' => [
'website_id' => '$website_id',
'rate_tic' => '$rate_tic',
],
'banner_params' => [
'title' => '$positions.banner_params.title',
'tmpl_id' => '$positions.banner_params.tmpl_id'
],
'tmpl' => '$positions.tmpls',
'_id' => 0
]
],
['$unwind' => '$tmpl'],
[
'$redact' => [
'$cond' => [
'if' => ['$eq' => ['$tmpl.id', '$banner_params.tmpl_id']],
'then' => '$$KEEP',
'else' => '$$PRUNE'
]
]
]
];
Unfortunately, I cannot use positional operators since there is a bug that doesn't allow deeper than 1 embedded document: https://jira.mongodb.org/browse/SERVER-831
So this wont work (using the Mongodb Ruby driver):
stat_profile.update({ profile_id: profile.id, providers: { '$elemMatch' => { provider_name: 'foo', dates: { '$elemMatch' => { date: 20130911, relationships: { '$elemMatch' => { relationship_type: 'friend' } } } } } } },
{ '$set' => { 'providers.$.dates.$.relationships.$.ids' => [1,2,3] } })
Given the following collection. Relationships is embedded in dates, dates is embedded in providers.
How do I update the ids field?
{
"_id" => BSON::ObjectId('523048983858f61767000008'),
"profile_id" => 3,
"providers" => [
[0] {
"provider_name" => "foo",
"dates" => [
[0] {
"date" => 20130911,
"relationships" => [
[0] {
"relationship_type" => "acquaintance",
"count" => 0
},
[1] {
"relationship_type" => "friend",
"count" => 0,
"males_count" => 0,
"females_count" => 0,
"top_ten_countries" => [],
"ids" => []
}
]
}
]
}
]
}