sunspot 0.9.8 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. data/History.txt +32 -0
  2. data/README.rdoc +40 -3
  3. data/TODO +10 -8
  4. data/VERSION.yml +2 -2
  5. data/bin/sunspot-configure-solr +22 -28
  6. data/bin/sunspot-solr +50 -29
  7. data/lib/sunspot/adapters.rb +1 -1
  8. data/lib/sunspot/composite_setup.rb +13 -15
  9. data/lib/sunspot/configuration.rb +14 -0
  10. data/lib/sunspot/data_extractor.rb +3 -0
  11. data/lib/sunspot/dsl/field_query.rb +33 -6
  12. data/lib/sunspot/dsl/fields.rb +14 -1
  13. data/lib/sunspot/dsl/fulltext.rb +168 -0
  14. data/lib/sunspot/dsl/query.rb +82 -5
  15. data/lib/sunspot/dsl/query_facet.rb +3 -3
  16. data/lib/sunspot/dsl/restriction.rb +7 -7
  17. data/lib/sunspot/dsl/scope.rb +17 -10
  18. data/lib/sunspot/dsl/search.rb +2 -2
  19. data/lib/sunspot/dsl.rb +2 -1
  20. data/lib/sunspot/facet.rb +9 -1
  21. data/lib/sunspot/facet_data.rb +56 -7
  22. data/lib/sunspot/facet_row.rb +2 -0
  23. data/lib/sunspot/field.rb +50 -26
  24. data/lib/sunspot/field_factory.rb +15 -0
  25. data/lib/sunspot/indexer.rb +6 -0
  26. data/lib/sunspot/instantiated_facet.rb +6 -9
  27. data/lib/sunspot/instantiated_facet_row.rb +7 -2
  28. data/lib/sunspot/query/boost_query.rb +20 -0
  29. data/lib/sunspot/query/connective.rb +98 -35
  30. data/lib/sunspot/query/dismax.rb +69 -0
  31. data/lib/sunspot/query/field_facet.rb +1 -22
  32. data/lib/sunspot/query/fulltext_base_query.rb +47 -0
  33. data/lib/sunspot/query/highlighting.rb +43 -0
  34. data/lib/sunspot/query/local.rb +24 -0
  35. data/lib/sunspot/query/pagination.rb +3 -4
  36. data/lib/sunspot/query/query.rb +93 -0
  37. data/lib/sunspot/query/query_facet.rb +14 -9
  38. data/lib/sunspot/query/query_facet_row.rb +3 -3
  39. data/lib/sunspot/query/query_field_facet.rb +10 -3
  40. data/lib/sunspot/query/restriction.rb +36 -15
  41. data/lib/sunspot/query/scope.rb +3 -159
  42. data/lib/sunspot/query/sort.rb +84 -15
  43. data/lib/sunspot/query/text_field_boost.rb +15 -0
  44. data/lib/sunspot/query.rb +2 -188
  45. data/lib/sunspot/schema.rb +7 -25
  46. data/lib/sunspot/search/highlight.rb +38 -0
  47. data/lib/sunspot/search/hit.rb +50 -3
  48. data/lib/sunspot/search.rb +51 -32
  49. data/lib/sunspot/session.rb +32 -12
  50. data/lib/sunspot/setup.rb +47 -10
  51. data/lib/sunspot/text_field_setup.rb +29 -0
  52. data/lib/sunspot/type.rb +4 -4
  53. data/lib/sunspot/util.rb +27 -1
  54. data/lib/sunspot.rb +8 -17
  55. data/solr/solr/conf/schema.xml +54 -40
  56. data/solr/solr/conf/solrconfig.xml +30 -0
  57. data/solr/solr/lib/geoapi-nogenerics-2.1-M2.jar +0 -0
  58. data/solr/solr/lib/gt2-referencing-2.3.1.jar +0 -0
  59. data/solr/solr/lib/jsr108-0.01.jar +0 -0
  60. data/solr/solr/lib/locallucene.jar +0 -0
  61. data/solr/solr/lib/localsolr.jar +0 -0
  62. data/spec/api/indexer/attributes_spec.rb +100 -0
  63. data/spec/api/indexer/batch_spec.rb +46 -0
  64. data/spec/api/indexer/dynamic_fields_spec.rb +33 -0
  65. data/spec/api/indexer/fixed_fields_spec.rb +57 -0
  66. data/spec/api/indexer/fulltext_spec.rb +43 -0
  67. data/spec/api/indexer/removal_spec.rb +46 -0
  68. data/spec/api/indexer/spec_helper.rb +1 -0
  69. data/spec/api/indexer_spec.rb +1 -308
  70. data/spec/api/query/connectives_spec.rb +162 -0
  71. data/spec/api/query/dsl_spec.rb +12 -0
  72. data/spec/api/query/dynamic_fields_spec.rb +149 -0
  73. data/spec/api/query/faceting_spec.rb +272 -0
  74. data/spec/api/query/fulltext_spec.rb +193 -0
  75. data/spec/api/query/highlighting_spec.rb +138 -0
  76. data/spec/api/query/local_spec.rb +54 -0
  77. data/spec/api/query/ordering_pagination_spec.rb +95 -0
  78. data/spec/api/query/scope_spec.rb +266 -0
  79. data/spec/api/query/spec_helper.rb +1 -0
  80. data/spec/api/query/text_field_scoping_spec.rb +30 -0
  81. data/spec/api/query/types_spec.rb +20 -0
  82. data/spec/api/search/dynamic_fields_spec.rb +27 -0
  83. data/spec/api/search/faceting_spec.rb +206 -0
  84. data/spec/api/search/highlighting_spec.rb +65 -0
  85. data/spec/api/search/hits_spec.rb +62 -0
  86. data/spec/api/search/results_spec.rb +52 -0
  87. data/spec/api/search/search_spec.rb +23 -0
  88. data/spec/api/search/spec_helper.rb +1 -0
  89. data/spec/api/spec_helper.rb +1 -1
  90. data/spec/helpers/indexer_helper.rb +29 -0
  91. data/spec/helpers/query_helper.rb +13 -0
  92. data/spec/helpers/search_helper.rb +78 -0
  93. data/spec/integration/faceting_spec.rb +1 -1
  94. data/spec/integration/highlighting_spec.rb +22 -0
  95. data/spec/integration/keyword_search_spec.rb +65 -0
  96. data/spec/integration/local_search_spec.rb +56 -0
  97. data/spec/integration/scoped_search_spec.rb +15 -1
  98. data/spec/integration/spec_helper.rb +3 -3
  99. data/spec/mocks/connection.rb +14 -1
  100. data/spec/mocks/photo.rb +1 -1
  101. data/spec/mocks/post.rb +5 -3
  102. data/spec/mocks/super_class.rb +2 -0
  103. data/spec/spec_helper.rb +13 -0
  104. data/tasks/gemspec.rake +18 -7
  105. data/tasks/schema.rake +1 -1
  106. data/tasks/spec.rake +1 -1
  107. data/templates/schema.xml.erb +36 -0
  108. metadata +117 -48
  109. data/lib/sunspot/query/base_query.rb +0 -90
  110. data/lib/sunspot/query/dynamic_query.rb +0 -69
  111. data/lib/sunspot/query/field_query.rb +0 -63
  112. data/spec/api/build_search_spec.rb +0 -1017
  113. data/spec/api/query_spec.rb +0 -153
  114. data/spec/api/search_retrieval_spec.rb +0 -362
  115. data/templates/schema.xml.haml +0 -24
