Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should filter values be connected by AND or OR? #35

Open
christophfriedrich opened this issue Sep 9, 2019 · 6 comments
Open

Should filter values be connected by AND or OR? #35

christophfriedrich opened this issue Sep 9, 2019 · 6 comments
Labels
Milestone

Comments

@christophfriedrich
Copy link
Collaborator

E.g. when selecting multiple output formats: Should the UI show the backends that support all or at least one of them?

Use Case for AND: User needs to feed the result into multiple systems that expect different formats -- e.g. the result is needed as a GeoJSON, but for a quick overview there should also be a rendered JPEG image.

Use Case for OR: User has a system that understands multiple formats and just inputs them all to check whether there's one that is supported (but doesn't really care which one it is) -- e.g. the result is needed as an image, but whether that's JPEG or PNG doesn't really matter.

So far I implemented it with AND, but while implementing "filter by API version" (see upcoming commit), I realised that OR might be just as reasonable.

🤔

christophfriedrich added a commit that referenced this issue Sep 9, 2019
Chose to connect the values with AND, because (so far) all others are connected by AND too -- but see issue #35.

Note that because api_versions is a value that differs *only across backends*, the line doesn't start with `backends.some`  but with `this.filters.apiVersions.every`.
@m-mohr
Copy link
Member

m-mohr commented Sep 9, 2019

Could you have a checkbox with label 'all' (=and) per criteria? I guess both use cases are valid and should be catered for... 🤔

Edit: 'all' might be understood as 'all available', not 'all selected'. So we may need a better label. Maybe 'any' (=or) is less confusing? Maybe you have a better idea, which is short and doesn't occupy too much space?

@christophfriedrich
Copy link
Collaborator Author

Such a checkbox is certainly possible, but rather untypical. It would make the UI a lot more technical. I was hoping there is another option? 🤔

If we go that way, I would suggest two radioboxes with "and" and "or" as labels?

Or a toggle like this?
grafik

@m-mohr
Copy link
Member

m-mohr commented Sep 10, 2019

I would hope there's one, but I couldn't find any yet.
I also thought about a toggle like that, but feel like and/or is even more technical than any/all. I don' have any proof though and would by happy with both using the toggle. The reason for proposing the checkbox was simply that it would take approx. half of the space.

@christophfriedrich christophfriedrich added this to the v0.4 milestone Sep 10, 2019
@m-mohr m-mohr modified the milestones: v0.4, v0.5 Dec 6, 2019
@m-mohr
Copy link
Member

m-mohr commented Jan 3, 2020

@christophfriedrich Could you document here what we have decided on for each field? I think we discussed and decided on AND / OR for each field depending on the most likely use-case, right?
Processes were likely AND, Collections OR, ...
Maybe we need this "switch" behavior only for a few selected fields or no fields at all? So a list with potential "switchable" fields would also be useful.

@christophfriedrich
Copy link
Collaborator Author

Exactly, we went through all the fields and guessed what would be the most common use case. This is what we decided:

  • API versions: OR
  • endpoints: AND
  • collections: OR
  • processes: AND
  • output formats: OR
  • service types: OR

This is documented with comments in the corresponding source code:

// APIVERSIONS (OR)
this.filters.apiVersions.length == 0 || backends.some(b => b.api_version && this.filters.apiVersions.some(v => (b.api_version).substr(0,3) == v)),
// EXCLUDEIFNOFREEPLAN
// exclude if *every* plan of *every* backend of the group is set to "paid=true" (more appropriate IMO)
!this.filters.excludeIfNoFreePlan || !backends.every(b => b.billing && Array.isArray(b.billing.plans) && b.billing.plans.every(p => p.paid == true)),
// include if at least one plan of the group *has* billing information and in there has a plan with "paid=false"
// !this.filters.excludeIfNoFreePlan || backends.some(b => b.billing && Array.isArray(b.billing.plans) && b.billing.plans.some(p => p.paid == false || p.name == 'free')),
// ENDPOINTS (AND)
this.filters.endpoints.length == 0 || backends.some(b => b.endpoints && this.filters.endpoints.every(e1 => b.endpoints.some(e2 =>
e2.methods.map(m => m.toLowerCase()).indexOf(e1.split(' ')[0]) != -1 && e2.path.toLowerCase().replace(/{[^}]*}/g, '{}') == e1.split(' ')[1]
))),
// COLLECTIONS (OR)
this.filters.collections.length == 0 || backends.some(b => b.collections && this.filters.collections.some(c1 => b.collections.some(c2 =>
c1.isSearchterm ? c1.matches.indexOf(c2.id || c2.name) != -1 : (c1.id || c1.name) == (c2.id || c2.name)
))),
// PROCESSES (AND)
this.filters.processes.length == 0 || backends.some(b => b.processes && this.filters.processes.every(p1 => b.processes.some(p2 =>
p1.isSearchterm ? p1.matches.indexOf(p2.id || p2.name) != -1 : (p1.id || p1.name) == (p2.id || p2.name)
))),
// OUTPUTFORMATS (OR)
this.filters.outputFormats.length == 0 || backends.some(b => b.outputFormats && this.filters.outputFormats.some(of => Object.keys(b.outputFormats.formats || b.outputFormats).indexOf(of.format) != -1)),
// SERVICETYPES (OR)
this.filters.serviceTypes.length == 0 || backends.some(b => b.serviceTypes && this.filters.serviceTypes.some(st => Object.keys(b.serviceTypes).indexOf(st.service) != -1))

IMO "potential switchable fields" are: collections, output formats, service types (because you may need more than 1 dataset for your calculations and may want to output in more than 1 format/to more than 1 service). Processes maaay be another candidate, but not really.

@m-mohr m-mohr modified the milestones: v0.5, v1.0 Feb 3, 2020
@christophfriedrich
Copy link
Collaborator Author

This issue can be found again one level deeper: When filtering for functionalities/endpoints, how should incomplete functionalities be treated? I.e. should the required endpoints within one functionality be combined with AND or OR (i.e. ALL or ANY OF)? I.e. should functionalities for which the SupportedFeatures component (from openeo-vue-component) displays a ⚠️ be filtered out or left in?

One could argue that if you select the functionality, you just want it to work -- not only half of it. On the other hand, half the functionality may bring you further than if it doesn't work at all, so you may want to see that backend in the result anyway.

In this decision it should also be considered how strict the featurelist.js file defines a "full" implementation of a functionality. E.g. when GET and POST are sufficient for "full" (as is the case at the moment of writing this) AND may be okay, but if PATCH is also required then OR could be more appropriate.

One could implement a switch for this too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants