我已经使用pg_search gem为我的Rails应用程序实现了全文搜索
我创建索引的迁移看起来像
execute(<<-'eosql'.strip)
CREATE index mytable_fts_idx
ON mytable
USING gin(
(setweight(to_tsvector('english', coalesce("mytable"."name", '')), 'A') ||
' ' ||
setweight(to_tsvector('english', coalesce("mytable"."description",'')), 'B')
)
)
eosql
Run Code Online (Sandbox Code Playgroud)
我的控制器代码看起来像
pg_search_scope :full_text_search,
:against => [
:name, :description],
:using => {
:tsearch => {
:prefix => true,
:dictionary => "english",
:any_word => true
}
}
Run Code Online (Sandbox Code Playgroud)
在Postgres 9.0.4上本地完全正常.但是,当我将其部署到heroku并搜索示例查询'test'时,它会引发错误
PGError: ERROR: syntax error in tsquery: "' test ':*"
SELECT COUNT(count_column) FROM (SELECT 1 AS count_column FROM "mytable" WHERE (((to_tsvector('english', coalesce("mytable"."name", '')) || to_tsvector('english', coalesce("mytable"."description", ''))) @@ (to_tsquery('english', …
Run Code Online (Sandbox Code Playgroud) 总结 :
Gem pg_search 提供的模块PgSearch 无法在staging 环境(Rbenv、nginx、unicorn、capistrano)中包含、需要或加载,问题通过http 发生在web 服务器上,但不会出现在staging 服务器的rails 命令上。可以包含其他 gem 提供的其他模块而不会出错。
本地开发环境(rvm、puma)没问题。
我目前正在使用 ruby 2.0.0 开发 Ruby On Rails 4.0 应用程序,其中 git 存储库托管在 bitbucket 上。我使用 capistrano 通过临时服务器部署应用程序。
两者的 rails 环境文件(environment/production.rb 和 environment/staging.rb)是相同的。
我做了什么:
我已经安装了 pg_search gem(一个 PostgreSQL 全文搜索 gem),将它添加到我的 Gemfile 并将子句“include PgSearch”放在我想与 pg_search gem 一起使用的 Active Record 模型中
我已经在开发模式下运行该应用程序......它有效!
问题 :
将更改部署到登台服务器后:通过 http 服务器,我收到此错误:
App::MyController#index 中的 NameError 未初始化常量 MyActiveRecordModel::PgSearch
(通常,包含在 GemFile 中的这个 pg_search gem 应该在自动加载搜索路径中包含它的 lib/*.rb 文件和一个像 load "pg_search.rb", require"pg_search" 或 …
我在Rails应用程序中使用pg_search gem来搜索用户 - 他们的bios和相关的技能模型.用户是开发人员,所以他们的技能包括"CSS","C++","C#","Objective C"等等......
我最初使用以下搜索范围:
pg_search_scope :search,
against: [:bio],
using: {tsearch: {dictionary: "english", prefix: true}},
associated_against: {user: [:fname, :lname], skills: :name}
Run Code Online (Sandbox Code Playgroud)
但是,如果在这种情况下搜索"C++",则会得到包含"CSS"(包括其他内容)的结果.我更改了范围以使用"简单"字典并删除了前缀:
pg_search_scope :search_without_prefix,
against: [:bio],
using: {tsearch: {dictionary: "simple"}},
associated_against: {user: [:fname, :lname], skills: :name}
Run Code Online (Sandbox Code Playgroud)
这解决了一些问题 - 例如,搜索"C++"并不显示"CSS".但是,搜索"C++"或"C#"仍然匹配列出"C"或"Objective C"的用户
我绝对可以做一个基本的ILIKE
匹配,但如果可能的话,希望用pg_search完成这个.
我从RoR 4.0.4更新到4.1.1以应用最新的安全补丁,看起来pg_search破了.
这是一个错误:
PG :: SyntaxError:错误:"AS"处或附近的语法错误第1行:...... sh',''''|| unaccent('banner')|| '''')),0)))AS pg_sear ...
我正在通过ajax搜索,但我认为这不是基于上面输出的问题.我也在使用will_paginate,但我正在使用的分支应该用rails 4.1.x和pg_search修复以前的问题.
gem 'will_paginate', :git => 'https://github.com/nazgum/will_paginate.git' #until rails 4.1 will_paginate fixed
Run Code Online (Sandbox Code Playgroud)
这是我正在执行搜索的代码模型:
include PgSearch
pg_search_scope :search, against: [:title, :body],
using: {tsearch: {dictionary: "english"}},
ignoring: :accents
def self.text_search(query)
if query.present?
search(query)
else
scoped
end
end
Run Code Online (Sandbox Code Playgroud)
在RoR版本颠簸之前,一切都在工作 - 希望有人可能会有一些建议.
这是完整的堆栈跟踪:
: SELECT COUNT("photos".*, ((ts_rank((to_tsvector('english', unaccent(coalesce("photos"."description"::text, ''))) || to_tsvector('english', unaccent(coalesce(pg_search_3b58f11462e6f0086ceffb.pg_search_dc60169d7766a303bd09de::text, '')))), (to_tsquery('english', ''' ' || unaccent('"banner"') || ' ''')), 0))) AS pg_search_rank) FROM "photos" LEFT OUTER JOIN (SELECT "photos"."id" AS id, …
Run Code Online (Sandbox Code Playgroud) 我想使用ransack(通过ActiveAdmin)对模型进行全文搜索。
我怎样才能获得使用pg_search的搜索结果?我想运行在其他查询组件中使用pg_search功能的查询。
我正在使用Rails 4.2.4和pg_search 1.0.5.
class Advert < ActiveRecord::Base
include PgSearch
multisearchable :against => [:title, :body]
end
Run Code Online (Sandbox Code Playgroud)
我想按:created_at
广告记录的日期订购pg_search结果.从逻辑上讲,在我看来,以下可能会工作(:asc
):
> @pgs = PgSearch.multisearch('55948189').order(created_at: :asc)
PgSearch::Document Load (136.1ms) SELECT "pg_search_documents".* FROM "pg_search_documents" INNER JOIN (SELECT "pg_search_documents"."id" AS pg_search_id, (ts_rank((to_tsvector('simple', coalesce("pg_search_documents"."content"::text, ''))), (to_tsquery('simple', ''' ' || '55948189' || ' ''')), 0)) AS rank FROM "pg_search_documents" WHERE (((to_tsvector('simple', coalesce("pg_search_documents"."content"::text, ''))) @@ (to_tsquery('simple', ''' ' || '55948189' || ' '''))))) AS pg_search_ce9b9dd18c5c0023f2116f ON "pg_search_documents"."id" = pg_search_ce9b9dd18c5c0023f2116f.pg_search_id ORDER BY pg_search_ce9b9dd18c5c0023f2116f.rank DESC, "pg_search_documents"."id" ASC, "pg_search_documents"."created_at" …
Run Code Online (Sandbox Code Playgroud) 当试图在文档中找到"Harrison Ford"时,pg_search将返回包含"Harrison"和"Ford"的任何文本,例如:
pg_search_scope :search_by_full_name, :against => [:first_name, :last_name]
Run Code Online (Sandbox Code Playgroud)
People.search_by_full_name("哈里森福特")
可以返回:
乔治哈里森驾驶福特福克斯
我怎样才能确保只'Harrison Ford'
返回完全匹配?
我使用gem pg_search在我的postgres db上执行全文搜索.我的范围是这样的:
pg_search_scope :fulltext, against: [:firstname, :lastname, :middlename],
using: {
tsearch: { prefix: true },
trigram: {
:threshold => 0.2
}
}
Run Code Online (Sandbox Code Playgroud)
当我用字符串搜索GRO我想那场比赛完全相同字的记录GRO有秩比相匹配的话,像记录高组(组包含GRO).
任何想法,如果有一些设置来做到这一点?
我正在将pg_search添加到Rails应用程序中.我正在按照github上的说明和这个railscast,但我遇到了一个问题.
我正在建立一个多模型搜索,我有一个基本的实现工作.但是我想扩展pg_seach来使用它的英文字典.
我已经有了一个初始化程序:
PgSearch.multisearch_options = {
:using => [:tsearch,:trigram],
:ignoring => :accents
}
Run Code Online (Sandbox Code Playgroud)
所以,从我读过的内容来看,添加词典就像是一样简单
PgSearch.multisearch_options = {
:using => [:tsearch => [:dictionary => "english"],:trigram],
:ignoring => :accents
}
Run Code Online (Sandbox Code Playgroud)
但是,当我启动我的服务器
...config/initializers/pg_search.rb:2: syntax error, unexpected ']', expecting tASSOC (SyntaxError)
:using => [:tsearch => [:dictionary => "english"],:trigram],
Run Code Online (Sandbox Code Playgroud)
我已经尝试交换方括号和大括号,以及我能想到的所有其他语法排列,但没有运气.
这里的语法是什么?为什么我的尝试没有效果,因为我遵循了范围搜索的语法?
我终于想出了如何实现pg_search的multiisearch功能.但是我在制作一个可用的搜索结果页面时遇到了麻烦,该页面显示了包含搜索词的各种文章和常见问题解答的链接.这是使用Rails 3.2.3的一个非常基本的设置:
楷模:
我有一个文章和一个常见问题解答模型,都有"标题"和"内容"属性,以及这两个模型中的代码:
include PgSearch
multisearchable :against => [:title, :content]
Run Code Online (Sandbox Code Playgroud)
搜索表单查看代码:
搜索表单将所有内容传递给名为"results"的控制器.
<%= form_tag result_index_path, method: :get do %>
<%= text_field_tag :query, params[:query] %>
<%= submit_tag "GO", name: nil %>
<% end %>
Run Code Online (Sandbox Code Playgroud)
结果控制器:
class ResultController < ApplicationController
def index
@pg_search_documents = PgSearch.multisearch(params[:query])
end
end
Run Code Online (Sandbox Code Playgroud)
我想创建一个搜索结果页面,显示找到的每个结果的标题,并返回该项目的链接.我想出了如何将'class'属性拉出@pg_search_documents.我的想法是在结果页面上做这样的事情:
<ul>
<% @pg_search_documents.each do |pg_search_document| %>
<li><%= link_to pg_search_document.searchable.title, "../#{pg_search_document.searchable.class}/#{pg_search_document.searchable.id}" %></li>
<% end %>
</ul>
Run Code Online (Sandbox Code Playgroud)
此代码产生的示例链接是:http://localhost/Article/3
.如果我能弄清楚如何对"pg_search_document.searchable.class"进行整理和复数化,那么我将无家可归.我试过在模型和控制器中编写各种方法,并尝试编写一个帮助器.但这是我的Rails技能让我失望的地方.
有什么建议?有谁知道更优雅的方式来完成这个?任何想法/建议都非常感谢.