How to do mongo db aggregation join operation in php? - mongodb

I have three collections in mongodb like
employeeTitleTbl contains
{
"_id": ObjectId("5a7c2027d2ccda04d0006070"),
"EmployeeTitleName": "Librarian",
"EmployeeTitleCode": "ji8766",
..
}
DepartmentsTbl contains
{
"_id": ObjectId("5a817402d2ccda13240015a5"),
"DepartmentCode": "149",
"DepartmentName": "Biology",
..
}
EmployeesTbl contains
{
"_id": ObjectId("5a81957bd2ccda13240015a8"),
"EmployeeNumber": "25789998",
"JobTitle": ObjectId("5a7c2008d2ccda04d000606f"),
"Department": ObjectId("5a8173e6d2ccda13240015a4"),
...
}
I am very new to mongodb and also driver has also updated 3.6, so it is very difficult to find the latest method of aggregation in php. So I was tweaking the below code for adding department and employee title actual values like "EmployeeTitleName" and "DepartmentName" in EmployeesTbl.
public function fetchAll()
{
$pipeline = array(
array(
'$lookup' => array(
'from' => 'DepartmentsTbl',
'localField' => 'Department',
'foreignField' => '_id',
'as' => 'DepartmentDetails'
)
),
array(
'$lookup' => array(
'from' => 'employeeTitleTbl',
'localField' => 'JobTitle',
'foreignField' => '_id',
'as' => 'JobTitleDetails'
)
),
);
try
{
$cursor = $this->db->EmployeesTbl->aggregate($pipeline);
}
catch(Exception $e){
}
return $cursor->toArray();
}
Please help me in latest method!!!
The output is like
array(2) { [0]=> object(MongoDB\Model\BSONDocument)#29 (1) { ["storage":"ArrayObject":private]=> array(25) { ["_id"]=> object(MongoDB\BSON\ObjectId)#10 (1) { ["oid"]=> string(24) "5a8176c0d2ccda13240015a6" } ["EmployeeNumber"]=> string(8) "25799989"....
...........
["DepartmentDetails"]=> object(MongoDB\Model\BSONArray)#27 (1) { ["storage":"ArrayObject":private]=> array(0) { } } ["JobTitleDetails"]=> object(MongoDB\Model\BSONArray)#28 (1) { ["storage":"ArrayObject":private]=> array(0) { } } } } [1]=.........

You need to use $lookup to join 2 or more tables for example..
db.employeeTitle.aggregate([{
$lookup: {
from: 'employees',
localField: 'EmployeeTitleName',
foreignField: '_id',
as: 'employeeData'
}
},
{ $unwind: '$employeeData' },
{
$project: { profile: '$employeeData' }
}
])
It joins two tables employeeTitle and employees and give you full information about employees.

Related

$match query not working for lookup array in mongodb

I have two tables in mongodb database
activityCountTbl contains data like
{
"_id": ObjectId("5c234f7e3250041280000ca3"),
"activityId": ObjectId("5c0e27ee590a06bf08003c33"),
"weekgroupId": ObjectId("5bfbddbcbb2c5645f8001495"),
"squadronId": ObjectId("5bfc7b7ebb2c56c320002a0a"),
"attendingCount": NumberInt(6),
....
}
{
"_id": ObjectId("5c234f7e3250041280000ca3"),
"activityId": ObjectId("5c0e27ee590a06bf08003c33"),
"weekgroupId": ObjectId("5bfbddbcbb2c5645f8001496"),
"squadronId": ObjectId("5bfc7b7ebb2c56c320002a0a"),
"attendingCount": NumberInt(6),
....
}
squadronTbl contains data like
{
"_id": ObjectId("5c19ccb7590a060691000554"),
"squadronCode": "336",
"squadronName": "336TRS",
}
{
"_id": ObjectId("5c19ccb7590a060691000556"),
"squadronCode": "337",
"squadronName": "337TRS",
}
I am storing count details of a particular activity of a weekgroup in activityCountTbl. I am performing lookup on squadronTbl with activityCountTbl
for fetching squadrons details of a particular weekgroup. The below code is not working.
When I comment/delete the $query code, it fetches all the squadrons of all weekgroups.
$query = ["ActivityArray.weekgroupId" => new MongoDB\BSON\ObjectID("5bfbddbcbb2c5645f8001495"), "ActivityArray.funRun" => "Yes"];
$pipeline = array(
[
'$match' => $query
],
[
'$lookup' => [
'from' => 'activityCountTbl',
'localField' => '_id',
'foreignField' => 'squadronId',
'as' => 'ActivityArray'
]
],
['$project' => [
'_id' => 1.0,
'squadronName' => 1.0,
'ActivityArray' => 1.0
]],
);
return $this->db->squadronTbl->aggregate($pipeline)->toArray();
Please help !!!
$query = ["ActivityArray.weekgroupId" => new MongoDB\BSON\ObjectID("5bfbddbcbb2c5645f8001495"), "ActivityArray.funRun" => "Yes"]
$pipeline = array(
[
'$match' => []
],
[
'$lookup' => [
'from' => 'activityCountTbl',
'localField' => '_id',
'foreignField' => 'squadronId',
'as' => 'ActivityArray'
]
],
[
'$match' => $query
],
['$project' => [
'_id' => 1.0,
'squadronName' => 1.0,
'ActivityArray' => 1.0
]],
);
something like that

Find on the basis of field of last element of embedded document in mongo db php

I have a collection studentTbl which contains records like
Record 1
"_id": ObjectId("5b45d89bbbc51e2c2c006973")
"first_name": "Pooja",
...
contact_details[
{
..
},
{
..
}
]
transport_details[
{
allotment_id:"68998546878",
..
status:"Inactive"
},
{
allotment_id:"25799856890",
..
status:"Active"
}
]
}
Record 2
"_id": ObjectId("5b45d89bbbc51e2c2533")
"first_name": "Poornima",
...
contact_details[
{
..
},
{
..
}
]
transport_details[
{
allotment_id:"68998546878",
..
status:"Inactive"
}
]
}
Record 3
"_id": ObjectId("5b45d89bbbc51e2c2c00646")
"first_name": "Poonam",
...
contact_details[
{
..
},
{
..
}
]
transport_details[
{
allotment_id:"68998546878",
..
status:"Inactive"
},
{
allotment_id:"25799856890",
..
status:"Active"
}
]
}
I am trying to tweak the below lines of code in order to fetch those students whose first_name or middle_name or last_name contains "poo" and inside the last element of embedded document transport_details, status should be "Active". How to write such a query which will find students on the name basis and traverse through the last element of embedded document transport_details and checks whether the status is active? For e.g in the above collection, pooja and poonam should be returned.
The code is like
// default if nothing is filled
$query = array("schoolId"=> new MongoDB\BSON\ObjectID($this->schoolId));
// if name = filled, class = null, year = null
if(!empty($this->name) && empty($this->academicYearName) && empty($this->programId))
{
$param = preg_replace('!\s+!', ' ', $this->name);
$arg = trim($param);
$query = array(
'$or' => array(
array("first_name" => new MongoDB\BSON\Regex($arg, 'i')),
array("middle_name" => new MongoDB\BSON\Regex($arg, 'i')),
array("last_name" => new MongoDB\BSON\Regex($arg, 'i')),
array("registration_temp_perm_no" => $arg)
),
"schoolId"=> new MongoDB\BSON\ObjectID($this->schoolId)
);
}
...
...
...
$pipeline = array(
array(
'$match' => $query
),
array(
'$lookup' => array(
'from' => 'programTbl',
'localField' => 'classId',
'foreignField' => '_id',
'as' => 'ClassDetails'
)
),
);
try
{
$cursor = $this->collection->aggregate($pipeline);
}
catch (Exception $e) {
}
return $cursor->toArray();
Note that the actual code contains more conditional $query variable...
You can use below query in 3.6.
array(
'$or' => array(
array("first_name" => new MongoDB\BSON\Regex("/poo/i")),
array("middle_name" => new MongoDB\BSON\Regex("/poo/i")),
array("last_name" => new MongoDB\BSON\Regex("/poo/i"))
),
"$expr" => array(
"$eq" => array(
array("$arrayElemAt" => array("$transport_details.status", -1)),
"Active"
)
)
);
You can add below stages in your pipeline
array(
"$match" => array(
"$expr" => array(
"$and" => [
array(
"$or" => [
array( "$eq" => [ array( "$strcasecmp" => [ "$first_name", "Poo" ] ), 1 ] ),
array( "$eq" => [ array( "$strcasecmp" => [ "$last_name", "Poo" ] ), 1 ] ),
array( "$eq" => [ array( "$strcasecmp" => [ "$middle_name", "Poo" ] ), 1 ] ),
],
),
array(
"$eq" => [
array( "$arrayElemAt" => [ array( "$slice"=> [ "$transport_details.status", -1 ] ), 0 ] ),
"Active"
]
)
]
)
)
)

