I am performing aggregation command in mongodb php application like below lines of code.
<?php
$query = array('$or' => array(
array('employeeList'=>array('$exists' => false)),
array('employeeList'=>array('$eq' => null)),
array('employeeList'=>array('$eq' => ",")),
array('employeeList'=>array('$eq' => ""))
));
$pipeline = array(
array(
'$match' => $query
),
array(
'$lookup' => array(
'from' => 'userTbl',
'localField' => 'user_id',
'foreignField' => 'uid',
'as' => 'userdetails'
)
),
);
$output = $this->db->broadcastTbl->aggregate($pipeline);
$result =array();
array_push($result, $output);
Now the output is displayed as
[{"waitedMS":0,"result":[{"_id":{"$id":"58d7a6561d78597411000029"},"broadcast_id":35,"studentList":"","employeeList":"999","mailTitle":"hello","broadcastMessage":"how","emailSent":"0","userdetails":[]},{"_id":....
...
"ok":1}]
I want to remove "waitedMS":0. "result":, and "ok":1 from the json. The output should be like
[{"_id":{"$id":"58d7a6561d78597411000029"},"broadcast_id":35,"studentList":"","employeeList":"999","mailTitle":"hello","broadcastMessage":"how","emailSent":"0","userdetails":[]}, ...
]
Please help me !!!
All you need to do is access the "result" item. Don't push it onto another array.
<?php
$query = array('$or' => array(
array('employeeList'=>array('$exists' => false)),
array('employeeList'=>array('$eq' => null)),
array('employeeList'=>array('$eq' => ",")),
array('employeeList'=>array('$eq' => ""))
));
$pipeline = array(
array(
'$match' => $query
),
array(
'$lookup' => array(
'from' => 'userTbl',
'localField' => 'user_id',
'foreignField' => 'uid',
'as' => 'userdetails'
)
),
);
$output = $this->db->broadcastTbl->aggregate($pipeline);
$result = $output["result"];
Related
I have written like below lines of code
$cursor = $this->collection->aggregate(array(
array(
'$match' => array(
"_id" => new MongoDB\BSON\ObjectID($this->id)
)
),
array(
'$project' => array(
'AllotmentsDetails' => array(
'$filter' => array(
'input' => '$AllotmentsDetails',
'as' => 'allot',
'cond' => array(
'$and' => array(
'$lt' => array('$$allot.ToDate', new MongoDB\BSON\UTCDateTime((new DateTime())->getTimestamp() * 1000)),
'$eq' => array('$$allotment.RoomId', $this->RoomId)
)
)
)
),
)
)
))->toArray();
It is throwing error message " Uncaught exception 'MongoDB\Driver\Exception\RuntimeException' with message 'An object representing an expression must have exactly one field:"
Please help!!!
Just missing array notations and matching up in some wrong places:
$pipeline = array(
array( '$match' => array(
"_id" => new MongoDB\BSON\ObjectID($this->id)
)),
array('$project' => array(
'AllotmentsDetails' => array(
'$filter' => array(
'input' => '$AllotmentsDetails',
'as' => 'allotment',
'cond' => array(
'$and' => array(
array('$lt' => array(
'$$allotment.ToDate',
new MongoDB\BSON\UTCDateTime((new DateTime())->getTimestamp() * 1000)
)),
array('$eq' => array('$$allotment.RoomId', $this->RoomId))
)
)
)
)
))
);
$cursor = $this->collection->aggregate($pipeline)->toArray();
or since we are in a modern world, a bit easier to read:
$pipeline = [
['$match' => [
"_id" => new MongoDB\BSON\ObjectID($this->id)
]],
['$project' => [
'AllotmentsDetails' => [
'$filter' => [
'input' => '$AllotmentsDetails',
'as' => 'allotment',
'cond' => [
'$and' => [
['$lt' => [
'$$allotment.ToDate',
new MongoDB\BSON\UTCDateTime((new DateTime())->getTimestamp() * 1000)
]],
['$eq' => ['$$allotment.RoomId', $this->RoomId] ]
]
]
]
]
]]
];
$cursor = $this->collection->aggregate($pipeline)->toArray();
I suggest a better editor and also to use json_encode() on your data structures in order to check that the generated JSON matches what you see as examples in the documentation.
hi i have a problom with mongo $aggregate on the php driver
i have this code in PHP:
$match1 = array( '$and' => array(
array("uid" => array('$nin'=> $where_blocked)),
array("type" => "picture" ),
array("active" => true )
));
$match2 = array( '$and' => array(
array("uid" => array('$in'=> $where)),
array("type" => "users" )
));
$query = array(
array(
'$match' => array(
'$or' => array( $match1,$match2 )
),
),
array(
'$lookup' => array(
'from' => 'users',
'localField' => 'objId',
'foreignField' => '_id',
'as' => 'user'
),
),
array(
'$lookup' => array(
'from' => 'pictures',
'localField' => 'objId',
'foreignField' => '_id',
'as' => 'pic'
),
),
array(
'$limit' => $pageSize
),
array(
'$sort' => array("DateCreated" => -1 )
),
array(
'$skip' => $pageSize*($page-1)
)
);
$cursor = $log->aggregate($query);
this is working but i only get the $match1 not the $match2 i need to get OR match 1 or match2 depending of the most new document.
on find this wil work:
$query_or = array('$or' => array($match1,$match2));
$cursor = $log->find($query_or)->sort(array("DateCreated" => -1))->skip($pageSize*($page-1))->limit($pageSize);
but need the $lookup (join) and i can not use it on find
can someone help me?
Thanks
If you absolutely need to use $lookup, just use aggregate instead of find.
It does work and will bring you all the data:
db.your_table.aggregate([
{
$match: {
$or: [
{type:"picture"},
{type:"rate"}
]
}
},
{
$lookup: {
'from' : 'users',
'localField' : 'objId',
'foreignField' : '_id',
'as' :'user'
}
},
{
$lookup: {
'from' : 'pictures',
'localField' : 'objId',
'foreignField' : '_id',
'as': 'pic'
}
}
])
i have a function with a dynamic array.
function doIt($accountid,$targeting){
$post_url= "https://url".$accountid."/";
$fields = array(
'name' => "test",
'status'=> "PAUSED",
'targeting' => array(
$targeting
),
);
$curlreturn=curl($post_url,$fields);
};
And i want to build the array "$fields" dynamically within a foreach loop. Like that:
$accountid="57865";
$targeting=array(
"'device_platforms' => array('desktop'),'interests' => array(array('id' => '435345','name' => 'test')),",
"'device_platforms' => array('mobile'), 'interests' => array(array('id' => '345345','name' => 'test2')),",
);
foreach ($targeting as $i => $value) {
doit($accountid,$value);
}
The Problem is, that the array within the function will not be correctly filled. If i output the array in the function i get something like:
....[0] => array('device_platforms' => array('desktop'),'custom_audiences'=> ['id' => '356346']), )
The beginning [0] should be the problem. Any ideas what im doing wrong?
Hope this will help you out. The problem was the way you are defining $targeting array. You can't have multiple keys with same name
Change 1:
$targeting = array(
array(
'device_platforms' => array('desktop'),
'interests' => array(
array('id' => '435345',
'name' => 'test')),
),
array(
'device_platforms' => array('mobile'),
'interests' => array(
array('id' => '345345',
'name' => 'test2'))
)
);
Change 2:
$fields = array(
'name' => "test",
'status' => "PAUSED",
'targeting' => $targeting //removed array
);
Try this code snippet here this will just print postfields
<?php
ini_set('display_errors', 1);
function doIt($accountid, $targeting)
{
$post_url = "https://url" . $accountid . "/";
$fields = array(
'name' => "test",
'status' => "PAUSED",
'targeting' => $targeting
);
print_r($fields);
}
$accountid = "57865";
$targeting = array(
array(
'device_platforms' => array('desktop'),
'interests' => array(
array('id' => '435345',
'name' => 'test')),
),
array(
'device_platforms' => array('mobile'),
'interests' => array(
array('id' => '345345',
'name' => 'test2'))
)
);
foreach ($targeting as $i => $value)
{
doit($accountid, $value);
}
My query is working in mongodb and produce output Properly. But same query i tried to run using php then it gives following error
Array
(
[ok] => 0
[errmsg] => A pipeline stage specification object must contain exactly one field.
[code] => 16435
)
Following is my MongoDB Query
db.sample_coll.aggregate(
{
$unwind: {
path:"$KeyValues",
includeArrayIndex:"arrayIndex",
preserveNullAndEmptyArrays:true
}
},
{
$project: {
timestamp:{
"$add":["$EventTS",{"$multiply":[60000,"$arrayIndex"]}]
} ,
"InputVolt":"$KeyValues.InputVolt",
arrayIndex:1
}
},
{
$match: {
$and: [
{InputVolt: {$ne: null}}
]
}
}
);
The Above query is converted in php
$pipeline = array(
array('$unwind' =>
array( 'path' => '$KeyValues'),
array( 'includeArrayIndex' => 'arrayIndex' ),
array( 'preserveNullAndEmptyArrays' => 'true' )
),
array(
'$project' => array(
'timestamp' => array(
'$add' => array(
'$EventTS',
array('$multiply' => array( 60000, '$arrayIndex' ))
)
),
array( 'InputVolt' => array( '$KeyValues', 'InputVolt' ) ) ,
array('arrayIndex' => 1)
)
),
array(
'$match' => array(
'$and' => array(
array('InputVolt' => array('$ne' => null )),
)
)
)
);
$result = $collection->aggregate($pipeline);
Kindly help to resolve this issue.
Thanks in advance
Your pipeline in PHP:
$pipeline = array(
array('$unwind' => array(
'path' => '$KeyValues',
'includeArrayIndex' => 'arrayIndex',
'preserveNullAndEmptyArrays' => true
)),
array('$project' => array(
'timestamp' => array(
'$add' => array('$EventTS', array('$multiply' => array(60000, '$arrayIndex')))
),
'InputVolt' => '$KeyValues.InputVolt',
'arrayIndex' => 1
)),
array('$match' => array(
'InputVolt' => array('$ne' => null)
))
);
I'm using mongodb 2.1 and how to translate this query into php
db.counter.aggregate([
{ $match:{ page_id:123456 }},
{ $group:{_id:"$page_id",total:{$sum:"$pageview"}} }
]);
Thanks
You can use the 'command()' method in PHP to run the aggregation framework as a database command. The precise syntax for your sample query would be:
$conn = new Mongo("localhost:$port");
$db = $conn->test;
$result = $db->command (
array(
"aggregate" => "counter",
"pipeline" =>
array(
array( '$match' => array( 'page_id' => 123456 )),
array( '$group' => array( "_id" => '$page_id',
'total' => array( '$sum' => '$pageview')
)
)
)
)
);
Try:
$m = new MongoClient();
$con = $m->selectDB("dbName")->selectCollection("counter");
$cond = array(
array('$match' => array('page_id' =>123456)),
array(
'$group' => array(
'_id' => '$page_id',
'total' => array('$sum' => '$pageview'),
),
)
);
$out = $con->aggregate($cond);
print_r($out);
For more detail click here