【问题标题】:How to implement fuzzy search with SQLite's FTS3?如何使用 SQLite 的 FTS3 实现模糊搜索?
【发布时间】:2015-02-18 06:44:44
【问题描述】:

我已经有integrated search based on the official Android documentation 和 我正在使用以下 SQLite 架构和查询:

CREATE VIRTUAL TABLE Search USING FTS3 (
    _id,
    name,
    location
);

select * from Search where name MATCH ?
-- where ? is the user typed exact "query"
-- or if it doesn't have spaces or stars I append a star to search prefix: "query*"

我想知道如何扩展它?允许以下内容:

假设我有一些名为:

  • 我喜欢的物品
  • 我的秘密物品
  • 项目 #1
  • 您的精美物品

当用户在搜索框中输入blah 时,搜索结果会显示:

  • my
    • 我的花式物品
    • 我的秘密物品
  • mfi
    • My Fancy tem
  • fan item, fanit, fit
    • 我的粉丝cy em
    • 你的粉丝cy em
  • it, item, im, itm
    • 我的幻想tem
    • 我的秘密tem
    • #1
    • 你喜欢tem

结果应该根据匹配的好坏进行排名,例如,如果字母距离较远,它们的排名应该低于精确匹配,例如mfi:“My Fancy Item”应该排名最后,“MFI” thingy”应该排在第一位(如果有这样的项目)。

注意:我的最小 SDK 是 API 级别 10,means it has to work SQLite 3.6.22

在 IDE 中可以找到类似的功能:

【问题讨论】:

  • 没有一种方法可以实现模糊搜索。您的要求太模糊,无法给出正确的答案。
  • *l*i*k*e*t*h*i*s* ...但我确实担心这个解决方案的效率
  • @popovitsj 用户输入任何内容,如果与名称的某些部分匹配,则会显示结果。
  • 如果它比@Selvin 简单的话是对的,但这几乎没用。从用户的角度来看,它会给出很多“意想不到的”匹配。
  • 您可以使用 sim metric 进行模糊搜索,对有限数量的条目有用链接:sourceforge.net/projects/simmetrics

标签: android sqlite search full-text-search fts3


【解决方案1】:

SQLite 的 FTS 只允许搜索整个单词或单词前缀。

这样的模糊搜索没有内置功能。 (并且 Android 数据库 API 不允许您添加自定义虚拟表实现。)

【讨论】:

  • 有替代方案的想法吗?
【解决方案2】:

我放宽了搜索所有单词开头的条件:

private static String fixQuery(String query) {
    return query.trim().replaceAll("\\s+", "*") + "*";
}

效果很好。不防错字,但我使用时感觉很自然。

【讨论】:

  • 你能解释一下这是做什么的吗?
  • @theGreenCabbage "搜索所有单词的开头",\\s+ 正则表达式表示"任何连续的空格",所以ab cd ef 将变为ab*cd*ef*see the docs what * means
  • 谢谢。我认为这就是一篇 Python 实现的模糊搜索的文章所做的。我正在使用 Laravel,发现我可以简单地使用范围查询。如果这不起作用,我会回到你的解决方案。谢谢。
  • 我认为 * 只能出现在搜索词的末尾它不能出现在中间
  • @MohammadYahia 我知道它也适用于中间,我在我的库存应用程序中使用它:fixQuery("but saf") -> "but*saf*" 匹配 “随机按钮和安全别针”
猜你喜欢
  • 1970-01-01
  • 2017-05-05
  • 1970-01-01
  • 1970-01-01
  • 2021-10-13
  • 2013-05-30
  • 2015-05-17
  • 1970-01-01
  • 2021-03-08
相关资源
最近更新 更多