I have such function in my data source:
func getAllFood(by type: String) -> [UserFoodInformation] {
var findedFood = [UserFoodInformation]()
findedFood.append(contentsOf: baseUserFoodDataSource.getAllFood(by: type))
let predicate = NSPredicate(format: "foodType == %#", type)
let resultOfSearching = dataBase.objects(AddedUserFood.self).filter(predicate).sorted(byKeyPath: "name")
for searchedFood in resultOfSearching {
findedFood.append(searchedFood)
}
return findedFood
}
When I try to query with string that consist whitespace, I have no result, but if I query with simple one-word parameter, everything goes fine. Why is that? Can I have a string field in Realm that consists multiple words?
The predicate you're using is looking for objects whose foodType property is equal to the type string that is passed in. Only those objects whose property is exactly equal to that string will match. If you want to perform some other form of matching you'll need to use something other than the equality operator. BEGINSWITH, CONTAINS, ENDSWITH and LIKE are the comparison operators that Realm supports on string fields.
Can I have a string field in Realm that consists multiple words?
String fields can contain any string values. The supported comparison operators don't have the concept of a "word", though, so if you want to do filtering using that concept you'll likely need to do further work on your part. Depending on your use case, I can see a couple of ways to go about it:
Use CONTAINS to find any objects whose foodType properties contains the given type string.
Parse the string into structured data that you store in your model. For instance, it may make sense to store a List<FoodType> rather than a String for the foodType property.
There are likely other options, but they depend on details of what it is you're trying to achieve that you've not shared.
Related
I am implementing an iOS app which contains a CoreData DB with one of the columns containing a text field, on which the user is supposed to perform several types of search (semantic, exact matches, among other options). Right now, I am stuck at trying to implement the following MySQL query (Python implementation):
'''select * from quotes where match section against ('\\"%s\\"' in boolean mode) ''' % (query)
The above query returns all the text rows containing all the words of string "query" without any particular order, as long as the text field contains all of the words. As an example, a query such as "tomorrow is Saturday" should find a match in a field containing the sentence "Saturday we are going somewhere. Tomorrow is Friday."
I have tried a few approaches, such as NSPredicate, and regex. I couldn't find a direct match in CoreData to the MySQL boolean mode, but the best I have been able to achieve so far was using regex with NSPredicate such as:
let queryArray = query.components(separatedBy: " ")
let regex = ".*\\b(" + queryArray.map {
NSRegularExpression.escapedPattern(for: $0)
}.joined(separator: "|") + ")\\b.*"
let predicate = NSPredicate(format: "textField MATCHES %#", regex)
However, this query is returning any textField row that contains one or more of the words in the initial query, which is not the desired result in my case.
How can I achieve the desired result in CoreData?
For those that may get stuck, NSCompoundPredicate did the trick for me, just create an array of predicates, where which NSPredicate instance is looking for one of the words in the string, ignoring case and apply the NSCompoundPredicate to the NSFetchRequest.
This seems to be legitimate Lua syntax:
example = { ["dummy"] = "foobar"}
Why would you use the above and not simply:
example = { dummy = "foobar"}
They appear to functionally the same...
Because field names do not have to be identifiers: they can be any string, including strings having spaces, for instance.
The second statement is valid Lua syntax and is very convenient for field names that are identifiers.
Table keys do not have to be strings: they can actually be any value (except nil) and the [expr]=expr syntax for table entries allows the values of arbitrary expressions to be used as keys.
In my model code currently in some places, I am doing
var optionalString : String?
and in some places
var otherString : String = ""
When it is an optional and I am unwrapping it, I am scared it shouldn't be nil and just for being on the safe side I do
let newString = optionalString ?? ""
With optionals, I need to unwrap and perform nil checks. It makes the code a little less readable.
Should a String ever be an optional in the model? Any scenario where it must be one?
Optionals are used when the absence of a value (the string) has differing semantics from an empty value.
Simple example:
A password could be either
set to some string
empty
not yet set at all.
Here, the "not-set" case must be handled differently than the "empty" case.
You should only use optionals when model logic differs for empty vs. missing string. Same is true for collection types (Array, Dictionary).
IMO, String optionals and empty strings are interchangable sometimes.
Let's say we have a person class, it has a name property. In this case, a person must have a name, so optional and empty strings are interchangable (You can use either). You can use nil or "" to indicate that a person has no name. They mean the same. You can declare a constant too:
let NoName = ""
And you can just check it with this very abstract constant, rather than nil, which is a little bit less abstract.
On the other hand, sometimes you must use an optional. And that is when nil and "" have different meanings in the context. Let's use our person class to illustrate this as well. The person class has a property called dogName. If he/she does not have a dog, it is nil. If he/she has a dog but has not given it a name, it is an empty string. And if he/she has a dog and has given it a name, it would be "fido" or some other names. In this case, nil means he/she has no dog, and "" means his/her dog has no name. They have different meanings!
Conclusion: When nil and empty string have the same meaning, use optional optionally. When nil and empty string have different meanings, use optional.
I have a PFObject subclass which stores an array of strings as one of its properties. I would like to query for all objects of this class where one or more of these strings start with a provided substring.
An example might help:
I have a Person class which stores a firstName and lastName. I would like to submit a PFQuery that searches for Person objects that match on name. Specifically, a person should be be considered a match if if any ‘component’ of either the first or last name start with the provided search term.
For example, the name "Mary Beth Smith-Jones" should be considered a match for beth and bet, but not eth.
To assist with this, I have a beforeSave trigger for the Person class that breaks down the person's first and last names into separate components (and also lowercases them). This means that my "Mary Beth Smith-Jones" record looks like this:
firstName: “Mary Beth”
lastName: “Smith-Jones”
searchTerms: [“mary”, “beth”, “smith”, “jones”]
The closest I can get is to use whereKey:EqualTo which will actually return matches when run against an array:
let query = Person.query()
query?.whereKey(“searchTerms”, equalTo: “beth”)
query?.findObjectsInBackgroundWithBlock({ (places, error) -> Void in
//Mary Beth is retuned successfully
})
However, this only matches on full string equality; query?.whereKey(“searchTerms”, equalTo: “bet”) does not return the record in question.
I suppose I could explode the names and store all possible sequential components as search terms (b,e,t,h,be,et,th,bet,etc,beth, etc) but that is far from scalable.
Any suggestions for pulling these records from Parse? I am open to changing my approach if necessary.
Have you tried whereKey:hasPrefix: for this? I am not sure if this can be used on array values.
https://parse.com/docs/ios/guide#queries-queries-on-string-values
Domain (just simple example):
class House {
String address
String region
Long price
static searchable = { only = ['address', 'price', 'region'] }
}
I want to search by address with price selector
Search query is:
"${address} AND price: [100 TO 1000]"
But if address='500' in search result will be Houses with price 500. I need to find house for address only by House.address + House.region
If I understood, you want to use the value of ${address} to query only on the address and region attributes.
In that case, based on the "complex" query string example at http://grails.org/Searchable+Plugin+-+Searching+-+String+Queries, your query string could be:
"+(address:${address} OR region:${address}) price:[100 TO 1000]"
Matches must have a ${address} value for address or a ${address} value for region, and have a value from 100 to 1000 for price.
Note: your input variable has the same name of an entity attribute, "address", wich can cause some confusion when trying to understand query strings using them both. Though not needed, you might want to change that, for easier readable query strings.