阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Rails 中的全文搜索

111次阅读
没有评论

共计 6900 个字符,预计需要花费 18 分钟才能阅读完成。

介绍

在 Web 应用中,搜索数据记录是一个常见的需求。最常见的一个需求就是允许用户从大量的数据记录中快速访问他们想要的数据。虽然可以使用简单的 SQL 查询应对这样的查询需求,但有时,更有效的是使用搜索引擎。

Solr 是 Apache Lucene 项目中的一个流行的搜索平台。其主要功能包括强大的全文搜索,点击显示,分面搜索,近实时索引,动态聚类,数据库集成,富文本处理和空间搜索。在本教程中,我们将寻求利用 Sunspot 执行全文本搜索,Sunspot 是一个能够使 Solr 集成在 ruby 应用中的类库。

相关阅读:

Ubuntu 下 Apache 服务器安装以及使用 Passenger 插件部署 Rails 应用 http://www.linuxidc.com/Linux/2012-12/75230.htm

Ubuntu 下搭建 Ruby On Rails http://www.linuxidc.com/Linux/2012-06/61981.htm

Ruby on rails 初体验系列文章:

http://www.linuxidc.com/Linux/2014-04/100245.htm
http://www.linuxidc.com/Linux/2014-04/100246.htm
http://www.linuxidc.com/Linux/2014-04/100247.htm

项目安装

我在 Github 创建了一个简单的 app,我将用在这里而不是开始一个全新的项目。这个 app 显示了一个产品列表,包括产品名,图片,价格和描述。我引用了一些 seed 数据,所以如果你不想自己输入数据的话,你可以运行 rake db:seed。这个应用程序使用了 Paperclip 处理 图片附件,因为我用到图片大小调整,所以在你的系统需要装上 ImageMagick。 随教程的进行你还需要在你的机器安装 Java 运行环境。

下面图片展示了这个应用程序。顶部的搜索表单现在还没做什么,但是我们将使得一个用户通过搜索产品并得到基于不仅仅是产品名,也包括它的商品描述的结果。

Rails 中的全文搜索

搜索

首先我们要将 Sunspot 和 Solr 引入到我们的依赖库中. 在开发中, 我们会使用预打包有 Solr 发行版的 sunspot_solr 依赖包, 这样我们就不需要单独安装它了.

gem ‘sunspot_rails’
 
group :development do
    gem ‘sunspot_solr’
end

运行 bundle install 生成 Sunspot 配置文件.

 rails generate sunspot_rails:install

这里创建了文件 /config/sunspot.yml 用以让你的应用知道在哪里找到 Solr 服务器.

建立为你想要索引的对象, 并为其添加 searchable 块. 在 starter project 中, 我们有一个含有 name, price, description 和 photo 字段的 Product 模型. 我们要为字段 name 和 description 添加全文搜索. 在 /models/product.rb 中添加:

searchable do
    text :name, :description
end

通过执行下面的语句启动 Solr 服务器:

rake sunspot:solr:start

Sunspot 索引你添加的新记录 , 但是如果数据库中已经有了许多数据, 执行 rake sunspot:reindex 来索引他们.

然后我们将代码放入 Products 控制器中,它将会得到用户的输入并将其传入搜索引擎. 在下面的代码中,我们在一个 Product 模型上面调用搜索并传入一个块. 我们在这个块中调用 fulltext 方法并传入我们想要搜索的查询字符串. 这里我们可以使用到几个方法来定制我们想要的搜索结果. 然后搜索结果就会被赋值给 @products,它将会作用于我们的视图.

def index
    @query = Product.search do
        fulltext params[:search]
    end
    @products = @query.results
end

运行应用程序,你就应当能够用这个程序来搜索可用的产品了.

Solr 将会使用输入的关键词或者短句对产品的名称和描述做一个大小写敏感的搜索. 你可以通过让某个域拥有比其它域更多的权重来提升搜索结果的相关性. 这是由 boost 方法来 做到的,它会被传入一个值来决定不同域的权重. 带有最大值的域将取得更多的重视.

在我们的应用程序中,我们可以让在名称中搜索到关键字符串的产品设置一个较高的分数. 我们可以通过在 /models/product.rb 中进行如下改变来做到.

searchable do
    text :name, :boost => 2
    text :description
end

使用 rake sunspot:reindex 可以对记录进行重新索引,而现在在产品名称中搜索到关键字的产品将会比在产品描述中搜索到关键字的产品排名要高. 你可以添加更多的记录来测试这一点.

更多详情见请继续阅读下一页的精彩内容:http://www.linuxidc.com/Linux/2014-05/101377p2.htm

切片浏览

切片浏览是一种通过将相关属性进行不同组合的方式来浏览查询数据. 例如,在我们的应用程序中,我们可以依据价格级别来分类搜索产品,并给出每一个级别的总数.

首先将价格添加到 /models/product.rb 中的 searchable 方法中