Updating a particular sub document in mongo db php

I have a collection in mongo db called EmployeeTbl with document like
{
"_id": ObjectId("5a8d47d8d2ccda11fc004d91"),
"EmployeeNumber": "9883456787",
"FirstName": "Sana",
...
"ContactDetails": [
{
"ContactTypeId": "04596c6f-82e6-8f00-e3a9-1f3199894284",
"ContactType": "Phone",
"ContactTypeValue": "99456789756"
},
{
"ContactTypeId": "71d0152c-293f-4c6f-2360-bbdfe368eacb",
"ContactType": "Phone",
"ContactTypeValue": "9894567890"
}
]
}
I am trying to update a sub document inside ContactDetails and I have written below code. It is not updating the existing one. Instead of updating, it adds new sub document.
Please help me !!!
public function updateContactDetailsForItsSubDocument()
{
// $bulkbatch = new MongoDB\Driver\BulkWrite(['ordered' => true]);
$subDocumentContactDetails = array(
"ContactDetails" =>
array(
"ContactType" => $this->ContactType,
"ContactTypeValue" => $this->ContactTypeValue
)
);
$this->collection->update(
array('_id' => new MongoDB\BSON\ObjectID($this->id), 'ContactDetails.ContactTypeId'=> $this->ContactTypeId),
array('$set' => $subDocumentContactDetails)
);
// $this->manager->executeBulkWrite($this->collection, $bulkbatch);
}
Change your $subDocumentContactDetails variable so that it uses the $ positional operator for updating an embedded document:
$subDocumentContactDetails = array(
"ContactDetails.$.ContactType" => $this->ContactType,
"ContactDetails.$.ContactTypeValue" => $this->ContactTypeValue
);
$this->collection->update(
array(
"_id" => new MongoDB\BSON\ObjectID($this->id),
"ContactDetails.ContactTypeId" => $this->ContactTypeId
),
array("$set" => $subDocumentContactDetails)
);

