Reputation: 66320
In google engine I have the following query to find me all users with the given firstname.
When I type in 'Mi' It would list me all "Michael" and "Mike"'s in the database.
class User(UserMixin, ndb.Model):
firstname = ndb.StringProperty()
data = User.query(ndb.AND(User.firstname >= name_startsWith, User.firstname <= name_startsWith + u'\ufffd')).fetch(5)
I would like to make it invariant so that I can type "mi" and it still outputs the same names.
I tried lower()
in Python, but this doesn't work with app engine's StringProperty()
data = User.query(ndb.AND(User.firstname.lower() >= name_startsWith.lower(), User.firstname.lower() <= name_startsWith.lower() + u'\ufffd')).fetch(5)
It throws the error:
AttributeError: 'StringProperty' object has no attribute 'lower'
Upvotes: 0
Views: 348
Reputation: 2265
You can use a computed property:
class User(UserMixin, ndb.Model):
firstname = ndb.StringProperty()
name_lower = ndb.ComputedProperty(lambda self: self.firstname.lower())
https://developers.google.com/appengine/docs/python/ndb/properties#computed
And then use first name that is returned from your query (which will have correct case).
Upvotes: 2
Reputation: 2279
Store a normalized version of any strings you want to be able to search this way. Queries in App Engine can only do simple filters on what's actually in the indexes.
Try something like this
class User(ndb.Model):
firstname = ndb.StringProperty()
firstname_norm = ndb.StringProperty()
username = "Some Name"
User(firstname = username, firstname_norm = normalizer(username)).put()
data = User.query(ndb.AND(User.firstname_norm >= normalizer(name_startsWith), User.firstname_norm <= normalizer(name_startsWith) + u'\ufffd')).fetch(5)
where "normalizer()" is a functStore a normalized version of any strings you want to be able to search this way. Queries in App Engine can only do simple filters on what's actually in the indexes.ion that converts mixed-case strings to an all-lowercase form, then use the same function when constructing queries. This can be as simple as just calling the string's .lower() method or as complex as removing all punctuation, converting all runs of whitespace to single spaces, doing unicode normalization, etc., depending on your needs.
def normalizer(x):
return x.lower()
Upvotes: 0
Reputation: 599490
You can't do searches like that with the datastore API. You can either store an additional lower-case version of the field, or use the full-text search API which is meant for this sort of thing.
Upvotes: 2