searchable do
    text :name, :boost => 2
    text :description
    double :price
end

然后在控制器中调用 facet . 产品就会根据按 $100.00 为间隔的价格级别来切片 . 这里我们假定所有的产品价钱都低于 $500.

def index
    @query = Product.search do
        fulltext params[:search]
 
        facet :price, :range => 0..500, :range_interval => 100
        with(:price, Range.new(*params[:price_range].split(“..”).map(&:to_i))) if params[:price_range].present?
 
    end
    @products = @query.results
end

在视图文件中,将下面的代码粘贴到你想要看到切片结果的地方.

<div class=”row”>
    <h3>Search Results</h3>
    <ul>
        <% for row in @query.facet(:price).rows %>
            <li>
                <% if params[:price_range].blank? %>
                    <%= link_to row.value, :price_range => row.value, :search => params[:search] %> (<%= row.count %>)
                <% else %>
                    <%= row.value %> (<%= link_to “X”, :price_range => nil %>)
                <% end %>
            </li>
        <% end %>
    </ul>
</div>

现在,当你搜索一个条目时,将会有一个切片列表展示出在每个价格级别会有多少条结果 . 在我们的示例应用程序中,如果你搜索关键词 ‘camera’, 你将会看到下面这份列表.

100.0..200.0 (2)
200.0..300.0 (1)
300.0..400.0 (1)

每一项都是一个链接,并且当在上面点击的时候,你将会获得一个满足你的搜索条件,并且其价格也会落在你所点击的相应区间的产品列表.

链接向 index 动作传入了原有的查询关键词,以及点击所选择的价格区间 . 由于其传入的价格区间是一个字符串,我们要使用 Range.new(*params[:price_range].split(“..”).map(&:to_i)) 来将其转换回区间. 你可以使用条件语句来输出更多对用户友好的连接,比如像 $100 – $199 (2) 而不是 100.0..200.0 (2),但这里我们不会深入讨论这个.

高级的配置

你可以使用更多的配置来定制 Solr 的运作 . 在其默认的配置中,Sunspot 通过使用一个智能的叫做 StandardTokenizer 的标记生成器基于空格和其它分隔符将搜索字符串分成多个关键词标记 . 然后这些关键词标记将会被转换成小写并被提取出搜索的关键词.

这有时可能已经够可以的了,但你也许还需要对搜索引擎进行配置,以容许人工错误或不太严谨的查询. 比如,你可能想要要向引擎提供一些同义词,那样当用户并没有输入匹配你记录中的精确文本时,他们仍然能得到一个类似的结果. 一个例子就是你可能在记录中有标记为 ‘ipod’ 的数据项. 你可能会提供想 ‘iPod’, ‘i-pod’ 和 ‘i pod’ 的同义词,来增加用户找到数据的可能性.

另外一个你可以添加的实用功能是词干搜索, 其将允许 Solr 实用相同的词干匹配不同的关键词. 例如,如果用户输入了 ‘run’, 他们会得到带有 ‘run’ 和 ‘running’ 的结果. 或者如果他们搜索 ’walk’, 结果将会包含含有 ‘walk’, ‘walking’, ‘walked’, 等等关键词的数据.

Solr 的设置可以在 solr/conf/schema.xml 中找到,这个文件可以修改用来改变服务器的配置. 这超出了本教程的范围,而作为对此的更深入介绍,请查看 全文搜索的高级配置 以及 Solr wiki.

结论

现在来总结一下,通过执行下面的命令停止 Solr 服务:

rake sunspot:solr:stop

我们已经搞了一把借助 Sunspot gem 来整合 Solr 搜索引擎到 Rails 应用,除了那些我们已经固定的设置外,还有很多搜索的设置是可以个性化设置的,大家可以通过阅读 Readme File 找到更多选项来玩玩。

Solr 给你提供了一种通过传统 SQL 语句没法达成的搜索能力。对于那些简单的应用,数据库记录也很少,通过 SQL 来搜索是没有性能瓶颈的,但如果你想要灵活升级,用 Solr 搜索引擎或同类玩意来替代它是值得的。

Solr 的详细介绍:请点这里
Solr 的下载地址:请点这里

相关阅读:

Solr3.6.1 在 Tomcat6 下的环境搭建 http://www.linuxidc.com/Linux/2013-01/77664.htm

基于 Tomcat 的 Solr3.5 集群部署 http://www.linuxidc.com/Linux/2012-12/75297.htm

在 Linux 上使用 Nginx 为 Solr 集群做负载均衡 http://www.linuxidc.com/Linux/2012-12/75257.htm

Linux 下安装使用 Solr http://www.linuxidc.com/Linux/2012-10/72029.htm

在 Ubuntu 12.04 LTS 上通过 Tomcat 部署 Solr 4 http://www.linuxidc.com/Linux/2012-09/71158.htm

Solr 实现 Low Level 查询解析(QParser)http://www.linuxidc.com/Linux/2012-05/59755.htm

