我正在尝试将PostgreSQL配置为在我的rails应用程序中使用全文搜索,如此Railscast中所述.
我正在使用与with一起Ubuntu 12.04
运行PostgreSQL 9.1.5
安装的新服务器.apt-get
ppa:pitti/postgresql
precise
尝试运行迁移时,当我在psql控制台中使用peer postgres用户尝试相同的命令时,我收到以下错误:
postgres=# CREATE EXTENSION unaccent;
Run Code Online (Sandbox Code Playgroud)
错误:无法打开扩展控制文件"/usr/share/postgresql/9.1/extension/unaccent.control":
没有这样的文件或目录
在我的本地框运行中,Ubuntu 10.04 desktop
我使用相同的存储库(natty
),它运行良好.
任何见解将不胜感激.
postgresql full-text-search unaccent rails-postgresql postgresql-9.1
如何在Rails中修改搜索查询的where/like条件:
find(:all, :conditions => ["lower(name) LIKE ?", "%#{search.downcase}%"])
无论重音如何,结果都是匹配的?(例如métro= metro).因为我使用的是utf8,所以我不能使用"to_ascii".生产正在Heroku上运行.
我试图在我的Ubuntu框上安装Postgresql 8.4的contrib/unaccent包.但是当我键入make时,我收到了错误消息:
/usr/lib/postgresql/8.4/lib/pgxs/src/makefiles/pgxs.mk:没有这样的文件或目录
显然PGXS是Postgresql的安装扩展的基础设施,但我在我的ubuntu盒子里找不到文件pgxs.mk.
在互联网上的一些线索后,我尝试安装libpq-dev.尽管如此,即使安装了libpq-dev,我也找不到任何pgxs.mk.
令人沮丧的是,我甚至无法在互联网上的任何地方找到pgxs.mk的示例.如何安装PGXS基础架构?
我使用PostgreSQL 10并且我CREATE EXTENSION unaccent;
成功运行.我有一个包含以下内容的plgsql函数
whereText := 'lower(unaccent(place.name)) LIKE lower(unaccent($1))';
之后,根据用户选择的内容,可以添加更多条款whereText
.
在whereText
最终使用的查询:
placewithkeys := '%'||placename||'%';
RETURN QUERY EXECUTE format('SELECT id, name FROM '||fromText||' WHERE '||whereText)
USING placewithkeys , event, date;
Run Code Online (Sandbox Code Playgroud)
将whereText := 'LOWER(unaccent(place.name)) LIKE LOWER(unaccent($1))';
不起作用,即使我删除LOWER
的部分.
我做的select __my_function('???');
,我什么也没有回来,即使我应该回来的结果,因为在数据库中存在名称?????
如果我删除unaccent
,并留下了LOWER
它的工作原理,但没有口音:??
带来了?????
回来,因为它应该.这似乎unaccent
是导致问题.
我错过了什么?我怎样才能解决这个问题?
由于有关于语法和可能的SQLi的评论,我提供了整个函数定义,现在更改为在希腊语中对重音不敏感和不区分大小写的工作:
CREATE FUNCTION __a_search_place
(placename text, eventtype integer, eventdate integer, eventcentury integer, constructiondate integer, constructioncentury integer, arstyle integer, artype …
Run Code Online (Sandbox Code Playgroud) 在我们的 RoR 项目中,我们使用 postgres unaccent 函数来检索我们的模型名称属性之一的非重音版本。name 属性可以包含来自各种语言的任何重音字符。然后我们将其保存为 unaccent_name 属性。我不喜欢这个解决方案,因为我们需要确保已经安装并可以访问 postgres 扩展 UNACCENT(在测试、移动/清理数据库等时)。
在 RoR 中有 ActiveSupport::Inflector.transliterate 方法,它应该做一些非常相似的事情。
我发现它主要以相同的方式翻译重音字符,但也有一些区别:
相同的结果:
SELECT unaccent('?š??žý') AS unaccent_name;
=> "lsctzy"
ActiveSupport::Inflector.transliterate('?š??žý')
=> "lsctzy"
Run Code Online (Sandbox Code Playgroud)
不同的结果:
SELECT unaccent('ß') AS unaccent_name;
=> "S"
ActiveSupport::Inflector.transliterate('ß')
=> "ss"
Run Code Online (Sandbox Code Playgroud)
我知道这两种方法都可以接受带有自定义字母替换的字典,但我只对它们的一般/默认用法感兴趣。
音译方法的主要目的是否与 postgres unaccent 函数相同?我们可以用它作为替代品吗?
我想从导入PostgreSQL 9.3.5的OpenStreetMap数据库中检索具有给定名称的方法,操作系统是Win7 64位.为了有点容错,我使用了Postgres的unaccent扩展.
我的查询如下:
SELECT * FROM germany.ways
WHERE lower(tags->'name') like lower(unaccent('unaccent','Weststrasse'))
Run Code Online (Sandbox Code Playgroud)
查询计划:
Seq Scan on ways (cost=0.00..2958579.31 rows=122 width=465)
Filter: (lower((tags -> 'name'::text)) ~~ lower(unaccent('unaccent'::regdictionary, 'Weststrasse'::text)))
Run Code Online (Sandbox Code Playgroud)
奇怪的是,此查询使用顺序扫描方式,尽管索引存在于lower(tags->'name')
:
CREATE INDEX ways_tags_name ON germany.ways (lower(tags -> 'name'));
Run Code Online (Sandbox Code Playgroud)
一旦我从查询中删除unaccent,Postgres就会使用索引:
SELECT * FROM germany.ways
WHERE lower(tags->'name') like lower('Weststrasse')
Run Code Online (Sandbox Code Playgroud)
查询计划:
Index Scan using ways_tags_name on ways (cost=0.57..495.43 rows=122 width=465)
Index Cond: (lower((tags -> 'name'::text)) = 'weststrasse'::text)
Filter: (lower((tags -> 'name'::text)) ~~ 'weststrasse'::text)
Run Code Online (Sandbox Code Playgroud)
为什么无法防止Postgres使用索引?在我看来,这没有意义,因为在执行实际查询之前,应该已经完全知道unaccent(变音符号删除等)的结果.所以Postgres应该能够使用索引.使用unaccent时如何避免seq扫描?