我有一个包含产品信息(SKU,型号,描述等)的数据库,我希望有一个相对快速的搜索功能,用户只需键入几个字母或任何一个单词在文本字段中,然后获取在任何这些字段中包含该短语的产品列表。
数据库中的项目数可能不会超过100,000。
在不创建复杂查询的情况下,最简单的方法是什么?
答案 0 :(得分:2)
听起来你正在寻找自动完成功能。有很多方法可以做到这一点。
无论您选择何种解决方案,都需要在数据上添加一些索引。我建议在您要搜索的所有内容中添加跳过列表,并在任何长格式文本(例如产品说明)上添加附加的全文索引。字符串比较使用跳过列表,而只有FULLTEXT
搜索将使用全文索引。
你有一些选择。
https://docs.arangodb.com/3.1/AQL/Functions/String.html#like
您可以运行以下搜索:
for product in warehouse
filter like(product.model, @searchTerm, true) or
like(product.sku, @searchTerm, true)
return product
优势:简单的查询语法,一次搜索中的多个属性,支持子字符串,可以搜索文本正文的中间。
缺点:相对较慢。
这对于查询来说要复杂得多,但响应速度非常快,而且是我的应用程序用于自动完成的方法。
let sku = (for result in fulltext("warehouse", "sku", "prefix:@seacrhTerm")
return {sku: result.sku, model: result.model, description: result.description}
let model = (for result in fulltext("warehouse", "model", "prefix:@searchTerm")
return {sku: result.sku, model: result.model, description: result.description}
let description = (for result in fulltext("warehouse", "description", "prefix:@searchTerm")
return {sku: result.sku, model: result.model, description: result.description}
let resultsMatch = union(sku,model,description)
return resultsMatch
优势:非常快,响应速度极快,可以轻松处理很长的文本,在文本正文的任何位置进行搜索。
缺点:复杂的查询结构,因为您需要为您正在搜索的每个属性创建一个变量,在您正在搜索的每个属性上创建全文索引,并在末尾创建一个联合。您可能需要根据搜索需要的高级程度来结合联合结果。不支持子字符串搜索。
只需创建一个查询,过滤结果大于或等于搜索字词,但小于搜索字词,最后一个字母加1。示例位于我答案的Foxx部分下的链接中。这会利用跳过列表。
优势:只要字段不长,就非常快。非常容易实现。
缺点:不支持子字符串搜索。仅搜索字符串的第一部分。即你必须知道你正在搜索的字段的开头。
这样可以很好地快速搜索类似于模型编号的内容,用户可能会知道它的开头,但对于某些描述中的内容很差,用户可能会在某个位置的某个位置搜索单词文本。
Jan的小食谱示例是一个很好的起点:
https://docs.arangodb.com/cookbook/UseCases/PopulatingAnAutocompleteTextbox.html
我建议将你做的任何内容抽象到Foxx服务中。如果您需要在数据库中动态构建AQL查询,以防您需要搜索大量字段和集合,并且需要动态生成全文搜索,这一点尤为自由。
试验并了解哪种方法最适合您。我最好的猜测是,如果您需要搜索产品说明,您会发现最佳的全文解决方案。如果您希望用户始终搜索字段的前几个字母,只需使用与跳过列表的比较,因为它非常快。