@@ -0,0 +1,56 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe 'local search' do
4
+ ORIGIN = [40.6749113, -73.9648859]
5
+ before :each do
6
+ Sunspot.remove_all
7
+ @posts = [
8
+ Post.new(:coordinates => ORIGIN),
9
+ Post.new(:coordinates => [40.725304, -73.997211], :title => 'teacup'),
10
+ Post.new(:coordinates => [40.800069, -73.962283]),
11
+ Post.new(:coordinates => [43.706488, -72.292233]),
12
+ Post.new(:coordinates => [38.920303, -77.110934], :title => 'teacup'),
13
+ Post.new(:coordinates => [47.661557, -122.349938])
14
+ ]
15
+ @posts.each_with_index { |post, i| post.blog_id = @posts.length - i }
16
+ Sunspot.index!(@posts)
17
+ end
18
+
19
+ it 'should find all the posts within a given radius' do
20
+ search = Sunspot.search(Post) { |query| query.near(ORIGIN, 20) }
21
+ search.results.to_set.should == @posts[0..2].to_set
22
+ end
23
+
24
+ it 'should perform a radial search with fulltext matching' do
25
+ pending 'fix for LocalSolr facet query or subquery support'
26
+ search = Sunspot.search(Post) do |query|
27
+ query.keywords 'teacup'
28
+ query.near(ORIGIN, 20)
29
+ end
30
+ search.results.should == [@posts[1]]
31
+ end
32
+
33
+ it 'should perform a radial search with attribute scoping' do
34
+ search = Sunspot.search(Post) do |query|
35
+ query.near(ORIGIN,20)
36
+ query.with(:title, 'teacup')
37
+ end
38
+ search.results.should == [@posts[1]]
39
+ end
40
+
41
+ it 'should order by arbitrary field' do
42
+ search = Sunspot.search(Post) do |query|
43
+ query.near(ORIGIN, 20)
44
+ query.order_by(:blog_id)
45
+ end
46
+ search.results.should == @posts[0..2].reverse
47
+ end
48
+
49
+ it 'should order by geo distance' do
50
+ search = Sunspot.search(Post) do |query|
51
+ query.near(ORIGIN, 20)
52
+ query.order_by(:distance)
53
+ end
54
+ search.results.should == @posts[0..2]
55
+ end
56
+ end
@@ -85,7 +85,7 @@ describe 'scoped_search' do
85
85
  end
