Possible to limit results returned by NSArray filteredArrayUsingPredicate - iphone

I'm using [NSArray filteredArrayUsingPredicate] to get an array of objects that match certain conditions within an original array of 20,000 objects. Is it possible to limit the number of results that this method returns in order to speed it up?
This would be similar to the LIMIT clause in SQL. Thanks.

No, with predicates not. But you could make an extension to NSArray which filters and limits the result for you.
- (NSArray*)filteredArrayUsingPredicate:(NSPredicate*)predicate
resultLimit:(NSUInteger)limit;

Related

Which sorting method is efficient among sorting using JPA order by or sorting using collection sort() method?

I have a table called 'userProfileEmployment'. It has a start_date col. which stores values in yyyy-mm-dd format. From this I have to fetch the list of employments in Asc order.
Now, I have two approaches for it
1. fetch directly sorted rows from DB through JPA query.
2. fetch the rows as it is from DB, store it in a List and then sort it using collection sort method
I am sharing Code for approach 1:-
List employmentList = userProfileEmploymentRepository.findAllByProfileIdSorted(userProfileId);
Snippet from UserProfileEmploymentRepository.java class:
#Query("select upe from UserProfileEmployment upe where upe.profileId = :profileId and (upe.deleted = 0 or upe.deleted is null) order by upe.startDate")
List<UserProfileEmployment> findAllByProfileIdSorted(#Param("profileId") Long profileId);
Now we get the sorted output from both approaches. So my question is which one of the two is better. Does sorting using the order by clause is more costly or sorting using collection sort method is more better
Sorting in DB is preferable than in-memory(i.e. Collections) in most of the cases.
Firstly because DB's sorting is always optimized to handle large data set and you can be even optimize it better by using indexes.
Secondly, if later you want to start returning paginated data(i.e. slice of whole data) then you can load only those slices by using pageable from DB and save heap memory.

Is it faster to use with_limit_and_skip=True when counting query results in pymongo

I'm doing a query where all I want to know if there is at least one row in the collection that matches the query, so I pass limit=1 to find(). All I care about is whether the count() of the returned cursor is > 0. Would it be faster to use count(with_limit_and_skip=True) or just count()? Intuitively it seems to me like I should pass with_limit_and_skip=True, because if there are a whole bunch of matching records then the count could stop at my limit of 1.
Maybe this merits an explanation of how limits and skips work under the covers in mongodb/pymongo.
Thanks!
Your intuition is correct. That's the whole point of the with_limit_and_skip flag.
With with_limit_and_skip=False, count() has to count all the matching documents, even if you use limit=1, which is pretty much guaranteed to be slower.
From the docs:
Returns the number of documents in the results set for this query. Does not take limit() and skip() into account by default - set with_limit_and_skip to True if that is the desired behavior.

What's the easiest way to return the results of a query for a given key/value pair in mongo as an array of the values returned?

I have a field called id (not _id) in documents from two collections. I need to compare the contents of the first collection with the second. Basically, I need to know what documents with a given value 'id' exist in collection 'A', but not 'B'. What's the easiest way to build an array of id's from Collection A that I can use to do something like the following. :
db.B.find({id:{$nin: array_of_ids_from_coll_A}})
Please don't get hung up over why I'm using 'id' in this case, and not '_id'. Thanks.
Strictly speaking, this doesn't answer the question of 'how to build an array that...', but I'd iterate over collection A and, for each element, try to find a match in B. If none is found, add to a list.
This has a lot of roundtrips to the database, so it's not very fast, but it's very simple. Also, if A contains a lot of elements, the array of ids might be too large to throw all of them in the $nin, which otherwise would have to be solved by splitting up the array of ids. To make matters worse, $nin isn't efficient with indexes anyway.
I incorrectly assumed that the function 'distinct' returned a set of distinct documents based on a given 'field'. In fact, it returns an array of distinct values, provided a specific field. So, I was able to construct the array I was looking for with db.A.distinct('id'). Thanks to anyone who took the time to read this question, anyway.

Query on array from another array

I have the following 2 arrays. Array A with i.e. 10 id's, and the other array, Array B with 300 id's with all the corresponding data.
I want to retrieve all the data from B with id's which are stated in the array A.
I could just loop all entries in array B on every entry in array A, but this looks a little bit heavy for such simple task. What would be the best solutions in this case?
Thnx!
If you don't need an ordered array you could switch to an hash table (eg. NSSet) which has a much faster lookup time (strong bias towards O(1)). Otherwise you had to loop through the whole array and check all of its members.
Probably use a predicate (a, b are your arrays):
NSPredicate* filter = [NSPredicate predicateWithFormat: #"self IN %#", a];
NSArray* result = [b filteredArrayUsingPredicate: filter];
Although, it might only work if the objects in your arrays are simple things like strings.
When you are filling array B you can instead make it a dictionary. Assuming ids are unique you can then get value of the object for key in array A from array B. This will avoid looping and is sort of equivalent to hash table.
The returned value will then have the corresponding data for the particular unique id.
I don't see how you are going to do it otherwise if you are using arrays. The only way to access the right element is by looping through the array.

Complex Core Data predicate with to-many relation

I have 3 entities. Folder, Feed & FeedItem
I need to fetch Folders which have feeds and feeds which have unread FeedItems
NSPredicate * predicate = [NSPredicate predicateWithFormat:#" feeds.#count > 0 AND feeds.feedItems.unread == 0 "];
I get this error
'NSInvalidArgumentException', reason: 'to-many key not allowed here'
How do I construct such a predicate? Is it possible at all?
It doesn't like feeds.feedItems.unread==0 because feeds and feedItems return a set so the predicate doesn't know which object to test.
Try ANY feeds.feedItems.unread==0.
However, you're going about this backwards. It would be easier to fetch all FeedItem where unread==0 and then ask for each fetched item's feed.folder to get the folder.
Complex predicates are usually a bad idea because you can never predict the resource consumption of the search they perform as the object graph grows in complexity and the data itself grows in size. You should walk relationships instead when you can.
Update:
Looking at this again it looks like you need a SUBQUERY. Try:
NSPredicate *p = [NSPredicate predicateWithFormat:#"(0 != SUBQUERY(feeds, $x, (0 != SUBQUERY($x.feedItems, $y, $y.unread==0).#count)).#count)"];
Subqueries are poorly documented but they are essentially nested predicates. They have the format:
SUBQUERY(objects, singleObjectVariable, expression-for-single-object)
I believe that subqueries return sets so you can use any of the set operators on them and you can nest them. When you nest them, they walk the relationship graph so you can make them arbitrarily deep.