If I'd have the following table structure
ID name type
1 John Admin
2 Johan Admin
3 Sam User
4 Rick User
How would I use Laravels Eloquent with a groupBy query, but still grab each record, and also sum up per type how many records each type has?
Example result would be as follow
[
'type' => 'Admin',
'records' => 2
'data' => [
0 => [
'name' => 'John'
],
1 => [
'name' => 'Johan'
]
]
],
[
'type' => 'User',
'records' => 2
'data' => [
0 => [
'name' => 'Sam'
],
1 => [
'name' => 'Rick'
]
]
]
Since you are querying all the users you should be doing the grouping after the query instead of grouping in query like:
$users = User::all()->groupBy('type');
Then you can do:
foreach ($allUsers as $type => $users) {
$type; // 'Admin'
$users->count(); // Record Count
foreach ($users as $user) {
$user->name; //
}
}
If you want the data EXACTLY like your example then it would be:
User::all()
->groupBy('type')
->map(function($users, $type) {
return [
'type' => $type,
'records' => $users->count(),
'data' => $users->pluck('name')
];
})
->values();
I think the best way to achieve this is to have a table with types related through hasMany() to your data.
Then you can use standard Eloquent tools without restructuring the data manually:
$data = Type::with('users')->withCount('users')->get();
Also, you can use DB::select('select * from xxx group by yyy') to execute the query.
Related
I try to query my collection with only one query and 3 potentials search method:
fulltext search
classic search
search regex
This 3 matches can be executed at the same time or just one of them.
The fulltext search is the first stage pipeline as we know. Does this fulltext search can be optional in my aggregate? Because if my default value of search is "", my query returns any data. And I need data to perform my other optionals matches.
Here is my Laravel 8 controller :
Product::raw(function ($collection) use($filters, $fullText, $likeKey, $likeValue){
return $collection->aggregate([
[
'$match' =>
[
'$text' =>['$search' => $fullText],
],
],
[
'$match' => $filters
],
[
'$match' =>
[
$likeKey =>
[
'$regex' => $likeValue,
'$options' => "i"
]
]
],
[
'$addFields' =>
[
'avgReviews' => ['$avg' => '$reviews.ranking'],
'price' => ['$min' => '$variants.price'],
'equipmentsList' => [
'$reduce' => [
'input' => '$equipments.list.list',
'initialValue' => [],
'in' =>
[
'$concatArrays' => [
'$$value',
'$$this'
]
]
]
]
],
]
]);
})
->when($operations, function($products) use ($operations){
foreach($operations as $key => $operation){
return $products
->where($operation[0],$operation[1],$operation[2]);
}
})
->forPage($page,$limit)
->sortBy($sortBy, SORT_REGULAR, $order == 'desc')
->values();
$filters is an array and works fine when it's the only one match. But if I want to use $filters without $text, it returns any data. And with the third match, nothing works. Can somebody help me with this?
Good Afternoon,
I'm trying to create a Laravel factory where 2 of the 'columns' have the same values every time its called and the rest of the factory can be random.
For instance, I have the following columns in my DB
name
email
phone_number
status_message
status_code
I currently have my factory as follows;
$factory->define(Brand::class, function (Faker $faker) {
return [
'name' => $faker->unique()->company,
'email' => $faker->companyEmail,
'phone_number' => $faker->phoneNumber
];
});
This part works perfectly, as it should, the problem is that each specific status message comes with an individual status code. Is there a way I could add an array of status messages with a status code and have the factory pick a set at random for that record?
The status code / messages are listed below in array format;
[
'3e2s' => 'tangled web',
'29d7' => 'get certified',
'2r5g' => 'art of war',
]
I hope this makes sense. any help would be greatly appreciated.
as i can understand u need to pick random from this array u mentioned in above
$factory->define(Brand::class, function (Faker $faker) {
$data = [
'3e2s' => 'tangled web',
'29d7' => 'get certified',
'2r5g' => 'art of war',
];
$statusCode = array_rand($data);
$statusMessage = $data[$statusCode];
return [
'name' => $faker->unique()->company,
'email' => $faker->companyEmail,
'phone_number' => $faker->phoneNumber,
'status_message' => $statusMessage,
'status_code' => $statusCode,
];
});
Hello everyone am newly in laravel and i am trying to get data.using state ID please explain me with all Model with relationship each-other with example i have tables like this
1- states table
1- id
2-name
2- cities table
1- id
2-name
3- state_cities pivot table
1-id
2-sate_id
3-city_id
4- locations table
1-id
2-name
5- city_locations pivot table
1-id
2-city_id
3-location_id
6- pincodes table
1-id
2-pincode
7- location_pincodes table
1-id
2-location_id
3-pinecode_id
And this is my Controller
$states_with_cities = $states_with_cities->load(['cities.cityName','location.locationName'])->where('id',1)->get();
$states_with_cities->transform(function($states_with_cities) {
return [
'state_id' => $states_with_cities->id,
'state_name' => $states_with_cities->name,
'cities' => $states_with_cities->cities->map(function($cities,$location) {
return [
'city_id' => $cities->city_id,
'city_name' => $cities->cityName->name,
'location' => $location->locationName->map(function($locationName) use($location) {
return [
'location_id' => $location->location_id,
'location_name' => $locationName->locationName->name
];
})
];
}),
];
});
and that is error which is am geting
"message": "Trying to get property of non-object",
"exception": "ErrorException",
"file": "D:\\xampp\\htdocs\\samudaay-backend\\app\\Http\\Controllers\\API\\PincodeController.php",
"line": 32,
$states_with_cities = $states_with_cities->load(['cities.cityName','location.locationName'])->where('id',1)->get();
$states_with_cities->transform(function($states_with_cities) {
return [
'state_id' => $states_with_cities->id,
'state_name' => $states_with_cities->name,
'cities' => $states_with_cities->cities->map(function($cities,$location) {
// Location is the 'key' of the object in the collection. So it probably will be something like '0' or '1'.
return [
'city_id' => $cities->city_id,
'city_name' => $cities->cityName->name,
'location' => $location->locationName->map(function($locationName) use($location) {
//What you actually do here is: 0->locationName->map(...). This will result in your error
return [
'location_id' => $location->location_id,
'location_name' => $locationName->locationName->name
];
})
];
}),
];
});
$location in the first map function is the key of the object it is iterating at the moment. (see: https://laravel.com/docs/5.6/collections#method-map)
So on line 32 you are trying to call a property on the key variable (which will probably be '0' or '1' or something.) As that is not an object, it will result in the error you get.
Also, trying to map the locationName property is not going to work as expected. locationName is a property and not an eloquent collection.
You should probably try it like this:
'location' => [
'location_id' => $location->location_id,
'location_name' => $location->name
];
})
I can not use where in deeply nested associations.
I have tried in many ways, but in every case where I use where it doesn't take action
Actually, my case is like in Documentation
https://book.cakephp.org/3.0/en/orm/query-builder.html#using-innerjoinwith
What I have tried until now
$query = $itemTable
->find('all')
->contain(
[
'Products',
'ItemGroups',
'ItemGroups.FeaturesItemGroups.Features',
'Products.ProductCategories.ProductFractions',
'Products.ProductVessels',
'ItemCancellationReasons',
'Features',
'Users',
'Users.Groups',
'Orders',
'ItemPrices.ItemPricesBillingDocuments.RecyclerPrices.ProductFractions' => [
'conditions' => [
'ItemPricesBillingDocuments.id IS NOT NULL',
'ItemPricesBillingDocuments.billing_document_id' => $billingDocumentToRevert->id,
'ItemPricesBillingDocuments.billing_document_type_id' => BillingDocumentTypes::CREDIT_INDEX,
'ItemPricesBillingDocuments.active' => 1
]
]
]
);
Second example
->innerJoinWith(
'ItemPrices.ItemPricesBillingDocuments',
function ($q) use ($billingDocumentToRevert) {
return $q->where(
[
'ItemPricesBillingDocuments.id IS NOT NULL',
'ItemPricesBillingDocuments.billing_document_id' => $billingDocumentToRevert->id,
'ItemPricesBillingDocuments.billing_document_type_id' => BillingDocumentTypes::CREDIT_INDEX,
'ItemPricesBillingDocuments.active' => 1
]
)
->contain(['RecyclerPrices.ProductFractions']);
}
)
3.
$query->where([
'ItemPricesBillingDocuments.id IS NOT NULL',
'ItemPricesBillingDocuments.billing_document_id' => $billingDocumentToRevert->id,
'ItemPricesBillingDocuments.billing_document_type_id' => BillingDocumentTypes::CREDIT_INDEX,
'ItemPricesBillingDocuments.active !=' => false
]);
And as result in my debugging I am getting results where active flag is false.
Each relation from Items table is 1:many
ItemsPrices.ItemPricesBillingDocuments is also 1:many
Laravel 5 Eloquent sum of multiplied columns for mongo DB
This was my previous question and it got solved with the help of #Alex, now i need to add a where clause of $field != '0'
Here I am stuck I tried with the match but still I have no option left to get help from here.
Thanks
Using the aggregation pipeline where the $ne comparison query operator is in the $match pipeline:
DB::connection($this->MongoSchemaName)
->collection($this->InvoicesTable)
->raw(function($collection) use ($customer){
return $collection->aggregate([
['$match' => [
'ContactID' => (int)$customer->ContactID,
'Type' => 'PAYMENT',
'AmountDue' => [ '$ne' => 0 ]
]
],
['$group' => [
'_id' => '$ContactID',
'TotalInBaseCurrency' => [
'$sum' => ['$multiply' => ['$Total', '$CurrencyRate']]
]
]
]
]);
})