ArangoDB:同时查询多个字段进行部分匹配
ArangoDB: Querying multiple fields at the same time for partial match
我有一个包含产品信息(SKU、型号、描述等)的数据库,我想要一个相对快速的搜索功能,用户只需输入几个字母或任何一个词文本字段,然后获取在任何这些字段中包含该短语的产品列表。
数据库中的项目数可能不会超过 100,000。
在不创建复杂查询的情况下,最简单的方法是什么?
听起来您正在寻找自动完成功能。有很多方法可以做到这一点。
索引
无论您选择哪种解决方案,您都需要为数据添加一些索引。我建议为您要搜索的所有内容添加一个跳过列表,并为任何长格式文本(例如产品描述)添加一个额外的全文索引。字符串比较使用跳过列表,而只有 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 下的 link我的答案的一部分。这利用了跳过列表。
优点: 只要字段不是特别长,速度就非常快。非常容易实施。
缺点:不支持子字符串搜索。只搜索字符串的第一部分。 IE。您必须知道要搜索的字段的开头。
这非常适用于快速搜索诸如型号之类的内容,您的用户可能知道它的开头,但对于诸如描述之类的内容,您的用户可能在其中搜索中间某处的单词则效果不佳正文。
福克斯
Jan 的小食谱示例是一个很好的起点:
https://docs.arangodb.com/cookbook/UseCases/PopulatingAnAutocompleteTextbox.html
我建议将您所做的一切抽象到 Foxx 服务中。如果您需要在数据库中动态构建 AQL 查询,尤其是在您有大量字段和集合要搜索并且需要动态生成全文搜索的情况下,它尤其解放。
底线
试验一下,看看哪一种最适合您。我最好的猜测是,如果您需要搜索产品描述,您会发现全文解决方案是最好的。如果您希望您的用户始终搜索字段的前几个字母,只需使用跳过列表进行比较,因为它非常非常快。
我有一个包含产品信息(SKU、型号、描述等)的数据库,我想要一个相对快速的搜索功能,用户只需输入几个字母或任何一个词文本字段,然后获取在任何这些字段中包含该短语的产品列表。
数据库中的项目数可能不会超过 100,000。
在不创建复杂查询的情况下,最简单的方法是什么?
听起来您正在寻找自动完成功能。有很多方法可以做到这一点。
索引
无论您选择哪种解决方案,您都需要为数据添加一些索引。我建议为您要搜索的所有内容添加一个跳过列表,并为任何长格式文本(例如产品描述)添加一个额外的全文索引。字符串比较使用跳过列表,而只有 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 下的 link我的答案的一部分。这利用了跳过列表。
优点: 只要字段不是特别长,速度就非常快。非常容易实施。
缺点:不支持子字符串搜索。只搜索字符串的第一部分。 IE。您必须知道要搜索的字段的开头。
这非常适用于快速搜索诸如型号之类的内容,您的用户可能知道它的开头,但对于诸如描述之类的内容,您的用户可能在其中搜索中间某处的单词则效果不佳正文。
福克斯
Jan 的小食谱示例是一个很好的起点:
https://docs.arangodb.com/cookbook/UseCases/PopulatingAnAutocompleteTextbox.html
我建议将您所做的一切抽象到 Foxx 服务中。如果您需要在数据库中动态构建 AQL 查询,尤其是在您有大量字段和集合要搜索并且需要动态生成全文搜索的情况下,它尤其解放。
底线
试验一下,看看哪一种最适合您。我最好的猜测是,如果您需要搜索产品描述,您会发现全文解决方案是最好的。如果您希望您的用户始终搜索字段的前几个字母,只需使用跳过列表进行比较,因为它非常非常快。