86
86
  end
87
87
 
88
- test_field_type 'String', :title, :title, 'apple', 'banana', 'cherry', 'date', 'eggplant'
88
+ test_field_type 'String', :title, :title, 'apple pie', 'banana split', 'cherry tart', 'date pastry', 'eggplant a la mode'
89
89
  test_field_type 'Integer', :blog_id, :blog_id, -2, 0, 3, 12, 20
90
90
  test_field_type 'Float', :ratings_average, :average_rating, -2.5, 0.0, 3.2, 3.5, 16.0
91
91
  test_field_type 'Time', :published_at, :published_at, *(['1970-01-01 00:00:00 UTC', '1983-07-08 04:00:00 UTC', '1983-07-08 02:00:00 -0500',
@@ -123,6 +123,20 @@ describe 'scoped_search' do
123
123
  end
124
124
  end
125
125
 
126
+ describe 'prefix searching' do
127
+ before :each do
128
+ Sunspot.remove_all
129
+ @posts = ['test', 'test post', 'some test', 'bogus'].map do |title|
130
+ Post.new(:title => title)
131
+ end
132
+ Sunspot.index!(@posts)
133
+ end
134
+
135
+ it 'should return results whose prefix matches' do
136
+ Sunspot.search(Post) { with(:title).starting_with('test') }.results.should == @posts[0..1]
137
+ end
138
+ end
139
+
126
140
  describe 'exclusion by identity' do
127
141
  before do
128
142
  @posts = (1..5).map do |i|
@@ -1,7 +1,7 @@
1
- require File.join(File.dirname(__FILE__), '..', 'spec_helper')
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
2
 
3
3
  Spec::Runner.configure do |config|
4
- config.before(:all) do
5
- Sunspot.config.solr.url = 'http://localhost:8983/solr'
4
+ config.before(:each) do
5
+ Sunspot.config.solr.url = ENV['SOLR_URL'] || 'http://localhost:8983/solr'
6
6
  end
7
7
  end
@@ -82,11 +82,24 @@ module Mock
82
82
  return unless @last_search
83
83
  if params.respond_to?(:all?)
84
84
  params.all? do |key, value|
85
- @last_search.has_key?(key) && @last_search[key] == value
85
+ if @last_search.has_key?(key)
86
+ @last_search[key] == value
87
+ end
86
88
  end
87
89
  else
88
90
  @last_search.has_key?(params)
89
91
  end
90
92
  end
93
+
94
+ def has_last_search_including?(key, *values)
95
+ return unless @last_search
96
+ if @last_search.has_key?(key)
97
+ if @last_search[key].is_a?(Array)
98
+ (@last_search[key] & values).length == values.length
99
+ elsif values.length == 1
100
+ @last_search[key] == values.first
101
+ end
102
+ end
103
+ end
91
104
  end
92
105
  end
data/spec/mocks/photo.rb CHANGED
@@ -3,6 +3,6 @@ class Photo < MockRecord
3
3
  end
4
4
 
5
5
  Sunspot.setup(Photo) do
6
- text :caption
6
+ text :caption, :default_boost => 1.5
7
7
  boost 0.75
8
8
  end
data/spec/mocks/post.rb CHANGED
@@ -1,8 +1,9 @@
1
1
  require File.join(File.dirname(__FILE__), 'blog')
2
+ require File.join(File.dirname(__FILE__), 'super_class')
2
3
 
3
- class Post < MockRecord
4
+ class Post < SuperClass
4
5
  attr_accessor :title, :body, :blog_id, :published_at, :ratings_average,
5
- :author_name, :featured, :expire_date
6
+ :author_name, :featured, :expire_date, :coordinates
6
7
  alias_method :featured?, :featured
7
8
 
8
9
  def category_ids
@@ -31,7 +32,7 @@ end
31
32
 
32
33
  Sunspot.setup(Post) do
33
34
  text :title, :boost => 2
34
- text :body
35
+ text :body, :stored => true
35
36
  text :backwards_title do
36
37
  title.reverse if title
37
38
  end
@@ -51,6 +52,7 @@ Sunspot.setup(Post) do
51
52
  time :last_indexed_at, :stored => true do
52
53
  Time.now
53
54
  end
55
+ coordinates :coordinates
54
56
 
55
57
  dynamic_string :custom_string
56
58
  dynamic_float :custom_float, :multiple => true, :using => :custom_fl
@@ -0,0 +1,2 @@
1
+ class SuperClass < MockRecord
2
+ end
data/spec/spec_helper.rb CHANGED
@@ -27,6 +27,7 @@ rescue LoadError => e
27
27
  retry
28
28
  end
29
29
  end
30
+ require 'ostruct'
30
31
 
31
32
  unless gem_name = ENV['SUNSPOT_TEST_GEM']
32
33
  $:.unshift(File.dirname(__FILE__) + '/../lib')
@@ -40,6 +41,18 @@ Dir.glob(File.join(File.dirname(__FILE__), 'mocks', '**', '*.rb')).each do |file
40
41
  require file unless File.basename(file) == 'mock_record.rb'
41
42
  end
42
43
 
44
+ Spec::Runner.configure do |config|
45
+ Dir.glob(File.join(File.dirname(__FILE__), 'helpers', '*_helper.rb')).each do |helper|
46
+ helper_name = File.basename(helper, File.extname(helper))
47
+ spec_type = helper_name.sub(/_helper$/, '').to_sym
48
+ require(helper)
49
+ config.include(
50
+ Sunspot::Util.full_const_get(Sunspot::Util.camel_case(helper_name)),
51
+ :type => spec_type
52
+ )
53
+ end
54
+ end
55
+
43
56
  def without_class(clazz)
44
57
  Object.class_eval { remove_const(clazz.name.to_sym) }
45
58
  yield
data/tasks/gemspec.rake CHANGED
@@ -1,25 +1,36 @@
1
1
  begin
2
2
  require 'jeweler'
3
+ require 'jeweler/rubyforge_tasks'
4
+ require 'jeweler/gemcutter_tasks'
3
5
  Jeweler::Tasks.new do |s|
4
6
  s.name = 'sunspot'
5
7
  s.executables = ['sunspot-solr', 'sunspot-configure-solr']
6
- s.summary = 'Library for expressive, powerful interaction with the Solr search engine'
7
8
  s.email = 'mat@patch.com'
8
- s.homepage = 'http://github.com/outoftime/sunspot'
9
- s.description = 'Library for expressive, powerful interaction with the Solr search engine'
10
- s.authors = ['Mat Brown', 'Peer Allan', 'Dmitriy Dzema', 'Benjamin Krause']
11
- s.files = FileList['[A-Z]*', '{bin,lib,spec,tasks,templates}/**/*', 'solr/{etc,lib,webapps}/**/*', 'solr/solr/conf/*', 'solr/start.jar']
9
+ s.homepage = 'http://outoftime.github.com/sunspot'
10
+ s.summary = 'Library for expressive, powerful interaction with the Solr search engine'
11
+ s.description = <<TEXT
12
+ Sunspot is a library providing a powerful, all-ruby API for the Solr search engine. Sunspot manages the configuration of persistent Ruby classes for search and indexing and exposes Solr's most powerful features through a collection of DSLs. Complex search operations can be performed without hand-writing any boolean queries or building Solr parameters by hand.
13
+ TEXT
14
+ s.authors = ['Mat Brown', 'Peer Allan', 'Dmitriy Dzema', 'Benjamin Krause', 'Marcel de Graaf', 'Brandon Keepers', 'Peter Berkenbosch', 'Brian Atkinson', 'Tom Coleman']
12
15
  s.rubyforge_project = 'sunspot'
16
+ s.files = FileList['[A-Z]*', '{bin,lib,spec,tasks,templates}/**/*', 'solr/{etc,lib,webapps}/**/*', 'solr/solr/{conf,lib}/*', 'solr/start.jar']
13
17
  s.add_dependency 'mwmitchell-rsolr', '= 0.9.6'
14
18
  s.add_dependency 'daemons', '~> 1.0'
15
- s.add_dependency 'optiflag', '~> 0.6.5'
16
- s.add_dependency 'haml', '~> 2.2'
17
19
  s.add_development_dependency 'rspec', '~> 1.1'
18
20
  s.add_development_dependency 'ruby-debug', '~> 0.10'
21
+ s.add_development_dependency 'technicalpickles-jeweler', '1.2.1'
19
22
  s.extra_rdoc_files = ['README.rdoc']
20
23
  s.rdoc_options << '--webcvs=http://github.com/outoftime/sunspot/tree/master/%s' <<
21
24
  '--title' << 'Sunspot - Solr-powered search for Ruby objects - API Documentation' <<
22
25
  '--main' << 'README.rdoc'
23
26
 
24
27
  end
28
+
29
+ Jeweler::RubyforgeTasks.new
30
+ Jeweler::GemcutterTasks.new
31
+ end
32
+
33
+ namespace :release do
34
+ desc "Release gem to RubyForge and GitHub"
35
+ task :all => [:release, :"rubyforge:release:gem", :"gemcutter:release"]
25
36
  end
data/tasks/schema.rake CHANGED
@@ -1,5 +1,5 @@
1
1
  namespace :schema do
2
- desc 'Compile schema from Haml template'
2
+ desc 'Generate schema from template'
3
3
  task :compile do
4
4
  require File.join(File.dirname(__FILE__), '..', 'lib', 'sunspot', 'schema')
5
5
  File.open(
data/tasks/spec.rake CHANGED
@@ -12,7 +12,7 @@ end
12
12
  namespace :spec do
13
13
  desc 'run api specs (mock out Solr dependency)'
14
14
  Spec::Rake::SpecTask.new('api') do |t|
15
- t.spec_files = FileList[File.join(File.dirname(__FILE__), '..', 'spec', 'api', '*_spec.rb')]
15
+ t.spec_files = FileList[File.join(File.dirname(__FILE__), '..', 'spec', 'api', '**', '*_spec.rb')]
16
16
  t.spec_opts = ['--color']
17
17
  end
18
18
 
@@ -0,0 +1,36 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <schema version="0.9" name="sunspot">
3
+ <types>
4
+ <fieldtype class="solr.TextField" positionIncrementGap="100" name="text">
5
+ <analyzer>
6
+ <tokenizer class="<%= tokenizer %>"/>
7
+ <%- filters.each do |filter| -%>
8
+ <filter class="<%= filter %>"/>
9
+ <%- end -%>
10
+ </analyzer>
11
+ </fieldtype>
12
+ <fieldtype class="solr.RandomSortField" name="rand"/>
13
+ <%- types.each do |type| -%>
14
+ <fieldtype name="<%= type.name %>" class="solr.<%= type.class_name %>Field" omitNorms="true"/>
15
+ <%- end -%>
16
+ </types>
17
+ <fields>
18
+ <field name="id" type="string" indexed="true" stored="true" multiValued="false" />
19
+ <field name="type" type="string" indexed="true" stored="false" multiValued="true" />
20
+ <field name="class_name" type="string" indexed="true" stored="false" multiValued="false" />
21
+ <field name="text" type="text" indexed="true" stored="false" multiValued="true" />
22
+ <field name="lat" type="sdouble" indexed="true" stored="true" multiValued="false" />
23
+ <field name="long" type="sdouble" indexed="true" stored="true" multiValued="false" />
24
+ <dynamicField name="*_text" type="text" indexed="true" stored="false" multiValued="true" />
25
+ <dynamicField name="*_texts" type="text" indexed="true" stored="true" multiValued="true" />
26
+ <dynamicField name="random_*" type="rand" indexed="true" stored="false" multiValued="false" />
27
+ <dynamicField name="_local*" type="sdouble" indexed="true" stored="false" multiValued="false" />
28
+ <%- dynamic_fields.each do |dynamic_field| -%>
29
+ <dynamicField name="<%= dynamic_field.name %>" type="<%= dynamic_field.type %>" indexed="true" stored="<%= dynamic_field.stored? %>" multiValued="<%= dynamic_field.multiValued? %>" />
30
+ <%- end -%>
31
+ </fields>
32
+ <uniqueKey>id</uniqueKey>
33
+ <defaultSearchField>text</defaultSearchField>
34
+ <solrQueryParser defaultOperator="AND"/>
35
+ <copyField dest="text" source="*_text"/>
36
+ </schema>
metadata CHANGED
@@ -1,18 +1,23 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sunspot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.8
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mat Brown
8
8
  - Peer Allan
9
9
  - Dmitriy Dzema
10
10
  - Benjamin Krause
11
+ - Marcel de Graaf
12
+ - Brandon Keepers
13
+ - Peter Berkenbosch
14
+ - Brian Atkinson
15
+ - Tom Coleman
11
16
  autorequire:
12
17
  bindir: bin
13
18
  cert_chain: []
14
19
 
15
- date: 2009-09-13 00:00:00 -04:00
20
+ date: 2009-10-08 00:00:00 -04:00
16
21
  default_executable:
17
22
  dependencies:
18
23
  - !ruby/object:Gem::Dependency
@@ -36,46 +41,38 @@ dependencies:
36
41
  version: "1.0"
37
42
  version:
38
43
  - !ruby/object:Gem::Dependency
39
- name: optiflag
40
- type: :runtime
41
- version_requirement:
42
- version_requirements: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - ~>
45
- - !ruby/object:Gem::Version
46
- version: 0.6.5
47
- version:
48
- - !ruby/object:Gem::Dependency
49
- name: haml
50
- type: :runtime
44
+ name: rspec
45
+ type: :development
51
46
  version_requirement:
52
47
  version_requirements: !ruby/object:Gem::Requirement
53
48
  requirements:
54
49
  - - ~>
55
50
  - !ruby/object:Gem::Version
56
- version: "2.2"
51
+ version: "1.1"
57
52
  version:
58
53
  - !ruby/object:Gem::Dependency
59
- name: rspec
54
+ name: ruby-debug
60
55
  type: :development
61
56
  version_requirement:
62
57
  version_requirements: !ruby/object:Gem::Requirement
63
58
  requirements:
64
59
  - - ~>
65
60
  - !ruby/object:Gem::Version
66
- version: "1.1"
61
+ version: "0.10"
67
62
  version:
68
63
  - !ruby/object:Gem::Dependency
69
- name: ruby-debug
64
+ name: technicalpickles-jeweler
70
65
  type: :development
71
66
  version_requirement:
72
67
  version_requirements: !ruby/object:Gem::Requirement
73
68
  requirements:
74
- - - ~>
69
+ - - "="
75
70
  - !ruby/object:Gem::Version
76
- version: "0.10"
71
+ version: 1.2.1
77
72
  version:
78
- description: Library for expressive, powerful interaction with the Solr search engine
73
+ description: |
74
+ Sunspot is a library providing a powerful, all-ruby API for the Solr search engine. Sunspot manages the configuration of persistent Ruby classes for search and indexing and exposes Solr's most powerful features through a collection of DSLs. Complex search operations can be performed without hand-writing any boolean queries or building Solr parameters by hand.
75
+
79
76
  email: mat@patch.com
80
77
  executables:
81
78
  - sunspot-solr
@@ -102,6 +99,7 @@ files:
102
99
  - lib/sunspot/dsl.rb
103
100
  - lib/sunspot/dsl/field_query.rb
104
101
  - lib/sunspot/dsl/fields.rb
102
+ - lib/sunspot/dsl/fulltext.rb
105
103
  - lib/sunspot/dsl/query.rb
106
104
  - lib/sunspot/dsl/query_facet.rb
107
105
  - lib/sunspot/dsl/restriction.rb
@@ -116,12 +114,15 @@ files:
116
114
  - lib/sunspot/instantiated_facet.rb
117
115
  - lib/sunspot/instantiated_facet_row.rb
118
116
  - lib/sunspot/query.rb
119
- - lib/sunspot/query/base_query.rb
117
+ - lib/sunspot/query/boost_query.rb
120
118
  - lib/sunspot/query/connective.rb
121
- - lib/sunspot/query/dynamic_query.rb
119
+ - lib/sunspot/query/dismax.rb
122
120
  - lib/sunspot/query/field_facet.rb
123
- - lib/sunspot/query/field_query.rb
121
+ - lib/sunspot/query/fulltext_base_query.rb
122
+ - lib/sunspot/query/highlighting.rb
123
+ - lib/sunspot/query/local.rb
124
124
  - lib/sunspot/query/pagination.rb
125
+ - lib/sunspot/query/query.rb
125
126
  - lib/sunspot/query/query_facet.rb
126
127
  - lib/sunspot/query/query_facet_row.rb
127
128
  - lib/sunspot/query/query_field_facet.rb
@@ -129,11 +130,14 @@ files:
129
130
  - lib/sunspot/query/scope.rb
130
131
  - lib/sunspot/query/sort.rb
131
132
  - lib/sunspot/query/sort_composite.rb
133
+ - lib/sunspot/query/text_field_boost.rb
132
134
  - lib/sunspot/schema.rb
133
135
  - lib/sunspot/search.rb
136
+ - lib/sunspot/search/highlight.rb
134
137
  - lib/sunspot/search/hit.rb
135
138
  - lib/sunspot/session.rb
136
139
  - lib/sunspot/setup.rb
140
+ - lib/sunspot/text_field_setup.rb
137
141
  - lib/sunspot/type.rb
138
142
  - lib/sunspot/util.rb
139
143
  - solr/etc/jetty.xml
@@ -151,19 +155,52 @@ files:
151
155
  - solr/solr/conf/solrconfig.xml
152
156
  - solr/solr/conf/stopwords.txt
153
157
  - solr/solr/conf/synonyms.txt
158
+ - solr/solr/lib/geoapi-nogenerics-2.1-M2.jar
159
+ - solr/solr/lib/gt2-referencing-2.3.1.jar
160
+ - solr/solr/lib/jsr108-0.01.jar
161
+ - solr/solr/lib/locallucene.jar
162
+ - solr/solr/lib/localsolr.jar
154
163
  - solr/start.jar
155
164
  - solr/webapps/solr.war
156
165
  - spec/api/adapters_spec.rb
157
- - spec/api/build_search_spec.rb
166
+ - spec/api/indexer/attributes_spec.rb
167
+ - spec/api/indexer/batch_spec.rb
168
+ - spec/api/indexer/dynamic_fields_spec.rb
169
+ - spec/api/indexer/fixed_fields_spec.rb
170
+ - spec/api/indexer/fulltext_spec.rb
171
+ - spec/api/indexer/removal_spec.rb
172
+ - spec/api/indexer/spec_helper.rb
158
173
  - spec/api/indexer_spec.rb
159
- - spec/api/query_spec.rb
160
- - spec/api/search_retrieval_spec.rb
174
+ - spec/api/query/connectives_spec.rb
175
+ - spec/api/query/dsl_spec.rb
176
+ - spec/api/query/dynamic_fields_spec.rb
177
+ - spec/api/query/faceting_spec.rb
178
+ - spec/api/query/fulltext_spec.rb
179
+ - spec/api/query/highlighting_spec.rb
180
+ - spec/api/query/local_spec.rb
181
+ - spec/api/query/ordering_pagination_spec.rb
182
+ - spec/api/query/scope_spec.rb
183
+ - spec/api/query/spec_helper.rb
184
+ - spec/api/query/text_field_scoping_spec.rb
185
+ - spec/api/query/types_spec.rb
186
+ - spec/api/search/dynamic_fields_spec.rb
187
+ - spec/api/search/faceting_spec.rb
188
+ - spec/api/search/highlighting_spec.rb
189
+ - spec/api/search/hits_spec.rb
190
+ - spec/api/search/results_spec.rb
191
+ - spec/api/search/search_spec.rb
192
+ - spec/api/search/spec_helper.rb
161
193
  - spec/api/session_spec.rb
162
194
  - spec/api/spec_helper.rb
163
195
  - spec/api/sunspot_spec.rb
196
+ - spec/helpers/indexer_helper.rb
197
+ - spec/helpers/query_helper.rb
198
+ - spec/helpers/search_helper.rb
164
199
  - spec/integration/dynamic_fields_spec.rb
165
200
  - spec/integration/faceting_spec.rb
201
+ - spec/integration/highlighting_spec.rb
166
202
  - spec/integration/keyword_search_spec.rb
203
+ - spec/integration/local_search_spec.rb
167
204
  - spec/integration/scoped_search_spec.rb
168
205
  - spec/integration/spec_helper.rb
169
206
  - spec/integration/stored_fields_spec.rb
@@ -176,6 +213,7 @@ files:
176
213
  - spec/mocks/mock_record.rb
177
214
  - spec/mocks/photo.rb
178
215
  - spec/mocks/post.rb
216
+ - spec/mocks/super_class.rb
179
217
  - spec/mocks/user.rb
180
218
  - spec/spec_helper.rb
181
219
  - tasks/gemspec.rake
@@ -184,9 +222,11 @@ files:
184
222
  - tasks/schema.rake
185
223
  - tasks/spec.rake
186
224
  - tasks/todo.rake
187
- - templates/schema.xml.haml
225
+ - templates/schema.xml.erb
188
226
  has_rdoc: true
189
- homepage: http://github.com/outoftime/sunspot
227
+ homepage: http://outoftime.github.com/sunspot
228
+ licenses: []
229
+
190
230
  post_install_message:
191
231
  rdoc_options:
192
232
  - --charset=UTF-8
@@ -212,33 +252,62 @@ required_rubygems_version: !ruby/object:Gem::Requirement
212
252
  requirements: []
213
253
 
214
254
  rubyforge_project: sunspot
215
- rubygems_version: 1.3.1
255
+ rubygems_version: 1.3.2
216
256
  signing_key:
217
- specification_version: 2
257
+ specification_version: 3
218
258
  summary: Library for expressive, powerful interaction with the Solr search engine
219
259
  test_files:
220
- - spec/api/adapters_spec.rb
221
- - spec/api/build_search_spec.rb
222
- - spec/api/indexer_spec.rb
223
- - spec/api/query_spec.rb
224
- - spec/api/search_retrieval_spec.rb
225
- - spec/api/session_spec.rb
226
- - spec/api/spec_helper.rb
227
- - spec/api/sunspot_spec.rb
228
- - spec/integration/dynamic_fields_spec.rb
260
+ - spec/spec_helper.rb
261
+ - spec/helpers/indexer_helper.rb
262
+ - spec/helpers/search_helper.rb
263
+ - spec/helpers/query_helper.rb
264
+ - spec/integration/spec_helper.rb
265
+ - spec/integration/local_search_spec.rb
229
266
  - spec/integration/faceting_spec.rb
230
- - spec/integration/keyword_search_spec.rb
231
267
  - spec/integration/scoped_search_spec.rb
232
- - spec/integration/spec_helper.rb
268
+ - spec/integration/highlighting_spec.rb
269
+ - spec/integration/keyword_search_spec.rb
270
+ - spec/integration/dynamic_fields_spec.rb
233
271
  - spec/integration/stored_fields_spec.rb
234
272
  - spec/integration/test_pagination.rb
235
- - spec/mocks/adapters.rb
273
+ - spec/mocks/mock_record.rb
236
274
  - spec/mocks/blog.rb
237
- - spec/mocks/comment.rb
238
- - spec/mocks/connection.rb
275
+ - spec/mocks/adapters.rb
239
276
  - spec/mocks/mock_adapter.rb
240
- - spec/mocks/mock_record.rb
277
+ - spec/mocks/user.rb
241
278
  - spec/mocks/photo.rb
242
279
  - spec/mocks/post.rb
243
- - spec/mocks/user.rb
244
- - spec/spec_helper.rb
280
+ - spec/mocks/comment.rb
281
+ - spec/mocks/super_class.rb
282
+ - spec/mocks/connection.rb
283
+ - spec/api/spec_helper.rb
284
+ - spec/api/session_spec.rb
285
+ - spec/api/indexer/spec_helper.rb
286
+ - spec/api/indexer/fixed_fields_spec.rb
287
+ - spec/api/indexer/attributes_spec.rb
288
+ - spec/api/indexer/dynamic_fields_spec.rb
289
+ - spec/api/indexer/fulltext_spec.rb
290
+ - spec/api/indexer/removal_spec.rb
291
+ - spec/api/indexer/batch_spec.rb
292
+ - spec/api/search/spec_helper.rb
293
+ - spec/api/search/hits_spec.rb
294
+ - spec/api/search/faceting_spec.rb
295
+ - spec/api/search/highlighting_spec.rb
296
+ - spec/api/search/dynamic_fields_spec.rb
297
+ - spec/api/search/search_spec.rb
298
+ - spec/api/search/results_spec.rb
299
+ - spec/api/adapters_spec.rb
300
+ - spec/api/query/dsl_spec.rb
301
+ - spec/api/query/spec_helper.rb
302
+ - spec/api/query/faceting_spec.rb
303
+ - spec/api/query/connectives_spec.rb
304
+ - spec/api/query/local_spec.rb
305
+ - spec/api/query/highlighting_spec.rb
306
+ - spec/api/query/ordering_pagination_spec.rb
307
+ - spec/api/query/dynamic_fields_spec.rb
308
+ - spec/api/query/types_spec.rb
309
+ - spec/api/query/scope_spec.rb
310
+ - spec/api/query/text_field_scoping_spec.rb
311
+ - spec/api/query/fulltext_spec.rb
312
+ - spec/api/sunspot_spec.rb
313
+ - spec/api/indexer_spec.rb
@@ -1,90 +0,0 @@
1
- module Sunspot
2
- module Query
3
- #
4
- # Encapsulates information common to all queries - in particular, keywords
5
- # and types.
6
- #
7
- class BaseQuery #:nodoc:
8
- include RSolr::Char
9
-
10
- attr_writer :keywords
11
-
12
- def initialize(types, setup)
13
- @types, @setup = types, setup
14
- end
15
-
16
- #
17
- # Generate params for the base query. If keywords are specified, build
18
- # params for a dismax query, request all stored fields plus the score,
19
- # and put the types in a filter query. If keywords are not specified,
20
- # put the types query in the q parameter.
21
- #
22
- def to_params
23
- params = {}
24
- if @keywords
25
- params[:q] = @keywords
26
- params[:fl] = '* score'
27
- params[:fq] = types_phrase
28
- params[:qf] = text_field_names.join(' ')
29
- params[:defType] = 'dismax'
30
- else
31
- params[:q] = types_phrase
32
- end
33
- params
34
- end
35
-
36
- #
37
- # Set keyword options
38
- #
39
- def keyword_options=(options)
40
- if options
41
- @text_field_names = options.delete(:fields)
42
- end
43
- end
44
-
45
- private
46
-
47
- #
48
- # Boolean phrase that restricts results to objects of the type(s) under
49
- # query. If this is an open query (no types specified) then it sends a
50
- # no-op phrase because Solr requires that the :q parameter not be empty.
51
- #
52
- # ==== Returns
53
- #
54
- # String:: Boolean phrase for type restriction
55
- #
56
- def types_phrase
57
- if escaped_types.length == 1 then "type:#{escaped_types.first}"
58
- else "type:(#{escaped_types * ' OR '})"
59
- end
60
- end
61
-
62
- #
63
- # Wraps each type in quotes to escape names of the form Namespace::Class
64
- #
65
- def escaped_types
66
- @escaped_types ||=
67
- @types.map { |type| escape(type.name)}
68
- end
69
-
70
- #
71
- # Returns the names of text fields that should be queried in a keyword
72
- # search. If specific fields are requested, use those; otherwise use the
73
- # union of all fields configured for the types under search.
74
- #
75
- def text_field_names
76
- text_fields =
77
- if @text_field_names
78
- Array(@text_field_names).map do |field_name|
79
- @setup.text_field(field_name.to_sym)
80
- end
81
- else
82
- @setup.text_fields
83
- end
84
- text_fields.map do |text_field|
85
- text_field.indexed_name
86
- end
87
- end
88
- end
89
- end
90
- end