How to create autocomplete with GAE?

拟墨画扇 提交于 2019-12-01 22:30:48

There are a few neat tricks here. Consider this augmented model:

class Person(db.Model):
  first_name = db.StringProperty()
  last_name = db.StringProperty()
  middle_name = db.StringProperty()
  names_lower = db.StringListProperty()

You'll need to keep names_lower in sync with the real fields, e.g.:

p.names_lower = [p.first_name.lower(), p.last_name.lower(),
                 p.middle_name.lower()]

You can do this more elegantly with a DerivedProperty.

And now, your query:

term = self.request.get('term').lower()
query = Person.all()
query.filter('names_lower >=', term)
query.filter('names_lower <=', unicode(term) + u"\ufffd")

This gives you:

  • Matching on all 3 properties with one index
  • Case insensitive matches
  • Wildcard suffix matches

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 =', term instead.

Edit:

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?

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:

  • names_lower = bob
  • names_lower = j
  • names_lower = smith

This eliminates the need to run distinct queries on each field.

I am also not clear what should be the reply format.

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.

Basically agreeing on everything Drew wrote I post a link to my blog with rather elaborate example for auto-completing selecting keywords when searching for information in the datastore.

All done in GAE with Python and using YUI3 instead of jQuery (plugging in jQuery or any other library instead would be trivial).

Shortly, the idea is that datastore contains set of documents that are indexed using keywords (using Relation Index Entity). And when user enters words to search for, the system autocompletes them with the keywords from those documents.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!