MongoDB get data from files from gridFS with aggregate function - mongodb

Is it possible to get the files from a gridFS mongo database with a aggregate query?
I have the following query:
$ops = array(
array(
'$match' => array(
"_id" => array('$lt' => new MongoId($id)),
"data.VisionId" => (string)$visionId,
"data.GroepNummer" => (string)$groepnummer,
"data.TypeFile" => ucfirst($typefile),
'data.Datum' => array('$gt' => $new_date, '$lte' => $datum),
)
),
array(
'$sort' => array(
"uploadDate" => -1,
)
),
array(
'$limit' => 1000
),
array(
'$group' => array(
"_id" => array("Datum" => '$data.Datum',),
"FirstId" => array('$first' => '$_id'),
),
),
);
$result = $gridFS->aggregate($ops);
With a foreach I get the result from this aggregate.
But how do I get the data from the file.
(with a normal query i do it like $obj2->getBytes();)

Related

Case insensitive search inside projection condition

The data in hotel table is stored like
{
_id: ....,
HotelName: ...,
MasterKeyDetails:[
{
MasterKeyId: 36K1,
...
},
{
MasterKeyId: 36J1,
...
}
]
}
I have written below query
$cursor = $this->collection->aggregate(array(
array(
'$match' => array(
"_id" => new MongoDB\BSON\ObjectID($this->id)
)
),
array(
'$project' => array(
'MasterKeyDetails' => array(
'$filter' => array(
'input' => '$MasterKeyDetails',
'as' => 'room',
'cond' => array(
'$eq' => array('$$room.MasterKeyId', $this->MasterKeyId)
)
)
),
)
)
)
)->toArray();
It is searching fine. It searches when $this->MasterKeyId contains 36K1, but does not search when $this->MasterKeyId contains 36k1. I want it should fetch despite of case sensitive data...
Please help!!!
You can use $toUpper to normalise the data:
$cursor = $this->collection->aggregate(array(
array(
'$match' => array(
"_id" => new MongoDB\BSON\ObjectID($this->id)
)
),
array(
'$project' => array(
'MasterKeyDetails' => array(
'$filter' => array(
'input' => '$MasterKeyDetails',
'as' => 'room',
'cond' => array(
'$eq' => array(array('$toUpper' =>'$$room.MasterKeyId'), $this->MasterKeyId)
)
)
),
)
)
)
)->toArray();
In the same way you make sure the data you have to supply for comparison is also in the same case. There is also $toLower if you prefer that way.
As yet there is no other "case insensitive match" function you can use as part of an aggregation pipeline, so "normalizing" is the current approach.

Search not working in mongo db php

I have a collection in mongo db like
"_id": ObjectId("5aa662b0d2ccda095400022f"),
"EmployeeNumber": "12345",
"JobTitle": ObjectId("5a7c2008d2ccda04d000606f"),
"Instructor": NumberInt(1),
"Department": ObjectId("5a8173e6d2ccda13240015a4"),
"FirstName": "Aasiya",
"MiddleName": "Rashid",
"LastName": "Khan"
And I am trying to search on one parameter by using below lines of code
$param = preg_replace('!\s+!', ' ', $this->searchCriteria);
$arg = trim($param);
var_dump($arg);
$cursor= $this->collection->aggregate(
array(
array(
'$project' => array(
'FullName' => array('$concat' => array('$FirstName', ' ', '$MiddleName', ' ', '$LastName')),
'FirstMiddle' => array('$concat' => array('$FirstName', ' ', '$MiddleName')),
'FirstLast' => array('$concat' => array('$FirstName', ' ', '$LastName')),
'Employee' => '$$ROOT'
)
),
array(
'$match' =>
array('$or' =>
array(
array("Employee.FullName" => new MongoRegex("/$arg/i")),
array("Employee.FirstLast" => new MongoRegex("/$arg/i")),
array("Employee.FirstMiddle" => new MongoRegex("/$arg/i")),
array("Employee.EmployeeNumber" => new MongoRegex("/^$arg/i"))
)
)
),
)
);
return $cursor->toArray();
It is returning empty array like "array(0) { }". I have tried something like this in earlier version of mongo db, the above query was working fine. Now I am mongo db 3.6, it is not working in this version. If I give "aa" in parameter searchCriteria, it does not work.
Please help!!!
The last stage should be
array(
'$match' =>
array('$or' =>
array(
array("FullName" => new MongoDB\BSON\Regex($arg, 'i')),
array("FirstLast" => new MongoDB\BSON\Regex($arg, 'i')),
array("FirstMiddle" => new MongoDB\BSON\Regex($arg, 'i')),
array("Employee.EmployeeNumber" => new MongoDB\BSON\Regex($arg, 'i'))
)
)
),