基于 Solr 3.5 搭建搜索服务器 http://www.linuxidc.com/Linux/2012-05/59743.htm

Solr 3.5 开发应用教程 PDF 高清版 http://www.linuxidc.com/Linux/2013-10/91048.htm

Solr 4.0 部署实例教程 http://www.linuxidc.com/Linux/2013-10/91041.htm

介绍

在 Web 应用中,搜索数据记录是一个常见的需求。最常见的一个需求就是允许用户从大量的数据记录中快速访问他们想要的数据。虽然可以使用简单的 SQL 查询应对这样的查询需求,但有时,更有效的是使用搜索引擎。

Solr 是 Apache Lucene 项目中的一个流行的搜索平台。其主要功能包括强大的全文搜索,点击显示,分面搜索,近实时索引,动态聚类,数据库集成,富文本处理和空间搜索。在本教程中,我们将寻求利用 Sunspot 执行全文本搜索,Sunspot 是一个能够使 Solr 集成在 ruby 应用中的类库。

相关阅读:

Ubuntu 下 Apache 服务器安装以及使用 Passenger 插件部署 Rails 应用 http://www.linuxidc.com/Linux/2012-12/75230.htm

Ubuntu 下搭建 Ruby On Rails http://www.linuxidc.com/Linux/2012-06/61981.htm

Ruby on rails 初体验系列文章:

http://www.linuxidc.com/Linux/2014-04/100245.htm
http://www.linuxidc.com/Linux/2014-04/100246.htm
http://www.linuxidc.com/Linux/2014-04/100247.htm

项目安装

我在 Github 创建了一个简单的 app,我将用在这里而不是开始一个全新的项目。这个 app 显示了一个产品列表,包括产品名,图片,价格和描述。我引用了一些 seed 数据,所以如果你不想自己输入数据的话,你可以运行 rake db:seed。这个应用程序使用了 Paperclip 处理 图片附件,因为我用到图片大小调整,所以在你的系统需要装上 ImageMagick。 随教程的进行你还需要在你的机器安装 Java 运行环境。

下面图片展示了这个应用程序。顶部的搜索表单现在还没做什么,但是我们将使得一个用户通过搜索产品并得到基于不仅仅是产品名,也包括它的商品描述的结果。

Rails 中的全文搜索

搜索

首先我们要将 Sunspot 和 Solr 引入到我们的依赖库中. 在开发中, 我们会使用预打包有 Solr 发行版的 sunspot_solr 依赖包, 这样我们就不需要单独安装它了.

gem ‘sunspot_rails’
 
group :development do
    gem ‘sunspot_solr’
end

运行 bundle install 生成 Sunspot 配置文件.

 rails generate sunspot_rails:install

这里创建了文件 /config/sunspot.yml 用以让你的应用知道在哪里找到 Solr 服务器.

建立为你想要索引的对象, 并为其添加 searchable 块. 在 starter project 中, 我们有一个含有 name, price, description 和 photo 字段的 Product 模型. 我们要为字段 name 和 description 添加全文搜索. 在 /models/product.rb 中添加:

searchable do
    text :name, :description
end

通过执行下面的语句启动 Solr 服务器:

rake sunspot:solr:start

Sunspot 索引你添加的新记录 , 但是如果数据库中已经有了许多数据, 执行 rake sunspot:reindex 来索引他们.

然后我们将代码放入 Products 控制器中,它将会得到用户的输入并将其传入搜索引擎. 在下面的代码中,我们在一个 Product 模型上面调用搜索并传入一个块. 我们在这个块中调用 fulltext 方法并传入我们想要搜索的查询字符串. 这里我们可以使用到几个方法来定制我们想要的搜索结果. 然后搜索结果就会被赋值给 @products,它将会作用于我们的视图.

def index
    @query = Product.search do
        fulltext params[:search]
    end
    @products = @query.results
end

运行应用程序,你就应当能够用这个程序来搜索可用的产品了.

Solr 将会使用输入的关键词或者短句对产品的名称和描述做一个大小写敏感的搜索. 你可以通过让某个域拥有比其它域更多的权重来提升搜索结果的相关性. 这是由 boost 方法来 做到的,它会被传入一个值来决定不同域的权重. 带有最大值的域将取得更多的重视.

在我们的应用程序中,我们可以让在名称中搜索到关键字符串的产品设置一个较高的分数. 我们可以通过在 /models/product.rb 中进行如下改变来做到.

searchable do
    text :name, :boost => 2
    text :description
end

使用 rake sunspot:reindex 可以对记录进行重新索引,而现在在产品名称中搜索到关键字的产品将会比在产品描述中搜索到关键字的产品排名要高. 你可以添加更多的记录来测试这一点.

更多详情见请继续阅读下一页的精彩内容:http://www.linuxidc.com/Linux/2014-05/101377p2.htm

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-20发表,共计6900字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中