有时候简单的方式是最好的。你说你的字典里有大约50000个条目,但你没有说其中有多少个是由多个单词组成的(例如“贝尔公园”或“马丁·路德·金大道”等)。为了论证,假设每个字典条目平均包含2个单词。
我不太擅长JavaScript,所以我会用通俗易懂的语言来描述,但你应该能够相对容易地实现它。
在预处理步骤中,创建一个包含数据库中所有项目(即全部50000个)的数组。例如:
Carpark
Cool Park
Park
Pike's Peak
...
接下来,创建一个包含每个单词条目和指向包含该单词的第一个数组项的索引列表的映射。因此,您的第二个数组将包含:
Carpark, {0}
Cool, {1}
Park, {1,2}
Pike's, {3}
Peak, {3}
将第二个数组按单词排序。因此顺序应为{Carpark,Cool,Park,Peak,Pike's}
。
当用户键入“P”时,在单词数组上执行二进制搜索,以找到以“P”开头的第一个单词。您可以从该点开始对数据进行顺序扫描,直到到达不以P
开头的单词为止。在访问每个单词时,请将索引列表中引用的单词添加到输出中。(您需要进行一些去重操作,但这很容易。)
二进制搜索是O(log n),因此找到第一个单词将非常快。特别是对于如此少量的数据。如果您对每个键入的字母执行HTTP请求,则通信时间将超过处理时间。没有特别好的理由尝试在服务器端加速此过程。
但是,您可以减少服务器的负载。意识到当用户键入“P”并且客户端从服务器获取数据时,客户端现在拥有可能返回的所有可能字符串,如果用户键入“PA”,则来自“PA”的结果是来自“P”的结果的子集。
所以,如果您修改了代码,使客户端仅在键入第一个字符时向服务器发出请求,您可以在客户端上进行后续搜索。您需要做的就是让服务器返回匹配单词列表(来自第二个数据结构)以及由这些单词索引的匹配短语列表。因此,当用户键入第二个、第三个、第四个等字符时,客户端会执行过滤过程,而无需涉及服务器。
当然,这样做的好处是响应速度更快,服务器负载更轻。成本是在客户端上增加了一小部分复杂性,以及在第一次请求时返回了一小部分额外的数据。但是,在第二个请求中返回给服务器的额外数据量可能会比服务器返回的数据量少。