Forum Discussion

Dave_Lee's avatar
Dave_Lee
Icon for Advisor rankAdvisor
2 years ago

API Filtering

Hi all

I’m hoping someone might be able to steer me in the right direction!

I’m trying to put together a filter to pull back devices that have:

  • system.azure.tag.environment = production
  • system.azure.tag.environment = prod
  • or have no system.azure.tag.environment at all

I’ve put this together so far:

systemProperties:"{\"name\":\"system.azure.tag.environment\",\"value\":\"Production\"}"|
"{\"name\":\"system.azure.tag.environment\",\"value\":\"Prod\"}"|
"{\"name\":\"system.azure.tag.environment\",\"value\":::empty}"

Which is accepted but it only pulls back devices where environment=Production or Prod.  I think the issues with :::empty is that it only works if the system property system.azure.tag.environment exists, which it won’t if it’s not set to anything.

I was hoping I might be able to do something like this, but this isn’t accepted….

systemProperties:"{\"name\":\"system.azure.tag.environment\",\"value\":\"Production\"}"|
"{\"name\":\"system.azure.tag.environment\",\"value\":\"Prod\"}" ||
systemProperties!~"{\"name\":\"system.azure.tag.environment\",\"value\":\"*\"}"

Any ideas?


 

  • Anonymous's avatar
    Anonymous

    The second one might not work because you have two || at the end of that statement. I’ve not seen the | statement work in the advanced queries though. But i haven’t proven to myself that they don’t work either. Any reason you can’t just make two calls and combine them after you’ve fetched them?

  • That’s a fair point!

    I should really have another look at the function I wrote for making the API calls.  I originally wrote that when my queries were pulling back much smaller result sets.  It’s a shared functions in a larger module so I’ve resisted the temptation to modify it too much.  I am now to the point where I’m building the logic to deal with pages into a couple of other pieces of code, so about time I built that into my API calling function instead.

    Dave

  • Anonymous's avatar
    Anonymous

    No, i mean, separate your filter into two filters. Instead of pulling back everything and filtering locally, use the filters, but instead of making one call with a really complex, non-working filter, make one call to grab just the objects that match criteria1, then another call to grab the objects that match criteria2, etc. That way you are only calling what you want. Your API calls should be in a function that handles the pagination.

  • I’m making the API calls from PowerShell, so ended up doing the filtering there.  It’s obviously not as efficient as it could be, as I’m retrieving things I don’t actually need from the LM API, but I couldn’t find a way to make it work otherwise.

    So I do my query, then loop through each page of results, then filter it as below and process just the items that pass the filter:

        $filteredDevices = $devices.items | Where-Object {

            ($_ | Select -ExpandProperty systemProperties | where-object {$_.name -eq "system.azure.tag.environment"}).value -in $prodTagValues -OR

            ($_ | Select -ExpandProperty systemProperties | where-object {$_.name -eq "system.azure.tag.environment"}).length -eq 0

        }

  • Anonymous's avatar
    Anonymous

    Any reason you can’t just make two calls and combine them after you’ve fetched them?

  • Any reason you can’t just make two calls and combine them after you’ve fetched them?

    The calls I’m making return quite a lot of results so I’d have multiple pages of results.  I had already written the code around pulling the result set, then processing each page at a time. It would have been a bit of a pain to refactor it to page through all the results, store it locally and then loop through it all.  I might consider doing that in future though.

    Dave