我有一个函数需要放入 SQLite3 查询中。
我有以下方法:
def levenshtein(a, b)
case
when a.empty? then b.length
when b.empty? then a.length
else [(a[0] == b[0] ? 0 : 1) + levenshtein(a[1..-1], b[1..-1]),
1 + levenshtein(a[1..-1], b),
1 + levenshtein(a, b[1..-1])].min
end
end
我想做一个如下所示的查询:
@results = The_db.where('levenshtein("name", ?) < 3', '#{userinput}')
我想在其中找到 name 的值The_db
其中名称列的值与用户输入之间的编辑距离小于3
。问题是我不知道如何在查询中使用 Ruby 函数。这可能吗?
看看create_function method http://rdoc.info/github/luislavena/sqlite3-ruby/SQLite3/Database#create_function-instance_method。您可以使用它来创建像这样的自定义函数(您已经定义了您的levenshtein
红宝石方法):
db.create_function "levenshtein", 2 do |func, a, b|
func.result = levenshtein(a, b)
end
然后您可以在 SQL 中使用它:
# first set up some data
db.execute 'create table names (name varchar(30))'
%w{Sam Ian Matt John Albert}.each do |n|
db.execute 'insert into names values (?)', n
end
#Then use the custom function
puts db.execute('select * from names where levenshtein(name, ?) < 3', 'Jan')
在这个例子中,输出是
Sam
Ian
John
我还没有在 Rails 中对此进行测试,但我认为它应该可以工作,查询字符串只是传递到数据库。你可以获得Sqlitedb
对象使用ActiveRecord::Base.connection.raw_connection http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/AbstractAdapter.html#method-i-raw_connection。 (我不知道如何配置 Rails,以便所有 ActiveRecord 连接都定义了该函数 - 如果您在控制器中添加该函数,它似乎确实可以工作,但这并不理想)。
已经展示了如何做到这一点can完成,我不确定是否可以should在网络应用程序中完成。您可能不想在生产中使用 Sqlite。如果您正在使用例如,它可能会很有用。 Postgres 有自己的levenshtein
生产中的功能(如建议的铁皮人的回答 https://stackoverflow.com/a/13939629/214790),但是想在开发中使用Sqlite。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)