如何使用GAE创建自动完成? [英] How to create autocomplete with GAE?

查看:164
本文介绍了如何使用GAE创建自动完成?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用jQuery UI 自动填充小部件。我还有GAE数据存储:
$ b $ pre $ class Person(db.Model):
#key_name包含格式为'如果计数器= 0
first_name = db.StringProperty()
last_name = db.StringProperty()$ b $,则省略
#计数器和前导短划线b middle_name = db.StringProperty()

如何在用户搜索自动填充小部件中的用户时可以输入姓氏,名字和/或中间名?

所以,我将用户输入字符串作为 self.request.get('术语')。我应该如何在数据存储中搜索相同的内容(因为我需要查看每个字段,可能是3个字段的组合值)?如何优化这样的查询?
我也不清楚应该是什么格式。 jQuery doc说:
$ b


数据源可以是:

 带本地数据的数组$ b $字符串,指定一个URL 
a回调

本地数据可以是一个简单的字符串数组,或者它包含数组中每个项目的
对象,其中包含标签或值
属性或两者。



解决方案

这里有几个巧妙的技巧。考虑这个增强的模型:

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

您需要将names_lower与实际字段保持同步,例如:

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

您可以使用 DerivedProperty



现在,您的查询:

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



<这给你:




  • 使用一个索引匹配所有3个属性
  • 不区分大小写的匹配

  • 通配符后缀匹配



因此,在任何情况下,对smi的查询将返回任何名称以smi开头的任何人。

基于名称的ListProperty启用不区分大小写的匹配,并允许我们使用一个查询搜索所有3个字段。 \\\�是可能的最高Unicode字符,所以它是我们的子字符串匹配的上限。如果由于某种原因需要完全匹配,请针对'names_lower =',term 进行过滤。

编辑


我应该如何在数据存储中搜索相同的内容(因为我需要在
每个领域,并可能为3个领域的综合价值)?如何
优化这样的查询?

这已经在原始解决方案中考虑到了。通过将这3个字段复制到一个ListProperty中,我们基本上创建了一个每个人都有多个条目的索引。如果我们有一个名叫Bob J Smith的人,他将在我们的索引中有3个点击: b $ b

  • names_lower = j

  • names_lower = smith



  • 在每个字段上运行不同的查询。


    我也不清楚回复格式应该是什么。


    请仔细阅读文档。为jQuery格式化输出应该非常简单。您的数据源将是指定网址的字符串,您需要将响应格式设置为JSON。


    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 Callback
    

    The 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:

    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.

    这篇关于如何使用GAE创建自动完成?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