I am having problem in getting data from doctrine object. When I use findOne(id) and try to access any variable like $result->getVariable() it works fine. But as soon as I use doctrine query builder and add some conditions, it says
Attempted to call method "getVariable" on class "Doctrine\ORM\QueryBuilder....
My Code is
foreach ($Ids as $Id) {
$result = $em->createQueryBuilder()->select("s")
->from("Entity", "s")
->where('s.id = :s_id')
->setParameters(array('s_id'=>$Id));
if($category)
{
$result->innerJoin('s.cat','c');
$result->where("c.primaryClassification = :category");
result->setParameter('category',$category);
}
}
The Code which is working is
foreach ($Ids as $Id) {
$em->getRepository("Entity")->findOneById($Id);
}
I think it is the difference in data returned because of different types of methods used.
Thanks in advance!
That's because the QueryBuilder is only for that, to build querys (BA-DUM-TSS).
What you need is to execute the query after you build it and set the parameter correctly for a =:
foreach ($Ids as $Id) {
$query[] = $em->createQueryBuilder()->select("s")
->from("Entity", "s")
->where('s.id = :s_id')
->setParameter('s_id', $Id))
->getQuery()
->getResult();
}
also if you are looking for an array of data, is BEST if you use the IN statement without the foreach and pass the array directly to the setParameter:
$result = $em->createQueryBuilder()->select("s")
->from("Entity", "s")
->where('s.id IN (:s_id)')
->setParameter('s_id', $Ids)
->getQuery
->getResult();
If you need more info on the query builder check the docs.
Related
I am querying Item using following:
$itemdata = Item::with('itemimagedetails')
->with('variation')
->select('item.id', 'item.cat_id', 'item.item_name', 'item.item_description', 'item.brand', 'item.manufacturer', 'item.country_origin', 'item.ingredient_type', 'item.delivery_time', 'categories.category_name', 'item.category_unit')
->join('categories','item.cat_id','=','categories.id')
->where('item.id', $request['item_id'])->get()->first();
I want to filter variations using planid fetched from user table.
$plan = User::where('id', $request['user_id'])
I have tried:
if (count($itemdata->variation) > 0) {
$plan = User::where('id', $request['user_id'])->get();
foreach ($itemdata->variation as $key => $tag_name) {
if($tag_name == $plan['plan_id']) {
unset($itemdata->variation[$key]);
}
}
}
But then I get an error in the API calls.
Can someone please suggest best approach?
try using "having" statement search it in in laravel docs
I am trying to run a foreach loop to query data within a json data column in my DB. I believe the foreach code is correct, but I cant retrieve data using the loop. I trying to use eloquent queries if possible.
Data stored in column named 'figuresinorder' : ["1","22","2","45"]
$items = ['1', '2', '3'];
$figures3 = customtrades::where(function ($query) use ($items) {
foreach($items as $item) {
$query->whereJsonContains('figuresinorder', "$item");
}
})
->get();
First try to remove the " surrounding $item,
$query->whereJsonContains('figuresinorder', $item);
If that doesn't work, try this instead:
$query->whereRaw('JSON_CONTAINS(figuresinorder, ?)', [$item]);
I have this script.
It fetch the rows from DB and choose the row which belongs to a Category(CatData).
getCatDatas() returns \Doctrine\Common\Collections\ArrayCollection() class.
So it can use contain() to check.
However I want to put this method in DQL itself, is there any practice??
$result = array();
$articles = $em->createQuery("SELECT a FROM DefaultBundle:ArticleData a ")
->getResult();
foreach ($articles as $a){// I want to put this function in DQL.
if ($a->getCatDatas()->contain($cat)){
array_push($articles,$result);
}
}
Yes, you can use DQL and do a where condition on relation.
You can find more info here: https://symfonycasts.com/screencast/symfony3-doctrine-relations/relation-query
In particular, the method findAllRecentNotesForGenus in GenusNoteRepository.
I think you can do something similar:
public function findPostsByCategoryData(CategoryData $cat)
{
return $this->createQueryBuilder('a')
->andWhere('a.catDatas = :cat')
->setParameter('cat', $cat)
->getQuery()
->execute();
}
#Alessandro Filira started in the right direction but forgot to take into account that this is a to-many relationship that you want to filter on.
Doctrine supports MEMBER OF operator, which works a bit like IN but in the opposite direction. It allows you to check if the specific value that you have is found as an element in the related group.
So the code should be like:
public function findPostsByCategoryData(CategoryData $cat): array
{
return $this->createQueryBuilder('a')
->andWhere(':cat MEMBER OF a.catDatas')
->setParameter('cat', $cat)
->getQuery()
->getResult();
}
See Doctrine Docs for MEMBER OF usage: https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/dql-doctrine-query-language.html (use Ctrl+F and "member of")
I found way to delete duplicate values in the result but it doesn't work correctly. How to fix it?
I have next code:
public function getListPositionByApplication($app_id){
// $app_id = \Request::input('app_id');
$list = SparePartApplicationPositionProvider::where('app_id',$app_id)->with(['provider','application_position'])->orderBy('apos_id')
->get();
$aa=0;
foreach ($list as $value) {
if($value->apos_id==$aa){
$value->application_position->name_detail='----';
}
$aa = $value->apos_id;
Log::info($value->apos_id);
}
return $list;
}
Log::info give next information: 26,26,26,26,26,26,27,27,27,27,27,27,28
but $value->application_position->name_detail have '----' in all cases with the exception of last value
#Hussein is right, group by the common column and don't do a foreach. Let the Eloquent DB do the heavy lifting. Notice the callback where you include your second table.
$list = SparePartApplicationPositionProvider::where('app_id',$app_id)
->with(['provider','application_position' => function ($query){
$query->groupBy('name_detail');
}])
->orderBy('apos_id')
->get();
You can try collection unique() method.
https://laravel.com/docs/master/collections#method-unique
Say I have a user object (which belongsToMany groups) and I'm doing a whereIn with an array of their respected ids like so:
whereIn('user_id', $group->users->modelKeys())
I need to, however, set a condition where I only pull data from each array item based on a condition of the group_user pivot table, "created_at" (which is basically a timestamp of when that user was added to the group).
So I need something like this:
whereIn('user_id', $group->users->modelKeys())->whereRaw('visits.created_at > group_user.created_at')
That doesn't work though because it's not doing the whereRaw for each array item but it's doing it once for the query as a whole. I might need to do something like a nested whereIn but not sure if that'll solve it either. Thoughts?
My full query as it is now:
$ids = $group->users->modelKeys();
return DB::table('visits')->whereIn('user_id', function($query) use ($ids) {
$query->select('user_id')->from('group_user')->whereIn('group_user.user_id', $ids)->whereRaw('visits.created_at > group_user.created_at');
})->sum("views");
Ok got it to work using nested loops instead:
$visits = DB::table('visits')->whereIn('user_id', $group->users->modelKeys())->get();
$sum = 0;
foreach($group->users as $user) {
foreach($visits as $visit) {
if($visit->user_id == $user->id) {
if($visit->created_at >= $user->pivot->created_at) {
$sum += $visit->views;
}
}
}
}
return $sum;
Would still like to see if it's possible to do it in a single query, no array looping.
Solved it! The foreach loop approach was making calls take waaaay too long. Some queries had over 100k records returning (that's a lot to loop through) causing the server to hang up. The answer is in part a big help from Dharmesh Patel with his 3rd edit approach. The only thing I had to do differently was add a where clause for the group_id.
Here's the final query (returns that 100k results query in milliseconds)
//Eager loading. Has overhead for large queries
//$ids = $group->users->modelKeys();
//No eager loading. More efficient
$ids = DB::table('group_user')->where('group_id', $group->id)->lists('user_id');
return DB::table('visits')->join('group_user', function ($query) use ($ids) {
$query->on('visits.user_id', '=', 'group_user.user_id')->on('visits.created_at', '>=', 'group_user.created_at');
})->whereIn('group_user.user_id', $ids)->where('group_id', $group->id)->sum('views');
Have you considered using a foreach?
$users = whereIn('user_id', $group->users->modelKeys());
foreach ($users as $user) {
// do your comparison here
}
I guess you need to use JOINS for this query, following code may take you in right direction:
$ids = $group->users->modelKeys();
return DB::table('visits')->join('group_user', function ($query) use ($ids) {
$query->on('visits.user_id', '=', 'group_user.user_id')
->whereIn('group_user.user_id', $ids)
->whereRaw('visits.created_at > group_user.created_at');
})->sum("views");
EDIT
$ids = $group->users->modelKeys();
return DB::table('visits')->join('group_user', function ($query) use ($ids) {
$query->on('visits.user_id', '=', 'group_user.user_id');
})->whereIn('group_user.user_id', $ids)
->whereRaw('visits.created_at > group_user.created_at')->sum("views");
EDIT
$ids = $group->users->modelKeys();
return DB::table('visits')->join('group_user', function ($query) use ($ids) {
$query->on('visits.user_id', '=', 'group_user.id') // group_user.id from group_user.user_id as per the loop
->on('visits.created_at', '>=', 'group_user.created_at');
})->whereIn('group_user.user_id', $ids)
->sum("views");