Anteris-Dev / autotask-client

An HTTP client for the Autotask API built with PHP.
MIT License
22 stars 15 forks source link

Combine multiple or statements in ticket query? #50

Closed JasonEde closed 2 years ago

JasonEde commented 2 years ago

I'm trying to combine multiple or statements into a single ticket query

I have a list of ticket numbers which I'm looping through to add to a query of ticket numbers. What is the best way to do this?

I've tried multiple query statements, but when I try a get I just seem to end up with info on last ticket number not all of them.

i.e. below line called multiple times

$client->tickets()->query()->where('ticketNumber','eq',$ticketnum);

I can potentially have several hundred ticket numbers in the request.

aidan-casey commented 2 years ago

Hey @JasonEde! See this section in the README. Basically you need to pass a callback to the orWhere method and perform your where calls within that.

JasonEde commented 2 years ago

Hi, I'd seen that. I was struggling to get it to loop through and use that to add to the query

JasonEde commented 2 years ago

So far I've got it working as long as I limit the number of items on each call otherwise I get a guzzle error

$at_tickets=$client->tickets()->query()->orWhere(function ($q) use ($tickets) { foreach (array_slice($tickets,0,9) as $ticketnum => $ticket) { $q=$q->where('ticketNumber','eq',$ticketnum); } return $q; })->get();

Need to work out how to get it to loop for all in neat way

JasonEde commented 2 years ago

Although it looks really ugly this works... $querylimit is number of items in each get

$ctr=0;

while ($ctr< sizeof($tickets)) {

$at_tickets=$client->tickets()->query()->orWhere(function ($q) use ($tickets,&$ctr,$querylimit) {
        foreach (array_slice($tickets,$ctr,$querylimit) as $ticketnum => $ticket) {
                $q=$q->where('ticketNumber','eq',$ticketnum);
                $ctr++;
        }
        return $q;
 })->get();

}
aidan-casey commented 2 years ago

You might try something like the code below. You may have to revise it a bit since I'm not aware of your code context.

$queryLimit = 50;
$chunks = array_chunk($tickets, $queryLimit);

foreach ($chunks as $chunk) {
    $ticketNumbers = array_keys($chunk);

    $atTickets = $client
        ->tickets()
        ->query()
        ->where('ticketNumber', 'in', $ticketNumbers)
        ->get();
}
JasonEde commented 2 years ago

That did it great thanks. Needed to add true to the array_chunk to preserve the key, but worked a treat.

aidan-casey commented 2 years ago

Awesome! Hopefully, that's a little cleaner for you. 🙂

JasonEde commented 2 years ago

yes, and it's about 3x as fast as what I had originally :)

aidan-casey commented 2 years ago

yes, and it's about 3x as fast as what I had originally :)

Even better! You could probably play with that query limit, you may even be able to pass all the ticket numbers at once when using in. Not sure what Guzzle error you were getting, but I suspect it was related to a limit on the URL size.

JasonEde commented 2 years ago

It looks like it was the size of the URL which is why I'd played with that limit to drop to 15 originally. I'll see if can put higher.