Ruby on rails Rails应用程序中全文potgresql搜索的奇怪行为
我已经遵循了规则,但我有一些奇怪的行为 例如,当我搜索“警察”时,我不会得到任何结果,但当我搜索“警察”时,我会得到任何结果。(我正在搜索的内容中存在警察)。它也没有返回任何结果——但我知道这个词是存在的,不管这个词是大还是小 当我启动rails dbconsole时,它说我正在使用psql(9.1.4),应用程序的其余部分似乎也正常运行 我需要重建索引吗 我使用的是PG gem和postgres_ext gem,我没有使用texticle或PG_搜索gem(因为我并不真正需要添加的功能) 我的代码与屏幕广播中的代码相同:Ruby on rails Rails应用程序中全文potgresql搜索的奇怪行为,ruby-on-rails,ruby-on-rails-3,postgresql,full-text-search,pg,Ruby On Rails,Ruby On Rails 3,Postgresql,Full Text Search,Pg,我已经遵循了规则,但我有一些奇怪的行为 例如,当我搜索“警察”时,我不会得到任何结果,但当我搜索“警察”时,我会得到任何结果。(我正在搜索的内容中存在警察)。它也没有返回任何结果——但我知道这个词是存在的,不管这个词是大还是小 当我启动rails dbconsole时,它说我正在使用psql(9.1.4),应用程序的其余部分似乎也正常运行 我需要重建索引吗 我使用的是PG gem和postgres_ext gem,我没有使用texticle或PG_搜索gem(因为我并不真正需要添加的功能) 我的
def self.text_search(query)
if query.present?
rank = "ts_rank(to_tsvector(name), plainto_tsquery(#{sanitize(query)}))"
where("to_tsvector('english', name) @@ :q
or to_tsvector('english', content) @@ :q", q: query).order("#{rank} desc")
else
scoped
end
end
我已经创建了如下索引:
class AddSearchIndexToArticles < ActiveRecord::Migration
def up
execute "create index articles_name on articles using gin(to_tsvector('english', name))"
execute "create index articles_content on articles using gin(to_tsvector('english', content))"
end
end
…它按预期工作(除了速度非常慢,因为索引似乎被忽略)
知道发生了什么事吗
更新:
打开完整日志记录后,下面是正在运行的sql:
LOG: statement: SELECT 1
LOG: statement: SELECT "dogs".* FROM "dogs" WHERE (to_tsvector('english', name) @@ 'wary'
or to_tsvector('english', other_names) @@ 'wary'
or to_tsvector('english', origin) @@ 'wary'
or to_tsvector('english', kusa) @@ 'wary') ORDER BY ts_rank(to_tsvector(name), plainto_tsquery('wary'))
desc LIMIT 10 OFFSET 0
LOG: statement: SELECT 1
LOG: statement: SELECT 1
我不是sql专家,但查询看起来还好吗
此外,我不确定它是否相关,但日志文件中也有很多这样的内容:
FATAL: lock file "postmaster.pid" already exists
HINT: Is another postmaster (PID 821) running in data directory "/usr/local/var/postgres"?
我是通过自制软件安装postgres的,我使用的是9.1.4,考虑一下“警察”这个词是如何被转化为\u tsvector的:
select to_tsvector('english','police');
结果:
to_tsvector
-------------
'polic':1
match
----------
f
match
-------
t
结果:
to_tsvector
-------------
'polic':1
match
----------
f
match
-------
t
结果:
to_tsvector
-------------
'polic':1
match
----------
f
match
-------
t
匹配
-------
T
结论:不要直接将tsvector与单词匹配,而是将其与plainto\u tsquery
或to\u tsquery
的结果匹配
还有一点您可能需要加强:当前您的查询既包含显式传递给它的英文配置的to_tsvector
调用,也包含不带此参数的调用(在ORDER BY
子句中),在这种情况下,它默认为default\u text\u search\u config
参数的当前值。
如果此参数与英语不同,则可能会对某些表达式产生意外结果。最好始终传递此参数,或者始终忽略它。后一种情况的优点是简洁,避免了对特定语言进行硬编码。考虑一下单词police是如何通过转换为\u tsvector的:
select to_tsvector('english','police');
结果:
to_tsvector
-------------
'polic':1
match
----------
f
match
-------
t
结果:
to_tsvector
-------------
'polic':1
match
----------
f
match
-------
t
结果:
to_tsvector
-------------
'polic':1
match
----------
f
match
-------
t
匹配
-------
T
结论:不要直接将tsvector与单词匹配,而是将其与plainto\u tsquery
或to\u tsquery
的结果匹配
还有一点您可能需要加强:当前您的查询既包含显式传递给它的英文配置的to_tsvector
调用,也包含不带此参数的调用(在ORDER BY
子句中),在这种情况下,它默认为default\u text\u search\u config
参数的当前值。
如果此参数与英语不同,则可能会对某些表达式产生意外结果。最好始终传递此参数,或者始终忽略它。后一种情况的优点是简洁,避免了对特定语言进行硬编码。查看应用程序运行的底层SQL。在postgresql.conf
中设置log\u语句='all'
,然后重新启动Pg或Pg\u ctl重载
。重新运行问题代码并检查日志。另外:在将来,请提及您正在使用的版本,特别是PostgreSQL,因为它可以带来不同。嗨,Craig,谢谢您的回复。我已经用附加信息更新了问题。如果您需要任何其他详细信息,请告诉我,谢谢您的帮助。请查看您的应用程序正在运行的底层SQL。在postgresql.conf
中设置log\u语句='all'
,然后重新启动Pg或Pg\u ctl重载
。重新运行问题代码并检查日志。另外:在将来,请提及您正在使用的版本,特别是PostgreSQL,因为它可以带来不同。嗨,Craig,谢谢您的回复。我已经用附加信息更新了问题。如果您需要任何其他详细信息,请告诉我,谢谢您的帮助。谢谢您的回答,丹尼尔!谢谢你的回答,丹尼尔!