在SQLite中使用乱码搜索数据库

时间:2018-02-10 23:18:27

标签: sqlite search

我想知道是否可以使用给定的加扰字在数据库中搜索。

我在数据库中有一个mobs表,它包含怪物名称的名称

如果给定的怪物名称为A Golden DregonA Golden DfigonA Gelden Dragon,我希望它找到A Golden Dragon或从数据库中找到与其接近的匹配项。通常,最多一个或两个字母就像加扰一样给出。

只有SQL查询才有可能吗?或者我应该通过解析给定的怪物名称来构建查询吗?

我在代码端使用LUA。

3 个答案:

答案 0 :(得分:4)

我已经将此搜索类型称为模糊搜索。我主要用JS编程并且一直使用fuse.js来解决这类问题。

模糊搜索基于Levenshtein算法,该算法对两个字符串的距离进行评级。当您具有此距离值时,您可以根据分数对列表中的元素进行排序或删除。

我在lua here找到了算法。

function levenshtein(s, t)
  local s, t = tostring(s), tostring(t)
  if type(s) == 'string' and type(t) == 'string' then
    local m, n, d = #s, #t, {}
    for i = 0, m do d[i] = { [0] = i } end
    for j = 1, n do d[0][j] = j end
    for i = 1, m do
      for j = 1, n do
        local cost = s:sub(i,i) == t:sub(j,j) and 0 or 1
        d[i][j] = math.min(d[i-1][j]+1, d[i][j-1]+1, d[i-1][j-1]+cost)
      end
    end
    return d[m][n]
  end
end

如网站所述,您可以比较两个字符串,并根据它们的距离得分,然后根据给出的分数对要搜索的项目进行排序或删除。由于这是CPU昂贵的,我建议使用缓存或使用memoize函数来存储常见错误。

  levenshtein('referrer', 'referrer') -- zero distance
  >>> 0
  levenshtein('referrer', 'referer') -- distance of one character
  >>> 1
  levenshtein('random', 'strings') -- random big distance
  >>> 6 

有一个简单版本的工作在lua here我必须说lua是一种简单的语言,可以选择并开始编码。

local monsters = {'A Golden Dragon', 'Goblins', 'Bunny', 'Dragoon'}

function levenshtein(s, t)
  local s, t = tostring(s), tostring(t)
  if type(s) == 'string' and type(t) == 'string' then
    local m, n, d = #s, #t, {}
    for i = 0, m do d[i] = { [0] = i } end
    for j = 1, n do d[0][j] = j end
    for i = 1, m do
      for j = 1, n do
        local cost = s:sub(i,i) == t:sub(j,j) and 0 or 1
        d[i][j] = math.min(d[i-1][j]+1, d[i][j-1]+1, d[i-1][j-1]+cost)
      end
    end
    return d[m][n]
  end
end

--Fuzzy Search Returns the Best Match in a list
function fuzzySearch(list, searchText)
    local bestMatch = nil;
    local lowestScore = nil;

    for i = 1, #list do
        local score = levenshtein(list[i], searchText)
        if lowestScore == nil or score < lowestScore then
            bestMatch = list[i]
            lowestScore = score
        end 
    end

    return bestMatch
end

print ( fuzzySearch(monsters, 'golen dragggon') )
print ( fuzzySearch(monsters, 'A Golden Dfigon') )
print ( fuzzySearch(monsters, 'A Gelden Dragon') )

print ( fuzzySearch(monsters, 'Dragooon') ) --should be Dragoon
print ( fuzzySearch(monsters, 'Funny') ) --should be Bunny
print ( fuzzySearch(monsters, 'Gob') ) --should be Goblins

输出

A Golden Dragon
A Golden Dragon
A Golden Dragon
Dragoon
Bunny
Goblins

对于SQL

您可以尝试在T-SQL中使用与here相同的算法。

在SQLlite中有一个名为editdist3的扩展程序,它也使用此算法,文档为here

答案 1 :(得分:0)

我很难弥补所有不同的一个和两个字母的混乱组合,但是你可以创建一个常见拼写错误的lua表,一个金龙&#34;检查它是否在表中。我之前从未使用过lua,但这是我最好的尝试一些示例代码:

local mob_name = "A Golden Dregon"--you could do something like, input("Enter mob name:")
local scrambled_dragon_names = {"A Golden Dregon", "A Golden Dfigon", "A Gelden Dragon"}
for _,v in pairs(scrambled_dragon_names) do
  if v == mob_name then
    mob_name = "A Golden Dragon"
    break
  end
end

我真的希望我有所帮助!

P.S。如果您有任何问题请继续发表评论,我会尽快回答。

答案 2 :(得分:0)

你必须在某种程度上解析给定的怪物名称,方法是假设它拼写错误。例如,如果用户提供了名称

  

b fulden gorgon

你无法进入“金龙”。但是,如果您假设用户将始终正确地获取每个单词的第一个和最后一个字母,那么您可以解析给定名称中的单词以获取每个单词的第一个和最后一个字母,这将为您提供

"A", "G" "n", "D" "n"

然后您可以在查询中使用LIKE运算符,如下所示:

SELECT * FROM mobs WHERE monster_name LIKE 'A G%n D%n';

这里的要点是你对拼写错误的假设。您越接近缩小范围,查询结果就越好。