I use jQuery UI autocomplete widget. Also I have GAE datastore:
class Person(db.Model):
# key_name contains person id in format 'lastname-firstname-middlename-counter',
# counter and leading dash are omitted, if counter=0
first_name = db.StringProperty()
last_name = db.StringProperty()
middle_name = db.StringProperty()
How can I search the person in the autocomplete widget, when user can input there surname, first name and/or middle name?
So, I am getting user input string as self.request.get('term'). How should I search for the same in my datastore (since I need to look at each field and probably for combined value of 3 fields)? How to optimize such query?
I am also not clear what should be the reply format. jQuery doc says:
A data source can be:
an Array with local data a String, specifying a URL a CallbackThe local data can be a simple Array of Strings, or it contains
Objects for each item in the array, with either a label or value
property or both.
There are a few neat tricks here. Consider this augmented model:
You’ll need to keep names_lower in sync with the real fields, e.g.:
You can do this more elegantly with a DerivedProperty.
And now, your query:
This gives you:
So a query for “smi” will return any person with any name starting with “smi” in any case.
Copying lower-cased names to a ListProperty enables case-insensitive matching, and allows us to search all 3 fields with one query. “\ufffd” is the highest possible unicode character, so it’s the upper limit for our substring match. If for some reason you want an exact match, filter for
'names_lower =', terminstead.Edit:
This is already accounted for in the original solution. By taking the 3 fields and copying them to a single ListProperty, we’re essentially creating a single index with multiple entries per person. If we have a person named Bob J Smith, he’ll have 3 hits in our index:
This eliminates the need to run distinct queries on each field.
Read the docs carefully. Formatting output for jQuery should be pretty straightforward. Your data source will be a string specifying a URL, and you’ll want to format the response as JSON.