Forum Discussion

mhashemi's avatar
4 years ago

API filter on multiple properties

I'm not seeing any way to return the devices I want, matching two property values.

 

Using a filter like this works: 'filter=systemProperties.value~"DeviceGroupName"'

 

But if I want only Exchange servers in the device group: 'filter=systemProperties.value~"DeviceGroupName",systemproperties.value~"Exchange"', does not return fewer devices.

 

Any way to do this in a single query?

  • 1 minute ago, mnagel said:

    Something that strikes me as I delve into this further is that filter syntax is largely undocumented.  There are examples in the legacy docs, nothing really in Swagger.  I have figured it out mostly via trial and error and the occasional support ticket. It is clear you can use AND logic with comma-separated components, but is is not clear if you can reference the same LHS multiple times.  The is really no indication you can implement OR via filter short of glob expression matching.  The only documentation I can find on filters specifically relate to limitations added for embedded special characters in the v2 API.  Perhaps the API team could document the various common parameters in Swagger or elsewhere?

     

    That'd be helpful. :)/emoticons/smile@2x.png 2x" title=":)" width="20" />

  • Anonymous's avatar
    Anonymous

    Why not just his this endpoint
    /device/groups/{id}/devices
    get immediate devices under group

  • I was thinking of was that the filter is not valid -- you cannot match only on values.  Well you can, but it is then detached from the property name and could match many properties.  You need to match on name and value together. 

    filter=customProperties.name:PROPNAME,customProperties.value:PROPVALUE

    The /device/groups idea is a good one if you are not matching on wildcards, like in this case (though you could use two passes to get an ID list, then iterate).  We have found the sometimes that is necessary due to lack of endpoints (e.g., there is no direct way to map a device datasource instance ID back to the datasource ID), but if you can use one query to do your work you should try to do so.

  • 45 minutes ago, Stuart Weenig said:

    Why not just his this endpoint
    /device/groups/{id}/devices
    get immediate devices under group

     

    Because I don't know where, in the group structure, the Exchange servers are located. For example, "Customer" could have "Location A" and "Location B" subgroups, each of which could have "Linux" and "Exchange" subgroups. Maybe they also have an Exchange server directly in the "Customer" folder. I could recursively search for subgroups, then for each one, use the endpoint you suggested, but that seems inefficient.

    30 minutes ago, mnagel said:

    I was thinking of was that the filter is not valid -- you cannot match only on values.  Well you can, but it is then detached from the property name and could match many properties.  You need to match on name and value together. 

    filter=customProperties.name:PROPNAME,customProperties.value:PROPVALUE

    The /device/groups idea is a good one if you are not matching on wildcards, like in this case (though you could use two passes to get an ID list, then iterate).  We have found the sometimes that is necessary due to lack of endpoints (e.g., there is no direct way to map a device datasource instance ID back to the datasource ID), but if you can use one query to do your work you should try to do so.

     

    This seems to work:

    filter=systemProperties.name:"system.staticgroups",systemProperties.value~"CustomerName",systemProperties.name:"system.categories",systemProperties.value~"IISServer"

     

    But what if I needed devices (in the CustomerName group) that had "category1" or "category" in system.categories? Both of the following filters returns zero results (in the portal right now, I am looking at one device that should be returned, but maybe there are more):

    filter=systemProperties.name:"system.staticgroups",systemProperties.value~"CustomerName",systemProperties.name:"system.categories",systemProperties.value~"category1",systemProperties.name:"system.categories",systemProperties.value~"category2"
    
    filter=systemProperties.name:"system.staticgroups",systemProperties.value~"CustomerName",systemProperties.name:"system.categories",systemProperties.value~"category1",systemProperties.value~"category2"

     

    Incidentally, while thinking of another example, I found that this works to give me 32-bit Windows servers with 3.75GB of memory (across all groups):

    filter=systemProperties.name:"system.systemtype",systemProperties.value~"x86-based PC",systemProperties.name:"system.sysinfo",systemProperties.value~"Windows",systemProperties.name:"system.totalphysicalmemory",systemProperties.value:"3.75GB"

     

  • Anonymous's avatar
    Anonymous
    6 minutes ago, mhashemi said:

    Because I don't know where, in the group structure, the Exchange servers are located. For example, "Customer" could have "Location A" and "Location B" subgroups, each of which could have "Linux" and "Exchange" subgroups. Maybe they also have an Exchange server directly in the "Customer" folder. I could recursively search for subgroups, then for each one, use the endpoint you suggested, but that seems inefficient.

    So create a dynamic group under "/Devices by Type" and query that group's membership from the API?

  • 23 minutes ago, Stuart Weenig said:

    So create a dynamic group under "/Devices by Type" and query that group's membership from the API?

     

    I'm trying to write something that will support various use cases without forcing the user down any particular path. If they want to create a dynamic group, that's fine, but it seems like we oughta be able to support filtering like this without resorting to mucking about in the portal (not everyone has Manage rights either).

  • Something that strikes me as I delve into this further is that filter syntax is largely undocumented.  There are examples in the legacy docs, nothing really in Swagger.  I have figured it out mostly via trial and error and the occasional support ticket. It is clear you can use AND logic with comma-separated components, but is is not clear if you can reference the same LHS multiple times.  The is really no indication you can implement OR via filter short of glob expression matching.  The only documentation I can find on filters specifically relate to limitations added for embedded special characters in the v2 API.  Perhaps the API team could document the various common parameters in Swagger or elsewhere?

  • I think I have just gotten used to full or partial table scans and then run all the complex bits on the client side.  Wasteful of resources and more time-intensive, but ya gotta do what ya gotta do.

  • Anonymous's avatar
    Anonymous
    21 minutes ago, mnagel said:

    Perhaps the API team could document the various common parameters in Swagger or elsewhere

    Agreed. We need every customer who wants this to request it through their CSM.

    13 minutes ago, mnagel said:

    I think I have just gotten used to full or partial table scans and then run all the complex bits on the client side.  Wasteful of resources and more time-intensive, but ya gotta do what ya gotta do.

    This is what i pretty much always do. The only time i put filtering on is to reduce the number of paging calls i have to do.