ObjectBox dynamic queries - flutter

e.g. the end user makes selections from two of five possible filters, the last three filters being left as ‘all’.
Rather than me creating queries for every possible combination of the 5 filters (25 different queries in total), what is the most efficient syntax for handling this?
Should I use .and to chain the queries together, and then can I specify ‘all’ for any which are not required?

A query builder can be used to build the query according to the selected filters. That is adding query criteria only using inside if conditions checking for the the filters.

I solved this as follows. Use a ternary operator ?: and in the second condition query one of the values with .notNull()
This gives the result of 'all', effectively ignoring this part of the query.
This is a hack, but it works. It is obviously an expensive solution, as the ideal would be to skip over unwanted filters completely.
Note to developer: 'if' cannot be used within query structure in dart. Thanks for finding time to respond, hopefully my additional info helps.

Related

In ObjectBox for Flutter, is there a way to compare two properties?

I'm new to using ObjectBox, so I've been trying to do some experimenting with its query system to familarize myself with it. One of the queries I've been unable to do is a query comparing two properties. Ignoring the errors they throw, these are some examples of what I'm looking to do:
// Get objects where first number is bigger than second number
boxA.query(ObjectA_.firstNumber.greaterThan(ObjectA_.secondNumber))
// Get parent objects where one of its children has a specific value from the parent
parentBox.query().linkMany(ParentObject_.children, ChildObject_.name.equals(ParentObject_.favoriteChild));
I know based on this question that it's possible in Java using filters, but I also know that query filters are not in ObjectBox for Dart. One of the workaround I've been testing is querying for one property, getting the values, and using each value to query for the second property. But that becomes unsustainable at even moderately sized amounts of data.
If anyone knows of a "proper" way to do this without the use of Java filters, that would be appreciated. Otherwise, if there's a more performant workaround than the one I came up with, that would be great too.
There is no query filter API for Dart in ObjectBox, because Dart already has the where API.
E.g. for a result list write results.where((a) => a.firstNumber >= a.secondNumber).

Flutter/Supabase stream filters - why the one field filter limit?

Using the "flutter_supabase" package, I've been trying to add a dynamic filtered stream to my Flutter app, and have found that an exception is thrown if more than filter is applied.
Why the one field limit? Is there any way around this?
In my case, I want to apply two filter fields to the stream, and the exact fields are applied dynamically based on user selections.
Supabase has advised that this is limit set by their real time streaming layer.
Work arounds to solve this:
a). Build logical views to represent the different filters
b). add a 'where' clause to the stream results and filter at the client end

When should I use startAt, endAt and when range where?

I want to query data between two values.
should I use
collection
.where("value",">=",'start')
.where("value","<=",'end')
or
collection
.orderBy('value')
.startAt('start')
.endAt('end')
is there any difference at all?
In practice, for a single query, probably not going to make much difference. However, using startAt and endAt is typically only used for pagination. So it might be confusing for the reader of your code to see those methods if you aren't actually doing any pagination. The first example is more clear for single queries.

SQL Server Execution Plans and Expanded Views

I'm attempting to use the Execution Plan XML to analyse dynamic SQL statements, specifically to determine whether or not it's referencing a non indexed view. The hope is to systematically navigate the XML via XPath within a separate C# project.
However it would seem that by default the SQL statement gets expanded to the constituent tables prior to the QEP being generated, and as such it doesn't include a reference to the view. (I'd like to avoid having to rely upon a string based search of the Statement Text)
Is there an option by which I can expand the XML plan to include the view expansion, or is there an alternative approach I might want to consider?
Thanks.
When the query execution plan is constructed, it goes through three phases - parsing, binding and optimization. In binding phase non indexed views are replaced with their definition and in optimization phase unused columns of the view are removed. So in the final execution plan there is nothing left from the view itself. This isn't true when NOEXPAND hint is specified in the query, which is the only case when you can find the view in the execution plan. But this require changes in the queries, which may not be an option in your case.
If you want to search for views usage in your queries, probably you should try to get the query text returned from sys.dm_exec_sql_text and search there (which isn't trivial though, because VIEW$SOMETHING will be found in the query referencing VIEW$SOMETHING_ELSE).

How to search for multiple tags around one location?

I'm trying to figure out what's the best solution to find all nodes of certain types around a given GPS-Location.
Let's say I want to get all cafes, pubs, restaurant and parks around a given point X.xx,Y.yy.
[out:json];(node[amenity][leisure](around:500,52.2740711,10.5222147););out;
This returns nothing because I think it searches for nodes that are both, amenity and leisure which is not possible.
[out:json];(node[amenity or leisure](around:500,52.2740711,10.5222147););out;
[out:json];(node[amenity,leisure](around:500,52.2740711,10.5222147););out;
[out:json];(node[amenity;leisure](around:500,52.2740711,10.5222147););out;
[out:json];(node[amenity|leisure](around:500,52.2740711,10.5222147););out;
[out:json];(node[amenity]|[leisure](around:500,52.2740711,10.5222147););out;
[out:json];(node[amenity],[leisure](around:500,52.2740711,10.5222147););out;
[out:json];(node[amenity];[leisure](around:500,52.2740711,10.5222147););out;
These solutions result in an error (400: Bad Request)
The only working solution I found is the following one which results in really long queries
[out:json];(node[amenity=cafe](around:500,52.2740711,10.5222147);node[leisure=park](around:500,52.2740711,10.5222147);node[amenity=pub](around:500,52.2740711,10.5222147);node[amenity=restaurant](around:500,52.2740711,10.5222147););out;
Isn't there an easier solution without multiple "around" statements?
EDIT:
Found This on which is a little bit shorter. But still multiple "around" statements.
[out:json];(node["leisure"~"park"](around:400,52.2784715,10.5249662);node["ameni‌​ty"~"cafe|pub|restaurant"](around:400,52.2784715,10.5249662););out;
What you're probably looking for is regular expression support for keys (not only values).
Here's an example based on your query above:
[out:json];
node[~"^(amenity|leisure)$"~"."](around:500,52.2740711,10.5222147);
out;
NB: Since version 0.7.54 (released in Q1/2017) Overpass API also supports filter criteria with 'or' conditions. See this example on how to use this new (if: ) filter.