How to use multiple array index in $unwind using MongoDB?

I have following query where I am using same array index for three fields. But query response is incorrect because of using same arra index. Using query as follows
$pipeline = array(
array(
'$project' => array(
'YPhaseVoltage' => 1,
'RPhaseVoltage' => 1,
'EventTS' => 1
)
),
array(
'$unwind' => array(
'path' => '$RPhaseVoltage',
'includeArrayIndex' => "arrayIndex",
'preserveNullAndEmptyArrays' => true
)
),
array(
'$unwind' => array(
'path' => '$YPhaseVoltage',
'includeArrayIndex' => "arrayIndex",
'preserveNullAndEmptyArrays' => true
)
),
array('$match' => array(
'$and' => array(
array("RPhaseVoltage" => array('$ne' => null)),
array("YPhaseVoltage" => array('$ne' => null))
)
),
),
array(
'$project' => array(
'_id' => 0,
'RPhaseVoltage' => 1,
'YPhaseVoltage' => 1,
'RYBTimestamp' => array(
'$add' => array(
array('$subtract' => array('$EventTS', $default_date)),
array('$multiply' => array( 60000, '$arrayIndex' ))
)
)
)
),
array(
'$project' => array(
'rvoltage_data' => array('$RYBTimestamp', '$RPhaseVoltage'),
'yvoltage_data' => array('$RYBTimestamp', '$YPhaseVoltage'),
'RYBTimestamp' => 1
)
),
array(
'$sort' => array('RYBTimestamp' => 1),
),
array(
'$limit' => 50
)
);
$result = $collection->aggregate($pipeline);
I want to use individual array index for each filed. Which gives me expected response. Please suggest me how to use multiple array index in mongodb aggregate?

Get sum of quantity in mongodb using yii2 framework

How can i sum of quantity using mongodb query in yii2?
In my database there are entries like below:
{
'_id': ObjectId("560e36f91e4acbf113d14f1f"),
'user_id': '55ded7c31e4acbea3c8b4567',
'money': '1.99',
'quantity': '1',
'purchased_date_time': '2015-10-02 07:49:13'
}
{
'_id': ObjectId("560e36f71e4acbf113d14f1e"),
'user_id': '55ded7c31e4acbea3c8b4567',
'money': '1.99',
'quantity': '1',
'purchased_date_time': '2015-10-02 07:49:11'
}
{
'_id': ObjectId("560d17381e4acbf013d14f1e"),
'user_id': '55ded7c31e4acbea3c8b4567',
'money': '4.99',
'quantity': '3',
'purchased_date_time': '2015-10-01 11:21:28'
}
I want to sum of quantity where user_id = 55ded7c31e4acbea3c8b4567.
What i tried is:
$collection = Yii::$app->mongodb->getCollection('purchase');
$result = $collection->aggregate(
array( '$match' => array( 'user_id' => '55ded7c31e4acbea3c8b4567') ),
array( '$group' => array( '_id' => NULL,
'quantity' => array( '$sum' => (int)'$quantity' )
))
);
But always i am getting this result:
<pre>Array
(
[0] => Array
(
[_id] =>
[quantity] => 0
)
)
</pre>
Can anyone help?
Remove int then after check......
I solved my issue after remove it
$collection = Yii::$app->mongodb->getCollection('purchase');
$result = $collection->aggregate(
array( '$match' => array( 'user_id' => '55ded7c31e4acbea3c8b4567') ),
array( '$group' => array( '_id' => NULL,
'quantity' => array( '$sum' => '$quantity' )
))
);

How to make this MongoDB aggregation return key:value?

I have this aggregation:
$out = $db->stats->aggregate (
array('$match' => $where),
,array( '$group' =>
array( "_id" => '$traffic.source',
'count'=> array('$sum' => 1)
)
)
,array( '$project' =>
array( "_id" => 0,
'type' => '$_id',
'count' => '$count'
)
)
);
which returns an array with:
[{type:sourceA, count:2},{type:sourceB, count:6}...]
Is it possible to make it return:
[sourceA:2, sourceB:6,....] without looping the array afterwords?