This is in response to someone asking for possible interfaces for building complex and/or queries.
Years ago I worked on a program called “BugLink,” and it had an interface for building complex and/or queries. The user interface worked like this:
When you first opened the application, the top of the screen had a search field that looked like this:
The idea is simple: there is a field selector which selects a pre-defined field from a pop-down menu. There is an operator selector which picks from a list of predefined operators from a pop-down menu–and the type of operators change depending on the type of field. (For example, strings may include a “is substring of” operator that a number field does not.) And “value” can either be a pop-down for booleans (true/false), or an edit field or selector allowing you to enter a value. (If you allow dates, then tapping on the value field may bring up a calendar picker.)
Now if you clicked “Add Field”, you get a new row. But you also get a new column, associated only with the first row in the list of rows: the operator you wish to apply to the list of fields.
The idea here is that now, you can pick how you want the rows to work: do you want all of them to be true before the query works? Or do you want any of them to be true?
As before you can set the value of each of the rows–the field, operator and value. And fields can repeat; that allows you to search in a date range.
You can of course add more rows:
And you can also selet rows:
Now here’s where the magic happens. You can also “group” and “ungroup” rows. When you do this, the selected rows indent to the right, and a new boolean operator appears:
This allows you to create complex queries.
Naturally you need to be able to handle a bunch of fringe cases. For example, you need to decide how to handle grouping at multiple levels. (One possibility is to simply disable group and ungroup. Another is to pick an item–the first selected item or the deepest item–and move everything else into a group under that item, regardless of position in the tree.)
And you need to be able to handle other fringe cases that seem odd at first, such as having the same operator at different group levels:
and having only one item in a group:
But aside from handling the fringe case of grouping and ungrouping items that may be scattered across the query, there really are no fringe cases that can occur.
Further, I liked this user interface because it progressively reveals itself. The simplest query has no boolean operator. Adding a new row gives you a new option. And grouping and ungrouping reveals further complexity. (Of course you need a way to signal that queries can be grouped or ungrouped–one could handle this by showing a button that allows grouping or ungrouping. You can also explain there is a right-click pop-over menu that will show up–but I’ve never cared for pop-over menus because there is often nothing that suggests to the user that one could show up.)
But this was a fairly good interface for handling building complex boolean queries–and while it lacks a ‘not’ operator, one could theoretically add that to the operator pop-ups with a little extra work and a little extra consideration about how the user interface is to work. (For example, you could add “not” to the boolean popup if there is only one row in the group–or add a ‘not and’ and ‘not or’ if there are two or more items in that group.)