Searching for Operating System in API query

Hello

No experience with the following. Would you be so kind to help me with this?

Is an API query, the following lines of relevance wok but need to include the search for only windows computer.
This is working

id of computers of it as string, name of computers of it, name of fixlet of it ) of results from (bes computers) whose (relevant flag of it) of (bes fixlets whose (exists cve id lists of it AND (cve id list of it as uppercase contains "CVE-2010-3190" OR cve id list of it as uppercase contains "CVE-2011-1280" OR cve id list of it as uppercase contains "CVE-2011-1977"))

So, I’ve tried with things like this but no success:

(id of computers of it as string, name of computers of it, name of fixlet of it) of results from (bes computers) whose (relevant flag of it AND (exists operating system of it AND (name of operating system of it as string as lowercase contains "win" as lowercase))) of (bes fixlets whose (exists cve id lists of it AND (cve id list of it as uppercase contains "CVE-2010-3190" OR cve id list of it as uppercase contains "CVE-2011-1280" OR cve id list of it as uppercase contains "CVE-2011-1977")))

(id of computers of it as string, name of computers of it, name of fixlet of it) of results from (bes computers) whose (relevant flag of it AND (name of operating system starts with "Win")) of (bes fixlets whose (exists cve id lists of it AND (cve id list of it as uppercase contains "CVE-2010-3190" OR cve id list of it as uppercase contains "CVE-2011-1280" OR cve id list of it as uppercase contains "CVE-2011-1977")))

I believe your first query attempt is very close…here it is in expanded form

(
 id of computers of it as string
 , name of computers of it
 , name of fixlet of it
) of results from (bes computers) whose (
  relevant flag of it 
  AND ( /* the 'computer' properties need to move inside the 'bes computers' selection */
   exists operating system of it 
   AND (name of operating system of it as string as lowercase contains "win" as lowercase)
   )
  ) of ( 
 bes fixlets whose (
   exists cve id lists of it 
   AND (
     cve id list of it as uppercase contains "CVE-2010-3190" 
     OR cve id list of it as uppercase contains "CVE-2011-1280" 
     OR cve id list of it as uppercase contains "CVE-2011-1977"
     )
 )
)

There are two pretty simple problems with the statement, and a much more complex efficiency problem. The first is where the filters are located, and the second is that on a ‘bes computer’ the ‘operating system’ property is just a string, there is no ‘name of operating system’ it’s just ‘operating system’.

The basic form of the statement

results from (bes computers) of (bes fixlets)

offers filtering in three places

results from (bes computers whose (computer filters)) whose (results filters) of (bes fixlets whose (fixlet filters) )

By moving the computer filter in yours, this statement is technically correct

(
     id of computers of it as string
     , name of computers of it
     , name of fixlet of it
    ) of results from (bes computers whose (operating system of it as lowercase contains "win" as lowercase)) whose (
      relevant flag of it 
      ) of ( 
     bes fixlets whose (
       exists cve id lists of it 
       AND (
         cve id list of it as uppercase contains "CVE-2010-3190" 
         OR cve id list of it as uppercase contains "CVE-2011-1280" 
         OR cve id list of it as uppercase contains "CVE-2011-1977"
         )
     )
    )

I say technically correct because, while it does work, it’s extremely inefficient. In my small lab it takes 14 seconds to get a bit over eight thousand results (when I expand the ‘cve list’ filter to pick up more fixlets). The reason for this is similar (but not identical) to the ‘cross product problem’ that brolly33 describes at Efficient Session Relevance Query for Computer Properties

What’s happening is that first the BES Fixlets are looked up - a scan across every fixlet that eventually retrieves the 37 fixlets that contain that CVE ID list.
Then, for the first fixlet, we scan for results from (bes computers whose (operating system of it as lowercase contains "win" as lowercase) of ( /* this fixlet */ ). This performs a full scan across every ‘bes computer’, finds the ones that have the Windows operating system, then retrieves the result for this computer and this fixlet, and filters out for only the results that have the ‘relevant flag’ set.
Because this scan repeats for every fixlet, the search of the BES Computer list and filter for the Windows ones repeats 37 times, once for each Fixlet,

A similar problem, better described at brolly33’s post I linked, comes up if we try to use

results (bes computers whose (SOME FILTER) , bes fixlets whose (SOME FILTER) )

In a tuple where each item (item 0, item 1) is plural, a cross-product is still created - for every ‘fixlet’, the ‘computer’ search is repeated.

The efficiency workaround for this is to create a set of the bes fixlets, so the scan & filtering of the fixlets is only performed once (to create the set); and the set, being a single ‘item’, does not trigger the ‘computer’ scan & filtering to be repeated. Likewise we create a set of bes computers, so the filtering on BES Computers is only performed once, and as the computer set is a single item, that also prevents the ‘fixlet’ set from being recreated multiple times. Then we expand the two sets so the already-filtered items can be compared in the ‘results (computer, fixlet)’ query.

Putting all of that together, and tweaking the ‘cve id list’ filter a bit for readability, I end up with

(
 id of computer of it as string
 , name of computer of it | "No Name Reported"
 , name of fixlet of it
) of (
 results (item 0 of it, item 1 of it) /* results (bes computer, bes fixlet) */
 ) whose ( relevant flag of it ) of  /* only keep the 'relevant' results */
 (
  elements of item 0 of it /* already-filtered bes computers */
  , elements of item 1 of it /* already-filtered bes fixlets */
 ) of 
 ( 
  set of bes computers whose (
        operating system of it as lowercase contains "win" as lowercase
        )
  , set of bes fixlets  whose (
        (
         it contains "CVE-2010-3190" 
         OR it contains "CVE-2011-1280" 
         OR it contains "CVE-2011-1977"
       )  of (cve id list of it as uppercase)
     )
 )

For an easier copy/paste, here’s the flattened form of that relevance

(id of computer of it as string , name of computer of it | "No Name Reported" , name of fixlet of it) of (results (item 0 of it, item 1 of it)) whose (relevant flag of it) of (elements of item 0 of it /* bes computers */ , elements of item 1 of it /* bes fixlets */) of (set of bes computers whose (operating system of it as lowercase contains "win" as lowercase) , set of bes fixlets whose ((it contains "CVE-2010-3190" OR it contains "CVE-2011-1280" OR it contains "CVE-2011-1977") of (cve id list of it as uppercase)))

On my system, that brings the query time down from 14 seconds to 758 milliseconds.

2 Likes