实现Ajax自动完成功能的最佳Web服务方法是什么
我正在用jQuery的自动完成功能实现一个类似“Google Suggest”的标签搜索功能。
我需要提供一个网络服务给jQuery,让它根据用户输入的内容提供建议列表。我看到有两种方法来实现这个网络服务:
1) 直接把所有标签存储在数据库里,然后根据用户输入的前缀去搜索数据库。这种方法简单,但我担心会有延迟。
2) 使用一个在内存中的字典树(trie)来存储所有标签,并在里面搜索匹配的结果。因为所有操作都在内存中,我预计这样会有更低的延迟。但这也有几个难点:
- 如何在进程启动时初始化这个字典树?我想我会把标签数据存储在数据库中,然后在第一次启动进程时把它们取出来并转成字典树。但我不太确定该怎么做。我使用的是Python/Django。
- 当用户创建一个新标签时,我需要把这个新标签插入到字典树里。但假设我有5个Django进程,也就是5个字典树,我该如何告诉其他4个字典树也要插入这个新标签呢?
- 如何确保字典树是线程安全的,因为我的Django进程会使用多线程(我使用的是mod_wsgi)。或者因为Python的全局解释器锁(GIL),我根本不需要担心线程安全的问题?
- 有没有办法在字典树中存储标签的使用频率?我该如何判断标签的字符串结束和频率开始的地方——比如,如果我把apple213存入字典树,它是“apple”频率213,还是“apple2”频率13呢?
对于以上问题的任何帮助或其他方法的建议,我都非常感激。
2 个回答
1
我会选择第一个选项。'KISS' - (保持简单,别复杂)。
对于少量数据来说,应该不会有太大的延迟。我们也做过类似的事情,比如查找名字,结果在几千条数据中很快就能显示出来。
希望这对你有帮助,
乔希
4
在你测量之前,不用太担心延迟问题——可以先随便创建一些假标签,把它们放进数据库里,然后测一下常见查询的延迟。根据你的数据库设置,延迟可能没你想的那么糟糕,这样你就可以省去不必要的担忧。
不过,一定要关注线程问题——全局解释器锁(GIL)并不能消除竞争条件(也就是多个线程争抢资源的问题)。控制权可能会在任何伪代码指令的边界处在不同线程之间切换,也可能在底层扩展或内置代码执行时发生。你需要先检查你使用的数据库API模块的threadsafety
属性(可以参考PEP 249),然后适当地使用锁,或者创建一个小的专用线程池来处理数据库交互(通过一个队列接收请求,再通过另一个队列返回结果,这种方式在Python中是比较常见且简单的线程处理架构)。