How to implement MongoDB query in Laravel 5?

I created mongodb query which I have to use in laravel controller.
My query is
db.PMS.aggregate([
{ $match: { "PanelID": "A00898" } },
{
$project: { EventTS: 1, MainsPower: 1, }
},
{
$unwind: {
path: "$MainsPower",
includeArrayIndex: "arrayIndex",
preserveNullAndEmptyArrays: true
}
},
{
$project: {
MainsPower: 1,
timestamp: {
"$add": [
"$EventTS",
{ "$multiply": [ 60000, "$arrayIndex" ] }
]
}
}
}
]);
I tried to use this query in a laravel function but I am little confused. Please help me how to implement this query in laravel.
Perform raw expressions on the internal MongoCollection object to run the aggregation:
$result = DB => collection('PMS')->raw(function ($collection){
return $collection->aggregate(array(
array( '$match' => array( "PanelID" => "A00898" ) ),
array( '$project' => array( 'EventTS' => 1, 'MainsPower' => 1 ) ),
array(
'$unwind' => array(
'path' => "$MainsPower",
'includeArrayIndex' => "arrayIndex",
'preserveNullAndEmptyArrays' => true
)
),
array(
'$project' => array(
'_id' => 0,
'MainsPower' => 1,
'timestamp' => array(
"$add" => array(
"$EventTS",
array( "$multiply" => array( 60000, "$arrayIndex" ) )
)
)
)
)
));
});

perl mongodb complex structure update

I have this structure:
{
"user" => "xxxx",
"position" =>
{
"A1" => { "state" => 'It', region=>"LOM" etc etc..},
"A2" => { .... },
"A3" => { .... },
....
"An" => { .. }
}
}
insert is ok. but update return this error:
not a reference at /usr/local/lib/perl/5.12.4/MongoDB/Collection.pm line 376
My update is:
$tbl->update({
{ _id => MongoDB::OID->new(value => "$id") },
{ '$set' =>
{
"position" =>
{
"A1" => { "state" => "En" }
}
}
}
});
Where I wrong?
Thks!
I check syntax of update source of MongoDB::Collection
syntax update
update (\%criteria, \%object, \%options?)
inside MongoDB::Collection method update
sub update {
my ($self, $query, $object, $opts) = #_;
...
}
but you pass only 1 parameter.
$tbl->update(
{ # 1st anonymous hash
{ _id => MongoDB::OID->new(value => "$id") },
{ '$set' => {
"position" => {
"A1" => { "state" => "En" }
}
}
}
});
So I advice you figure out with passed parameters to method update.