I am new to Core Data and am attempting something which seems to be simple but is elusive to me.
Entity: Person
Attribute: First Name
I would like to fetch all First Name attributes but only have each one show once. That means that if "Peter" exists 5 times it would only be fetched once.
I could fetch all "First Name" attributes and then iterate through it and compare all first names but this seems so clumsy. Is there a faster, more elegant way?
Coredata provide a property to get distinct Results. Use as below:
request.returnsDistinctResults = true
Related
This question already has answers here:
Swift 3. NSFetchRequest propertiesToFetch
(2 answers)
Closed 4 years ago.
I just need to fetch values of a single attribute from an entity and do not need to fetch all the attributes unnecessarily. To achieve this I have tried using 'propertiesToFetch' property with my fetch request, but it seems to return all the attribute values for the entity.
Say, I have an entity named 'Person' which has attributes 'name', 'age', 'height', 'weight'. Now I need to get only the height values. My fetch request is as below
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Person")
request.propertiesToFetch = ["height"]
Now when I retrieve the values, I expect name, age, weight for each person be nil, and all persons have only height values.
But it's not that way, and I can still see the values for name, age, the weight which seems to me that all the properties are trying to be fetched which I want to avoid.
The above is just an example. As I am dealing with enormous data, I am trying to optimize the fetch time by picking up only the necessary values wherever possible.
Can someone please point out what I am missing here to make it proper?
I you have a large amount of data in you Entity and you don't want to load it into memory every time the object is faulted the solution is to use relationships. Generally the large amount of data is a single property (imageData, or something similar), and can be changed to a one-to-one relationship with an entity with a single property. This will allow you to assess the data just as easily (i.e. myObject.dataHolder.data instead of myObject.data), but you can't search or sort by it. You can do the same things for all properties that you don't need to search or sort by, but unless those properties are very large I don't see a big return on that.
As pointed out in the comments, propertiesToFetch is only for dictionaryResultType and is generally not a good solution for most applications where a managedObject subclass is needed.
I have 20k unique labels that each have their own Entity with their own title.
What is the quickest way to get access to an Entity, given its title?
I know this can be done using a predicate, like so
fetch.predicate = NSPredicate(format: "title contains %#", "example title")
My issue with this approach is that it involves searching through every single one of the 20k Entities until the right one is found.
Is there a way to do this where all the titles are somehow indexed, and I can instantly get access to any label? Similar to how you can instantly get access to an item in an associative array, with array['item_name'].
Thanks.
Using a predicate is how you do it with Core Data.
Before you do anything, is this actually a problem? You don't mention that you've seen any performance issues. Are you having any, or is this still a theoretical problem?
You might improve performance by making sure that the "Indexed" box is checked for this attribute in the Core Data model editor. You might also consider adding a field to your entity that would contain a numeric hash of the title, and fetching based on the hash. You'd still be searching every entity but you'd be doing numeric comparisons instead of strings. You wouldn't be able to do substring searches (as your use of contains implies) but you would be doing the same thing as an associative array (which is also called a hash, for exactly this reason).
If none of that works well enough and you're searching strings very frequently, you'll need to investigate a different data model more suited to your needs-- like building a trie structure for fast searching.
Is it possible in realm to query for objects that have the same property value?
Imagine a list of contacts with firstname and lastname. I want to query all contacts that have the same name and may be duplicates in the db.
As far as I'm aware, there's no automatic way to do that with NSPredicate (Of which Realm implements); it would need to be done manually.
That being said, it should be relatively trivial to do manually; simply loop through each object, performing a query that searches for that object's name properties, and see if the number of results returned is greater than 1.
That being said, depending on how big your data set is, this could become a very slow operation very quickly. Ideally, you might be better off ensuring that duplicate entries don't occur, or if they do, to somehow index them so they're easier to look up.
I am using Parse as the backend for an app I'm working on. I was wondering if there is an optimal algorithm to query for only 'unseen' new objects.
What I am planning on doing is something like adding a user to the viewed object's relation and later querying all objects to check for the absence of the user. This seems to be O(n* all users who have seen an 'n') complexity which is a bit too much.
Another way to do this is to add the object to a user's key 'seen' and to then query for all objects the user has not seen.
Maybe a much more efficient way could be (assuming I view these objects chronologically) is to mark the first and last objects I see, and only show ones before or after those points using the createdAt key. Then I guess to show new objects outward from those points to not have to divide into multiple queries.
Ideally I'd like to shuffle through the objects, but I also would like to keep this algorithm as efficient as possible.
Create a Class called View. Each View consists of a unique identifier from a viewable Object (CANNOT BE THE OBJECTID) and a pointer to the User that viewed the object.
Your query should be:
//(Simple equalTo query)
Query1 = All View Objects where User pointer = User
//(whereKey:that-unique-id-column doesNotMatchKey:that-unique-id-column inQuery:Query1)
Query2 = All viewable Objects where not included in pointers in Query1
I have an NSFetchResultsController initialised with an NSSortDescriptor that sorts according to the localizedCaseInsensitiveCompare: method.
Entities are sorted on their last name, however some of them don't specify their last name and hence, the char 170 (in ASCII) is set as their last name (don't ask me why, the source code is done that way and I rather don't change it). When sorted, these persons "without last name" are displayed at the top of the table view. I would like them to be at the end of it.
Seems that it is not possible to use specific NSSortDescriptor in my case (i'm using a FRC), what are my options here ?
[EDIT]
Comparator blocks or custom comparator methods won't work with NSFetchResultsController
Your options are limited as the sort descriptor needs to be able to work with an SQLite data store.
You should edit the data model so you have an attribute that you can sort on. Exactly how you calculate the value is up to you, but the attribute can't be temporary. I would suggest that you either:
Implement willSave in your NSManagedObject subclass to create / update the sort data
Or, make your sort data a dependent key (using KVO, again in your NSManagedObject subclass)
Your sort data could be as simple as:
self.sortValue = (self.lastName == 170 in ASCII ? #"ZZZZZZZZZZZZZZZ" : lastName)