How to get distinct values from object's property with Drift (ex Moor); Flutter - flutter

TLDR: "SELECT DISTINCT category FROM items" efficiently in Drift
There is Item (or ItemsCompanion) data class that among others has 'String category' property. I'd like to get a list of distinct categories efficiently.
I'm failing to found a way
to get in result property of object without object itself
to filter out only unique values
Any help would be appreciated.
I can get a list of Items, iterate through and put it's categories in List, transform a List into a Set but it seems way too inefficient.

Using the answer from simolus3 https://stackoverflow.com/a/62359317/8108153
I got this:
Future<List<String>> getItemsCategories() {
final query = selectOnly(items, distinct: true)
..addColumns([items.category])
..where(items.category.isNotNull());
;
return query.map((row) => row.read(items.category)).get();
}
Whether it's the optimal approach or not yet it's way better anything I've come up with

Related

Filter out specific objects of Iterable list by specific property

I have an Iterable list that I am sorting by for different values. I want to add a new filter for users to filter out the list to just show a specific property the list contains. I am trying to use .where, but it does not seem to be working and I am not sure what to do. I have searched the web and see many examples on how to filter out just a plain list for a specific value in the objects with comparable but not able to get this to where for an Iterable list.
Here is what I am trying and not getting any results I would expect.
case 'specificValue':
return sorted.where((t) => t.state == 'speficicValue').toList();
Not sure if .where is the right way to filter out an Iterable list by a specific value within the objects of the list.
This was an issue with my new experience to Flutter and not knowing how too print. The list being filtered with .where was working but the list was so large it was hard to make sure it was showing up how I wanted. So printing it to the terminal I was able to look at the objects easier to validate the list was being filtered as I expected.

This function can only be invoked from LINQ to Entities. How can I solve this?

I can't figure out a way to overcome this, I'm trying to select one item on a dropdown list and on the next one show only the items associated to what I selected previously.
var xyz = ViewBag.ID_Cliente = new SelectList(db.Clientes, "ID", "Num_Cliente");
var results = from e in db.Extintores.AsEnumerable()
where SqlFunctions.StringConvert((double)e.ID_Cliente).Contains(xyz)
select e.Num_Extintor.ToList();
ViewBag.ID_Extintor = new SelectList(results);
Can someone help me?
Based on your desired action, I would suggest using the fluent Linq syntax and composing your query based on whether a selection has been made or not:
Your "xyz" variable is confusing, what is this meant to hold? From your description it sounds like you would want to have a list of clients, then select a Client ID and use that client ID to filter these Extintores.
var selectedClientId = ViewBag.SelectedClientId;
var results = db.Extintores;
if (selectedClientId != null)
results = results.Where(x => x.ID_Cliente == selectedClientId);
ViewBag.Id_Extintor = new SelectList(results.Select(x => x.Num_Extintor));
Frankly using ViewBag to relay state between view and controller isn't recommended. ViewBag is dynamic, so while it is flexible, it's difficult to assert that the state between requests will be reliable. Instead you should leverage a (view)model between calls. I would look to preserve the data type for your variables in the view bag as much as possible. The "list" of available items (SelectList) may be a SelectList of strings, but when one is selected, it can be parsed back to the appropriate data type rather than casting to strings in the Linq Queries. The big problem with that casting approach is that you forgo the use of indexes in your database. So if your ViewBag has a list of ID_Clients, selecting one client from that list should mark that one SelectedClient ID so we can use that to filter the next level. If you want to leverage a multi-select then you need to store a collection of IDs.

xamarin forms distinct objects sort based on the no of times that they appear

I have made an Xamarin forms application and the problem that I have a list named lista2 which has an object named poli. Poli is the city that it is located. I want to make a list based on distinct cities, which i have done using this command
var poleislist = lista2.Select(x => x.poli).Distinct();
now I want this poleislist to be sorted based on the amount of times that each element is on the lista2. For example the bigger cities appear more often and I want them in the first places of the list because this list(poleislist) is going to be the itemsource of a picker.
Thank you very much!
Instead of using Distinct you could Group the list, sort it by count descending then Select the poli.
It would be something like this:
var poleislist = lista2.GroupBy(item => item.poli)
.OrderByDescending(a => a.Count())
.Select(x => x.Key)
.ToList();
Note: sorry did not get to test it but this should work. Basically this should get you all the cities in the list, ordered descending by the number of times it appears.
Hope this helps.-

Sphinx Filtering based on categories using OR

I have the following text fields I search with Sphinx: Title, Description, keywords.
However, sometimes things are narrowed down using categories. We have 3 category fields: CatID1, CatID2 and CatID3.
So, for example, I need to see if the word "Kittens" is in the Title, Description, or Keywords, but I also want to filter so that only items that have the categories (Animals - ID Number 8) or (Pets - ID Number 9) or (Felines - Category ID Number 10) in either of those CatID fields.
To clarify, only show items that have a 8,9 or 10 in CatID1, 2 or 3.
Any ideas on how I would accomplish this using sphinx filtering or searching the CatID1 fields as keywords?
Note: I am able to filter and it works great only using one category, i.e:
if(!empty($cat_str)) {
$cl->SetFilter( 'catid1', array( $cat_str ));
}
Thanks!
Craig
SetFilter takes an array. In your example you are putting $cat_str into an array. A array of one item.
So you just needs to build array with all the ids.
$cl->SetFilter( 'catid', array( $cat1, $cat2, $cat3 ));
But thats not very flexible. So you probably build the array dynamically, rather than hard-coded like that. But thats upto your application how to build the array.
But also storing the ids, in three sperate attributes, makes it hard to search. Notice in the above example, just noticed a attribute called catid. This would be a single multi-value attribute, that contains the ids from all three cat fields. That way its easy to search for ids in ANY of the columns at once.
http://sphinxsearch.com/docs/current.html#mva
if using a sql source, could do with something like
sql_query = SELECT id, title ... , CONCAT_WS(',', CatID1, CatID2 and CatID3) as catid FROM ...
sql_attr_multi = uint catid from field;

How do I execute a subquery as an attribute using Core Data?

I have an entity named "Genre" that has attributes genreID and parentGenreID. I want to make a dynamic attribute that gives me the count of Genre entities where parentGenreID is equal to the row's genreID so that I don't have to query for the count for each returned row.
If I was doing this in SQL, I'd use the query:
SELECT g.title, (SELECT COUNT(*) FROM genres sg WHERE sg.parentGenreID = g.genreID) as subgenres FROM genres g
I was thinking perhaps a Fetched Property would be the answer, but those seem to be returned as NSArrays, and still I'm trying to figure out what the appropriate syntax would be.
My best guess is something like:
SUBQUERY(Genre, $genre, $genre.parentGenreID = $FETCH_SOURCE.genreID).#count
What would be the right way to do this in Core Data?
Using NSPredicate, you can put condition where parentGenreID=genreID. Instead of using executeFetchRequest,use countForFetchRequest to get the count and again use NSPredicate subgenres IN with executeFetchRequest which returns record that contains title as you expected.