add where condition in jensseger mongodb with lookup - mongodb

I have code like this:
$users = User::raw(function ($collection) use($profession, $userId, $skip, $pageSize) {
return $collection->aggregate([
[
'$lookup' => [
'from' => 'user_profile',
'localField' => 'uid',
'foreignField' => 'user_id',
'as' => 'profile'
]
],
[
'$match' => [
'profile.field_of_work' => $profession['id'],
'uid' => ['$ne' => $userId]
],
],
['$skip' => $skip],
['$limit' => $pageSize]
]);
});
from there, how to add where clause like this:
::where('name', 'like', '%test%');
I dont know how to using lookup in mongodb and I just know the basic pattern of eloquent.
Thank you

Related

get nested relations data $lookup

i have collection page and page has many widgets:
page collection :
_id
name
slug,
widget_codes
widget collection :
_id
name
code
type
product_ids
category_ids
product collection:
_id
name
type
category collection:
_id
name
type
for retrieve data i use like this:
public function getData($page) {
return $page->raw(function ($collection) use ($page) {
return $collection->aggregate([
[
'$lookup' => [
'from' => 'widgets',
'localField' => 'widget_codes',
'foreignField' => 'code',
'as' => 'widgets',
]
],
[
'$match' => ['slug' => $page->slug]
]
]);
});
}
it works perfect and get widget data now i want to get product and category data with widget using that widget has product_ids and category_ids what query can i use.
You can use pipeline in $lookup for subquery the multiple tables
public function getData($page) {
return $page->raw(function ($collection) use ($page) {
return $collection->aggregate([
[
'$match' => ['slug' => $page->slug]
],
[
'$lookup' => [
'from' => 'widgets',
"let"=> [ "widget_codes"=> "$widget_codes" ],
"pipeline"=> [
[ "$match"=> [ "$expr"=> [ "$in"=> ["$_id", "$$widget_codes"] ]]],
[
'$lookup' => [
'from' => 'category',
'localField' => 'category_ids',
'foreignField' => '_id',
'as' => 'categories',
]
],
[
'$lookup' => [
'from' => 'product',
'localField' => 'product_ids',
'foreignField' => '_id',
'as' => 'products',
]
]
],
'as' => 'widgets',
]
]
]);
});
}

MongoDB PHP aggregate - incorrect data set in output array

I'm trying to select data from few documents and output in nested arrays.
Aggregate:
$aggBuilder = $this->documentManager->getDocumentCollection(User::class);
$outputData = $aggBuilder->aggregate([
['$match' => [
'_id' => ['$in' => $usersId]
]
],
['$unwind' => '$articles'],
['$lookup' => [
'from' => 'articles',
'localField' => 'articles._id',
'foreignField' => '_id',
'as' => 'article',
]],
['$unwind' => '$article'],
['$lookup' => [
'from' => 'comments',
'localField' => 'comments._id',
'foreignField' => 'article_id',
'as' => 'article.comment'
]],
['$group' => [
'_id' => [
'id' => '$_id',
'name' => '$name',
'desc' => '$desc',
],
'articles' => ['$addToSet' => [
'id' => '$article._id',
'title' => '$article.title',
'content' => '$article.content',
'comments' => ['id' => $article.comment.id', 'content' => '$article.comment.content'],
]],
]]
],
[
'cursor' => [
'batchSize' => 101,
],
]);
dd($outputData->toArray());
The problem is in part where I try to in every article get collection of comments for this article.
Some reason output looks this:
'Andy Jones' = [
'Article First' = [
'id' = 'sdgdf76g8df',
'title' = 'First Article'
'content' = 'Contetn of article'
'comments' = [
'id' = [
'dfdh54gdfter',
'32gdfhfgh43et',
'34te3gdfgerdt'
],
'content' = [
'content for first article',
'content for second article',
'content for third article'
]
]
]
]
As you see comments are splited in two arrays. One for 'id' and one for 'content'.
What I want is separate array for every comment and in that array data from single comment. Like bellow:
'comments' = [
[0] = [
'id' = 'dfdh54gdfter',
'content' = 'Lorem ipsum 1',
],
[1] = [
'id' = 'dfdg4554er',
'content' = 'Lorem ipsum 2',
],
[2] = [
'id' = 'dfdh54gdfter',
'content' = 'Lorem ipsum 3',
],
]
Thank you.

$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

MongoDB query $lookup with prefix

I have two collection rounds and summaries
A record in rounds looks like
{
"_id": "2018-04",
"name": "Round 2018-04"
}
A record in summaries look like
{
"phase": "round:2018-04",
"userId": NumberLong(66325),
}
I want to query summaries and lookup into rounds joining based on phase of summaries into _id of rounds
PROBLEM: It will be pretty simple if there was no prefix of round: in phase.
Is there anyway to do this?
This is my code so far.
$cursor = $this->mongo->selectCollection('summaries')->aggregate([
array('$match' => []),
array(
'$lookup' => [
'from' => 'rounds',
'localField' => 'phase',
'foreignField' => '_id',
'as' => 'roundDetail'
]
),
array(
'$unwind' => '$roundDetail',
),
array(
'$project' => [
'userId' => 1,
'roundDetail.name' => 1
]
)
]);
MongoDB version 3.4.16
You can use substrBytes to remove characters from the string.
$cursor = $this->mongo->selectCollection('summaries')->aggregate([
array('$match' => []),
array('$addFields' => [ 'phase' => [ '$substrBytes' => [ '$phase', 6, 7 ] ] ] ),
array(
'$lookup' => [
'from' => 'rounds',
'localField' => 'phase',
'foreignField' => '_id',
'as' => 'roundDetail'
]
),
array(
'$unwind' => '$roundDetail',
),
array(
'$project' => [
'userId' => 1,
'roundDetail.name' => 1
]
)
])

MongoDB count with queries

I've been working on a project that now needs to use the MongoDB count function (MySQL equivalent's count function). The code I have at the moment is
$filter = ["username" => array('$ne' => null, '$ne' => '')];
$options = ["projection" => ['username' => true]];
$query = new MongoDB\Driver\Query($filter, $options);
$cursor = $mongo->executeQuery('mongodbLog.logs', $query);
I want to add the count functionality in the $filter array, but I can't get it to work correctly.
I want my MongoDB query to get the same result as this MySQL query: "SELECT username,count(*) FROM mysqlLog WHERE username <> '' GROUP BY username".
All I have managed so far is the where clause equivalent and now I'm stuck.
You can try the below aggregation.
Aggregation Stages - $match - $group - $project
$pipeline =
[
[
'$match' =>
[
'$and' =>
[
['username' => ['$ne' => null]],
['username' => ['$ne' => '']],
],
],
],
[
'$group' =>
[
'_id' => '$username',
'count' => ['$sum' => 1],
],
],
[
'$project' =>
[
'_id' => 0,
'username' => 1,
'count' => 1,
],
],
];
$command = new \MongoDB\Driver\Command([
'aggregate' => 'logs',
'pipeline' => $pipeline
]);
$cursor = $mongo->executeCommand('mongodbLog', $command);