How to use aggregate and $lookup with php 7 mongo driver manager.
How to convert the following mongo command to php
db.a.aggregate([{$lookup:{from:"b",localField:"business_id",foreignField:"_id",as:"contact"}}])
Also recommend good reference tutorials.
This code worked
$mng = new MongoDB\Driver\Manager("mongodb://localhost:27017");
$command = new MongoDB\Driver\Command([
'aggregate' => 'a',
'pipeline' => [
['$lookup' => ["from" => "b","localField" => "business_id","foreignField" => "_id","as" => "contact"]],
],
]);
$cursor = $mng->executeCommand('test', $command);
Try something like this:
$mongo->db->a->aggregate([
['$lookup' => ['from' => 'b', 'localField' => 'business_id', 'foreignField' => '_id', 'as' => 'contact'] ]
]);
PHP7.2
MongoDB 4.2
I took reference from #Jibin Mathew' answer but I got some errors.
then I added
'cursor' => new stdClass,
this line in code.
Now it's working properly.
//mongo database join example
public function test_join() {
global $mng;
global $dbname;
$pipeline = [['$lookup' => ["from" => "b","localField" => "business_id","foreignField" => "_id","as" => "contact"]]];
$aggregate = new \MongoDB\Driver\Command([
'aggregate' => 'a',
'cursor' => new stdClass,
'pipeline' => $pipeline,
]);
$cursor = $mng->executeCommand($dbname, $aggregate);
return $cursor;
}
Related
I want to get data from mongodb by using MongoDB PHP7.1 Driver with the help of $or or $and clause in filter. I have tried to construct query to do the same but that didn't work.
Here is my sample code here:
$manager = new MongoDB\Driver\Manager("mongodb://localhost:27017");
try {
$filter = [
'$or' => [
'age' => [ '$gt' => 40],
'name' => 'abc'
]
];
$query = new MongoDB\Driver\Query($filter);
$rows = $manager->executeQuery("test.users", $query);
foreach ($rows as $key => $val) {
print_r($val);
}
} catch(MongoDB\Driver\Exception $e) {
echo $e->getMessage(), "\n";
exit;
}
The above code gives me below error:
Fatal error: Uncaught MongoDB\Driver\Exception\ConnectionException: $or must
be an array in C:\xampp\htdocs\local\demo.php:50 Stack trace: #0
C:\xampp\htdocs\local\demo.php(50): MongoDB\Driver\Manager-
>executeQuery('test.users', Object(MongoDB\Driver\Query)) #1 {main} thrown
in C:\xampp\htdocs\local\demo.php on line 50
Please help me to understand what I am doing wrong.
Adding to answer from #Veeram: Had this as my filter, which did not work:
$filter = [
'$and' =>
['date' => ['$gte' => $start_date]],
['date' => ['$lte' => $end_date]]
];
added the extra [] as #Veeram suggested. This configuration works for $and:
$filter = [
'$and' => [
['date' => ['$gte' => $start_date]],
['date' => ['$lte' => $end_date]]
]
];
you can do this also
$result=$collections->
find(array('$and=>array(array('date'=>array('$gte'=>$start_date)
),array('date'=>array('$lte'=>$end_date))));
In mongo shell the query:
db.collections.distinct('user_id');
simply gives the distinct documents.
I am working on phalcon and there is no option like
Collections::distinct()
So how do i query distinct in phalcon. Please help me
Perhaps Phalcon's answer in the forum could help: https://forum.phalconphp.com/discussion/6832/option-for-function-distinct-phalconmvccollection
They suggest using aggregations:
$data = Article::aggregate(
array(
array(
'$project' => array('category' => 1)
),
array(
'$group' => array(
'_id' => array('category' => '$category'),
'id' => array('$max' => '$_id')
)
)
)
);
Is there a way to perform a raw query (just as you can do with MySQL) in Doctrine with MongoDB?
I'm trying to do this:
db.report.aggregate([{"$group" : {_id:"$content", count:{$sum:1}}}])
It doesn't seem to be a native aggregate function in Doctrine either, is it?
Following did the trick for me
$dbName = $this->container->getParameter('mongo_db_name');
$connection = $this->container->get('doctrine_mongodb')->getConnection();
$mongo = $connection->getMongo();
$db = $mongo->selectDB($dbName);
$results = $db ->command([
'aggregate' => 'report',
'pipeline' => [
['$group' => ['_id' => '$content', 'count' => ['$sum' => 1]]]
]
]);
return $results;
Not sure about native Doctrine function, but in case of aggregations I'd prefer to have RAW JSON output, because it's mostly used to render out some charts.
I needed to use an advanced version of a $lookup stage, but sadly, didn't because its lookup() method adds just a basic version of a stage like:
public function getExpression(): array
{
return [
'$lookup' => [
'from' => $this->from,
'localField' => $this->localField,
'foreignField' => $this->foreignField,
'as' => $this->as,
],
];
}
An obvious solution would be to provide a custom version of Stage/Lookup.php class, but I didn't want to create a separate file for such a small thing, so I decided to go with inline class:
$lookupExpr = [
'$lookup' => [...],
];
$aggregationBuilder->addStage(new class($lookupExpr, $aggregationBuilder) extends Aggregation\Stage {
public function __construct(private array $lookupExpr, Builder $builder) {parent::__construct($builder);}
public function getExpression(): array
{
return $this->lookupExpr;
}
});
In Doctrine ODM 2.0, the underlying connection is handled by the mongodb/mongodb package instead of doctrine/mongodb. As such, you can get the connection though doctrine ManagerRegistry::getConnection(), then use the command function using the mongodb library:
use Doctrine\Bundle\MongoDBBundle\ManagerRegistry;
class Test {
function execute(ManagerRegistry $mr) {
$database= $mr->getConnection()->db_name;
$cursor = $database->command([
'geoNear' => 'restos',
'near' => [
'type' => 'Point',
'coordinates' => [-74.0, 40.0],
],
'spherical' => 'true',
'num' => 3,
]);
$results = $cursor->toArray()[0];
var_dump($results);
}
}
In my case i use aggregation
$db = $mongo->selectDB('ostrov_sync');
$dbTable = $mongo->selectCollection($db, 'sync_task');
$results = $dbTable->aggregate([
[
'$match' => [
'payloadHash' => [
'$eq' => '0000cfdc-c8cf-11e9-9485-000c29d1ed7a',
],
],
]
]);
dump(results);
Using ichikaway-cakephp I am trying to convert following query (running fine in php) to cakephp
In cakephp it returns empty array
Core PHP
$out = $collection->aggregate(array(
array('$unwind' => '$as'),
array(
'$group' => array(
'_id' => array('as'=>'$as'),
'count' => array('$sum' => 1)
)
)
));
Cakephp
$conditions=array('aggregate'=>array(
array('$unwind' => '$as'),
array(
'$group' => array(
'_id' => array('as'=>'$as'),
'count' => array('$sum' => 1)
)
)
));
$results = $this->Post->find('all',array('conditions'=>$conditions));
I am unable to find aggrgation framework function in test cases
So far only this commit talks about aggregation.
$params = array(
array('$unwind' => '$as'),
array(
'$group' => array(
'_id' => array('as'=>'$as'),
'count' => array('$sum' => 1)
)
)
));
$mongo = $this->Post->getDataSource();
$mongoCollectionObject = $mongo->getMongoCollection($this->Post);
$results = $mongoCollectionObject->aggregate($params);
I have some difficulty in getting Mongodb aggregate to work. It keeps giving me null. Please help. Below are the codes written in php. Thanks.
What I want to do is to sum up the values of 2 fields, Requests and Responses, between 2 particular dates
try {
$mongodb = new MongoClient("mongodb://ad:pass2word1#localhost");
$database = $mongodb->selectDB('backend');
$collection = new MongoCollection($database, 'RequestSummary');
$pipeline = array(
array(
'$group' => array(
'_id' => array(
'request' => array('$sum' => '$Requests'),
'response' => array('$sum' => '$Responses')
)
)
),
array(
'$match' => array(
'RequestDate' => array(
'$gte' => intval($_SESSION['range_from']),
'$lte' => intval($_SESSION['range_to'])
)
)
)
);
$collection->aggregate($pipeline);
var_dump($g);
} catch (MongoConnectionException $exc) {
echo $exc->getTraceAsString();
}
The _id of your $group can't contain aggregation operators like $sum. Those sums need to be defined as fields at the same level as _id. If you don't want to group on a specific field you can use NULL for the _id like this:
array(
'$group' => array(
'_id' => NULL,
'request' => array('$sum' => '$Requests'),
'response' => array('$sum' => '$Responses')
)
),