- 浏览: 239415 次
文章分类
最新评论
-
bluky999:
中间的兼职例子很逗 哈哈哈
tornado: web.py 之 Application -
flingfox63:
学习了,详细,赞个
Ruby变量作用域的类目录结构 -
zhou6711411:
不知是版本问题还是怎么的
class A
...
Ruby变量作用域的类目录结构 -
t284299773:
你在方法中定义方法就相当于在方法中调用lambda!
Ruby变量作用域的类目录结构(补二) -
lnj888:
很是有用 不错Powerpoint converter
一个简单的link_to,ROR到底在背后做了些什么?(未完)
原文出处:http://www.quarkruby.com/2007/8/12/acts_as_solr-for-search-and-faceting
Table of Contents
Solr is a search server based on lucene java search library with a HTTP/XML interface. Using Solr, large collections of documents can be indexed based on strongly typed field definitions, thereby taking advantage of Lucene's powerful full-text search features. is a ruby on rails plugin adding Solr capabilities to activerecord models. It hides all configuration and manual setting efforts with Solr and provides you with simple find_by...
methods. acts_as_solr can be used as a replacement to acts_as_ferret because of inbuilt full text search capabilities ;-) . The purpose of this article is to explain acts_as_solr with examples.
acts_as_solr
Installation: Installation is well explained on acts_as_solr homepage and getting started with acts_as_solr
Note: acts_as_solr requires jre1.5 on system. Before running any of the solr methods make sure you start solr server with rake solr:start
command.
Our example model for this tutorial will be DigitalCamera [classname: Camera] with following fields
- name (type:string)
- brand (type:string) [we want faceted browsing on this field]
- resolution (type:float) [we want faceted browsing on this field]
- other fields which we do not want to index
Basic Usage : for search
Lets start with basic search and then we will move on to faceted browsing. You need to specify which of the columns from your model file you want to be indexed for search (if no :fields
param is given, then all columns are indexed) :
1 2 3 |
class Camera acts_as_solr :fields=>[:name,:brand,:resolution] end |
|
@results = Camera.find_by_solr("canon powershot") |
:limit, :offset, :scores, :order, :operator
]
limit
: to limit the count of search resultsoffset
: starting index of the search results.scores
: solr scores for each of the result returnedorder
: by which field results should be ordered and in asc/desc order?operator
: words in query should be separated by "and" or "or" i.e. all words should exist in matching results or any of the words respectively
Note:
- If you do not want Camera models objects as results, you can use
find_id_by_solr
which will return just id's from the Camera table (score
option is not supported yet) - The result of
find_by_solr
is not an array of camera objects. Its a ActsAsSolr::SearchResults object.
You can get model objects and count of results by
1 2 |
@products = @results.docs @total_hits = @results.total_hits |
Pagination
We will be using will_paginate for pagination (rails default pagination is buggy). One way of paginating returned results is explained nicely at Using will paginate with acts_as_solr. But we don't need an additional module for getting count of results returned. This module is an overhead because of extra Solr query. acts_as_solr returns the total number of results via
find_by_solr
and you don't need to call count_by_solr
separately for getting result count. In your .rhtml file include this where you want pagination
1 2 |
<%= will_paginate WillPaginate::Collection.new((params[:page]||1), (params[:products_per_page]||10),@total_hits) -%> |
Faceting
Presentation by Keith Instone is an excellent read on faceted browsing with examples.
Back to acts_as_solr ... open the model file. Using option :facets => ...
add the columns on which you want to allow faceted browsing.
1 2 3 4 |
class Camera acts_as_solr :fields=>[:name,:brand,:resolution], :facets=>[:brand,:resolution] end |
resolution between 5 and 7
). Modify the model to look like:
1 2 3 4 |
class Camera acts_as_solr :fields=>[:name,:brand,{:resolution=>:range_float}], :facets=>[:brand,:resolution] end |
1 2 |
@results = Camera.find_by_solr("powershot",{:facets=> {:zeros=>false,:fields=>[:brand]}}) |
:zeros
parameter tells solr not to return the brand values whose facet count is zero.@results.facets["facet_fields"]["brand_facet"]
contains the names of brand with the corresponding counts. A sample result:{"Canon USA"=>1, "Canon PowerShot"=>1, "Canon"=>91}
But what about values for resolution facet as we have defined resolution to be varying float type (float_range)? Something like this does not work:
1 2 3 |
# INCORRECT @results = Camera.find_by_solr("powershot",{:facets=> {:zeros=>false,:fields=>[:brand,:resolution]}}) |
facet_query
param of find_by_solr
with ranges for resolution predefined i.e. Solr cannot calculate the range for the float/int fields itself and we need to specify the range of values while querying solr. For example if values in resolution column range from 0 to 20 and we want to have 4 facet ranges. Your query would be something like
1 2 3 4 5 6 7 |
@results = Camera.find_by_solr("powershot", {:facets=>{:zeros=>false, :fields=>[:brand], :query=>["resolution:[0 TO 4]","resolution:[5 TO 9]", "resolution:[10 TO 14]","resolution:[15 TO 20]"] } }) |
@results.facets["facet_queries"]
If you want to display the results to the user as links along with counts (something like example images at the top), where user can make a further selection, you need to get results from solr using
1 2 3 |
@results = Camera.find_by_solr("powershot"+" AND resolution:[0 TO 4]", {:facets=>{:zeros=>false, :fields=>[:brand]}}) ## resolution queries has been removed since you already made a selection in resolution itself. |
between 0 to 4
and between 6 to 7
. So we can define query (first argument to find_by_solr) as "powershot" + " AND (resolution:[0 TO 4] OR resolution:[6 TO 7])"
.But unfortunately,
find_by_solr(query+" AND brand:Canon")
doesn't seems to work By default all fields are of type string and faceting for these fields is done using
browse
parameter i.e.
1 2 3 4 5 6 |
@results = Camera.find_by_solr(query,{:facets=> {:zeros=>false, :query=>["resolution:[0 TO 4]", "resolution:[5 TO 9]", "resolution:[10 TO 14]", "resolution:[15 TO 20]"], :browse=>["brand:Canon"]} }) |
Note: I don't know how to make this work with browse field because multiple options in browse are separated by AND and
:operator
option from find_by_solr
works only with words in query. A good alternative is to redefine your model fields which are of string type to field_type as
:facet
. Our acts_as_solr declaration becomes:
1 2 |
acts_as_solr :fields=>[:name,{:brand=>:facet}, {:resolution=>:range_float}], :facets=>[:brand,:resolution] |
"powershot" + " AND (brand:Canon OR brand:Sony)"
Boosting
Using boost option you can give one field priority over the others. Just a small change in acts_as_solr declaration is enough.
|
acts_as_solr :fields => [{:name=>{:boost=>2}},:brand,:resolution] |
Quick Tips
- How to search solr with no query or 'nil' query. i.e. Product pages with navigation without a search query. Use
query = "[* TO *]"
1 2 3 4 5 6 7
@results = Camera.find_by_solr("[* TO *]", {:facets=>{:zeros=>false, :fields=>[:brand], :query=>["resolution:[0 TO 4]", "resolution:[5 TO 9]", "resolution:[10 TO 14]", "resolution:[15 TO 20]"] } })
- Already have database, how to integrate solr now? Goto ./script/console and run
Camera.rebuild_solr_index
- Adding or updating rows to table automatically adds/modifies them in table.
- If you have already created index on solr (not acts_as_solr), it will not work with acts_as_solr. This is because, in solr configuration, schema.xml tells the solr exactly about the columns you are going to index, their data types. But, with acts_as_solr you never modify
schema.xml
. Actually, acts_as_solr uses dynamic fields to tell solr about the fields and their data types. So, acts_as_solr does not finds anything in your already created index because field names are no more same.
Testing Solr
Copy vendor/plugins/acts_as_solr/test/test_helper.rb
modified as shown below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
class Test::Unit::TestCase begin Net::HTTP.get_response(URI.parse('http://localhost:8981/solr/')) rescue Errno::ECONNREFUSED raise "You forgot to 'rake solr:start RAILS_ENV=test', foo!" end def self.fixtures(*table_names) if block_given? Fixtures.create_fixtures(Test::Unit::TestCase.fixture_path, table_names) { yield } else Fixtures.create_fixtures(Test::Unit:: TestCase.fixture_path, table_names) end table_names.each do |table_name| clear_from_solr(table_name) klass = instance_eval table_name.to_s.capitalize.singularize.camelize klass.find (:all).each{|content| content.solr_save} end end private def self.clear_from_solr(table_name) ActsAsSolr::Post.execute(Solr::Request::Delete.new(:query => "type_t:#{table_name.to_s.capitalize.singularize.camelize}") end end |
Modifications in the original file
- removed top lines
- added camelize for removing "_" from model names
- added lines to test presence of test server running .. (from google groups)
Now include, this file in your unit/functional tests just like you include test_helper.rb
in all your test files. After you have saved above file as RAILS_APP/test/solr_test_helper.rb
do not forget to include solr_test_helper in your test files and start writing your tests. :)
Oops! Still not working
Did you make sure that config/solr.yml
has been configured for testing environment. (by default solr test server runs on port 8981)
References
- acts_as_solr benchmark results
- acts_as_solr performance on some live site
- http://www.webdesignpractices.com/navigation/facets.html
- http://cfis.savagexi.com/articles/2007/07/10/how-to-profile-your-rails-application
- Deploying acts_as_solr on tomcat
发表评论
-
(ZZ)Ror on svn
2007-12-20 19:34 1468正好需要,zz过来,抄袭自:http://www.surui. ... -
用GetText来进行ROR的国际化和本地化
2007-11-22 15:17 1409IBM developerWorks上的一篇文章,直接贴地址, ... -
advanced act_as_solr
2007-10-31 19:40 1758原文出处:http://www.quarkruby.com/2 ... -
Ambition
2007-10-31 19:36 1300原文出处:http://railsontherun.com/2 ... -
使用Inkscape提供自己的pdf服务
2007-10-31 19:34 1496原文出处:http://www.thesatya.com/bl ... -
给will_paginate加上ajax效果
2007-10-31 19:30 2109原文出处:http://railsontherun.com/2 ... -
使用rails制作图表
2007-10-31 19:21 2756原文出处:http://www.railsontherun.c ... -
如果定制attachment_fu上传文件的路径和文件名
2007-10-31 16:59 2711原文出处:http://the.railsi.st/2007/ ... -
attachment_fu使用指南
2007-10-31 16:56 3164原文出处:http://clarkware.com/cgi/b ... -
(ZZ)Cache in Rails
2007-09-25 15:49 1468很经典的文章,留在blog里面做个收藏 Ruby on Rai ... -
(ZZ)Ruby on Rails Security Guide
2007-09-24 21:28 2610Ruby on Rails Security Gui ... -
学到三招
2007-09-24 01:54 1356第一招:用ruby-debug来调试rails程序 具体使用方 ... -
一个action的process过程
2007-09-17 00:11 2478ruby 代码 def process(req ... -
在线查看rails代码和edge rails api的网址,备份,以免忘记
2007-09-14 18:38 1279Edge Rails API: http://caboo.se ... -
总是看到returning,这到底是个什么东东,查了一下找到了源代码
2007-09-14 18:37 1339A Ruby-ized realization of the ... -
一个简单的link_to,ROR到底在背后做了些什么?(未完)
2007-09-14 18:20 3415滥用link_to会造成ror程序 ... -
学到关于include的一点儿知识
2007-08-23 18:09 1115ruby 代码 module Test ... -
在一个controller中render另外一个controller中view的时候出现问题
2007-08-21 18:27 2124我想在posts这个controller中的show.rh ... -
因为Rjs试用NetBeans
2007-06-20 09:44 1086因为昨天看Rails Recipe的时候提到了rjs,于是四处 ...
相关推荐
solr manageschema 配置文件,增加了分词器后的配置文件
此为solr8的ikanalyzer中文分词包
ansj_solr_all
solr
Solr是一个高性能,采用Java开发,基于Lucene的全文搜索服务器。同时对其进行了扩展,提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展并对查询性能进行了优化,并且提供了一个完善的功能管理界面,是一...
官方推荐读物 Apache_solr_4_cookbook.pdf英文版
开源企业搜索引擎SOLR的应用教程开源企业搜索引擎SOLR的应用教程
hive与SOLR更新插件, 实现HIVE数据与SOLR的同步
一个讲解solr配置和应用demo的文档
详细介绍了Elasticsearch 和 solr 的区别;是一道经典的java面试题
windows环境php5.5的php_solr.dll
solr_3.5_配置及应用
php5.3版本的php_solr.dll哦,很难找到的哦
script/plugin install git://github.com/brauliobo/acts_as_solr_reloaded.git 下载Solr rake solr:download 要求 Oracle或OpenJDK的Java Runtime Environment(JRE)6.0(或更高版本) 配置 请参阅config
Solr_1.4_Enterprise_Search_Server.pdf
solr_开发入门例子
Lucene Solr 搜索引擎解密 ppt
solr1.4源码(欢迎喜欢研究solr的人下载)
solr_5.0_tomcat7_IKAnalyzer中文分词安装步奏及demo演示, 步奏详细可用,配图
本文介绍的Apache Solr 即是一个基于Lucene 的全文检索服务,通过本文的介绍您将了解到如何安装、使用和 扩展Solr 全文检索服务。