How to get records with specific IDs? - swift

I can easily get record with specific ID. If I need something specific then I can use CKQueryOperation.
I need to provide it with proper predicate, but I can't specify IDs as parameter of predicate, because it doesn't support CKRecordValue protocol. Another idea is to use CKReference, but how to write proper predicate then?
If I try to use array of Strings and evaluate agains recordID.recordName key path:
var references:[String] = IDs.map{$0.recordName}
var predicate = NSPredicate(format: "ANY recordID.recordName IN %#", references)
I get following error:
<CKError 0x17005f3b0: "Invalid Arguments" (12/1009); "Invalid predicate: recordKey (recordID.recordName) contains invalid characters">
Predicate format output:
predicate ANY recordID.recordName IN {"AFF487BE-4A7E-4F76-8185-79FA2E1EFC33", "D4D83B37-97DE-4BF2-9E43-4C5522E36DF1", "0126008A-0B42-4F95-AB31-BB13B6215475", "6DE83AD9-F307-467D-A5EF-AD2B97B8E7F7", "F701ADBF-9BE7-4F42-8CA9-44D2D0E629F8", "38C4FB60-8A65-43F9-8E1E-4C48D5B60DCD"}
Any help is appreciated.

You can use a CKFetchRecordsOperation to fetch records whose RecordIDs you already know:
let fetchRecordsOperation = CKFetchRecordsOperation(recordIDs: recordIDs)
fetchRecordsOperation.desiredKeys = desiredKeys
Init the operation with an array of the CKRecordIDs you'd like to retrieve and it will return each individual record result in the perRecordCompletionBlock and all records fetched in fetchRecordsCompletionBlock.
You can retrieve the complete records by default or just a subset of their values by setting an array of NSStrings to the desiredKeys property with the names of the fields you'd like to retrieve.

Related

Swift predicate that returns matches on a Core Data transformable string array

I have a Core Data entity which has an attribute called likedMovies which is a String array [String]. This is configured as a Transformable attribute.
I populate a list of IDs inside this attribute, so for example:
User entity:
name = Duncan | likedMovies = [524, 558, 721]
name = Saskia | likedMovies = [143, 558, 653]
name = Marek | likedMovies = [655, 323, 112]
I would like to write a predicate which returns all User entities where the likedMovies array contains a given value. I have tried the predicate below but it doesn't work - for the id 558, instead of returning [Duncan, Saskia] I get no entities returned.
fetchRequest.predicate = NSPredicate(format: "%# IN %#", "558", "likedMovies")
Thank you in advance for your help.
There are two issues: first, your predicate format is wrong. You cannot use %# as placeholder for attribute names; you must instead use %K:
fetchRequest.predicate = NSPredicate(format: "%# IN %K", "558", "likedMovies")
But the second problem is that transformable attributes cannot be used in predicates as part of a fetch request (for a SQLite store). One option is to use the predicate to filter the User objects in memory (after fetching them). Another option is to represent the array of IDs as a string (with suitable separator), rather than an array of strings. You can then use the CONTAINS string operator to create the predicate. But adding and removing IDs to the likedMovies will become a rather unwieldy process of string manipulation. Another option is to replace the transformable attribute with a to-many relationship. I recommend the last of these.

Firestore + Swift Query - Check for value within an array in specified document

Is there a way to check for value within an array if you're querying for a specific document ID?
This doesn't work:
let userID = Auth.auth().currentUser?.uid ?? "nil"
let db = Firestore.firestore()
db.collection("users").document(userID).whereField("favorites", arrayContains: productID)
Seems like you can only use .whereField directly after declaring the collection, but not on the document.
The idea of the where methods is to find docs in a collection satisfying some criterion.
If you've already got a doc ref, just get() it and check the array in the client.
Alternatively, query the collection with where, and see if your user id is one of the ids in the resulting snapshot.

mgo $all query an array with an array and be case insensitive?

I have an array of ingredient names that is dynamic and provided per user. I'd like to match it to mongo documents where there is an array of objects called ingredients which has a property name. I've written a query (see below) which will take query parameters from the URL and will return all the documents that have all matching ingredient names, however this search is case sensitive and I'd like it not to be.
I've considered using bson.RegEx with Option: "i", however I'm not sure how to form this query or apply it to an array of strings.
Here is the case sensitive query:
// Check for ingredients, return all recipes that can be made using supplied ingredients
if qryPrms["ingredients"] != nil {
mongodQ["ingredients.name"] = bson.M{"$all": qryPrms["ingredients"]}
}
mongodQ is the bson.M I use to query the collection later in the code. Ideally I could apply RegEx to each element in qryPrms["ingredients"] so it would return closely matching ingredients like cheese would return swiss cheese as well. This is also a more general mongodb question I suppose when it comes to querying with a dynamic array.
I was able to accomplish this using a for loop to build a slice of type bson.RegEx.
if qryPrms["ingredients"] != nil {
var ingRegEx []bson.RegEx
for i := range qryPrms["ingredients"] {
ingRegEx = append(ingRegEx, bson.RegEx{Pattern: qryPrms["ingredients"][i], Options: "i"})
}
mongodQ["ingredients.name"] = bson.M{"$all": ingRegEx}
}

Argument labels '(format:, matchesArray:)' do not match any available overloads

I am doing a CloudKit query, in which I exclude any entities with the 'creatorUserRecordID' equal to any Id's stored within an array called matchesArray, I have done this by using NSPredicate (along with other custom predicates):
let predicate4:NSPredicate = NSPredicate(format: "creatorUserRecordID IN %#", matchesArray:[Array])
However, I am getting the following error:
Argument labels '(format:, matchesArray:)' do not match any available overloads.
Does anyone know how to fix this, and not query entitles which creators ID is stored within the matches array?
I think you were trying to write this,
let predicate4:NSPredicate = NSPredicate(format: "creatorUserRecordID IN %#", matchesArray)

how to filter all the posts that don't have one of the IDs in the favoiritePosts array?

I want to filter all the posts that don't have one of the IDs in the favoritePosts array.
I tried this but it doesn't work:
[NSPredicate predicateWithFormat:#"postID IN %#",favoritesPosts_];
I get this error: 'Invalid predicate: nil RHS'
Any ideas on how to write the predicate correctly?
The array is made of a NSNumber objects and i want to filter my tableview's fetchResultController with this predicate. the Post object has a PostID attribute which is of the NSNumber type.
Maybe thats not the way to do that.. The objective is to show in the tableview which is controlled by the fetchResultsController only the posts that their ids are in the favoritesPosts_ array. So if someone has a different idea on how to do that i will appreciate it.
If favoritesPosts_ is a string array containing the post IDs, then you can very well use the predicate you have created,
predicateWithFormat:#"postID IN %#", favoritesPosts_];
But if favoritesPosts_ contains objects which have a property, say, postID, then your predicate should be,
predicateWithFormat:#"postID IN %#", [favoritesPosts_ valueForKey:#"postID"]];