sunspot_rbg 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +12 -0
- data/Gemfile +4 -0
- data/History.txt +222 -0
- data/LICENSE +18 -0
- data/Rakefile +17 -0
- data/TODO +13 -0
- data/VERSION.yml +4 -0
- data/bin/sunspot-installer +19 -0
- data/bin/sunspot-solr +74 -0
- data/installer/config/schema.yml +95 -0
- data/lib/light_config.rb +40 -0
- data/lib/sunspot/adapters.rb +265 -0
- data/lib/sunspot/composite_setup.rb +202 -0
- data/lib/sunspot/configuration.rb +46 -0
- data/lib/sunspot/data_extractor.rb +50 -0
- data/lib/sunspot/dsl/adjustable.rb +47 -0
- data/lib/sunspot/dsl/field_query.rb +279 -0
- data/lib/sunspot/dsl/fields.rb +103 -0
- data/lib/sunspot/dsl/fulltext.rb +243 -0
- data/lib/sunspot/dsl/function.rb +14 -0
- data/lib/sunspot/dsl/functional.rb +44 -0
- data/lib/sunspot/dsl/more_like_this_query.rb +56 -0
- data/lib/sunspot/dsl/paginatable.rb +28 -0
- data/lib/sunspot/dsl/query_facet.rb +36 -0
- data/lib/sunspot/dsl/restriction.rb +25 -0
- data/lib/sunspot/dsl/restriction_with_near.rb +121 -0
- data/lib/sunspot/dsl/scope.rb +217 -0
- data/lib/sunspot/dsl/search.rb +30 -0
- data/lib/sunspot/dsl/standard_query.rb +121 -0
- data/lib/sunspot/dsl.rb +5 -0
- data/lib/sunspot/field.rb +193 -0
- data/lib/sunspot/field_factory.rb +129 -0
- data/lib/sunspot/indexer.rb +131 -0
- data/lib/sunspot/installer/library_installer.rb +45 -0
- data/lib/sunspot/installer/schema_builder.rb +219 -0
- data/lib/sunspot/installer/solrconfig_updater.rb +76 -0
- data/lib/sunspot/installer/task_helper.rb +18 -0
- data/lib/sunspot/installer.rb +31 -0
- data/lib/sunspot/query/abstract_field_facet.rb +52 -0
- data/lib/sunspot/query/boost_query.rb +24 -0
- data/lib/sunspot/query/common_query.rb +85 -0
- data/lib/sunspot/query/composite_fulltext.rb +36 -0
- data/lib/sunspot/query/connective.rb +206 -0
- data/lib/sunspot/query/date_field_facet.rb +14 -0
- data/lib/sunspot/query/dismax.rb +128 -0
- data/lib/sunspot/query/field_facet.rb +41 -0
- data/lib/sunspot/query/filter.rb +38 -0
- data/lib/sunspot/query/function_query.rb +52 -0
- data/lib/sunspot/query/geo.rb +53 -0
- data/lib/sunspot/query/highlighting.rb +55 -0
- data/lib/sunspot/query/more_like_this.rb +61 -0
- data/lib/sunspot/query/more_like_this_query.rb +12 -0
- data/lib/sunspot/query/pagination.rb +38 -0
- data/lib/sunspot/query/query_facet.rb +16 -0
- data/lib/sunspot/query/restriction.rb +262 -0
- data/lib/sunspot/query/scope.rb +9 -0
- data/lib/sunspot/query/sort.rb +95 -0
- data/lib/sunspot/query/sort_composite.rb +33 -0
- data/lib/sunspot/query/standard_query.rb +16 -0
- data/lib/sunspot/query/text_field_boost.rb +17 -0
- data/lib/sunspot/query.rb +11 -0
- data/lib/sunspot/schema.rb +151 -0
- data/lib/sunspot/search/abstract_search.rb +293 -0
- data/lib/sunspot/search/date_facet.rb +35 -0
- data/lib/sunspot/search/facet_row.rb +27 -0
- data/lib/sunspot/search/field_facet.rb +88 -0
- data/lib/sunspot/search/highlight.rb +38 -0
- data/lib/sunspot/search/hit.rb +136 -0
- data/lib/sunspot/search/more_like_this_search.rb +31 -0
- data/lib/sunspot/search/paginated_collection.rb +55 -0
- data/lib/sunspot/search/query_facet.rb +67 -0
- data/lib/sunspot/search/standard_search.rb +21 -0
- data/lib/sunspot/search.rb +9 -0
- data/lib/sunspot/server.rb +152 -0
- data/lib/sunspot/session.rb +260 -0
- data/lib/sunspot/session_proxy/abstract_session_proxy.rb +29 -0
- data/lib/sunspot/session_proxy/class_sharding_session_proxy.rb +66 -0
- data/lib/sunspot/session_proxy/id_sharding_session_proxy.rb +89 -0
- data/lib/sunspot/session_proxy/master_slave_session_proxy.rb +43 -0
- data/lib/sunspot/session_proxy/sharding_session_proxy.rb +222 -0
- data/lib/sunspot/session_proxy/silent_fail_session_proxy.rb +42 -0
- data/lib/sunspot/session_proxy/thread_local_session_proxy.rb +37 -0
- data/lib/sunspot/session_proxy.rb +87 -0
- data/lib/sunspot/setup.rb +350 -0
- data/lib/sunspot/text_field_setup.rb +29 -0
- data/lib/sunspot/type.rb +372 -0
- data/lib/sunspot/util.rb +243 -0
- data/lib/sunspot/version.rb +3 -0
- data/lib/sunspot.rb +569 -0
- data/lib/sunspot_rbg.rb +7 -0
- data/log/.gitignore +1 -0
- data/pkg/.gitignore +1 -0
- data/script/console +10 -0
- data/solr/README.txt +42 -0
- data/solr/etc/jetty.xml +218 -0
- data/solr/etc/webdefault.xml +379 -0
- data/solr/lib/jetty-6.1.3.jar +0 -0
- data/solr/lib/jetty-util-6.1.3.jar +0 -0
- data/solr/lib/jsp-2.1/ant-1.6.5.jar +0 -0
- data/solr/lib/jsp-2.1/core-3.1.1.jar +0 -0
- data/solr/lib/jsp-2.1/jsp-2.1.jar +0 -0
- data/solr/lib/jsp-2.1/jsp-api-2.1.jar +0 -0
- data/solr/lib/servlet-api-2.5-6.1.3.jar +0 -0
- data/solr/logs/.gitignore +1 -0
- data/solr/solr/.gitignore +1 -0
- data/solr/solr/README.txt +54 -0
- data/solr/solr/conf/admin-extra.html +31 -0
- data/solr/solr/conf/elevate.xml +36 -0
- data/solr/solr/conf/mapping-ISOLatin1Accent.txt +246 -0
- data/solr/solr/conf/protwords.txt +21 -0
- data/solr/solr/conf/schema.xml +238 -0
- data/solr/solr/conf/scripts.conf +24 -0
- data/solr/solr/conf/solrconfig.xml +934 -0
- data/solr/solr/conf/spellings.txt +2 -0
- data/solr/solr/conf/stopwords.txt +58 -0
- data/solr/solr/conf/synonyms.txt +31 -0
- data/solr/solr/conf/xslt/example.xsl +132 -0
- data/solr/solr/conf/xslt/example_atom.xsl +67 -0
- data/solr/solr/conf/xslt/example_rss.xsl +66 -0
- data/solr/solr/conf/xslt/luke.xsl +337 -0
- data/solr/start.jar +0 -0
- data/solr/webapps/solr.war +0 -0
- data/solr-1.3/etc/jetty.xml +212 -0
- data/solr-1.3/etc/webdefault.xml +379 -0
- data/solr-1.3/lib/jetty-6.1.3.jar +0 -0
- data/solr-1.3/lib/jetty-util-6.1.3.jar +0 -0
- data/solr-1.3/lib/jsp-2.1/ant-1.6.5.jar +0 -0
- data/solr-1.3/lib/jsp-2.1/core-3.1.1.jar +0 -0
- data/solr-1.3/lib/jsp-2.1/jsp-2.1.jar +0 -0
- data/solr-1.3/lib/jsp-2.1/jsp-api-2.1.jar +0 -0
- data/solr-1.3/lib/servlet-api-2.5-6.1.3.jar +0 -0
- data/solr-1.3/solr/conf/elevate.xml +36 -0
- data/solr-1.3/solr/conf/protwords.txt +21 -0
- data/solr-1.3/solr/conf/schema.xml +64 -0
- data/solr-1.3/solr/conf/solrconfig.xml +725 -0
- data/solr-1.3/solr/conf/stopwords.txt +57 -0
- data/solr-1.3/solr/conf/synonyms.txt +31 -0
- data/solr-1.3/solr/lib/geoapi-nogenerics-2.1-M2.jar +0 -0
- data/solr-1.3/solr/lib/gt2-referencing-2.3.1.jar +0 -0
- data/solr-1.3/solr/lib/jsr108-0.01.jar +0 -0
- data/solr-1.3/solr/lib/locallucene.jar +0 -0
- data/solr-1.3/solr/lib/localsolr.jar +0 -0
- data/solr-1.3/start.jar +0 -0
- data/solr-1.3/webapps/solr.war +0 -0
- data/spec/api/adapters_spec.rb +33 -0
- data/spec/api/binding_spec.rb +50 -0
- data/spec/api/indexer/attributes_spec.rb +149 -0
- data/spec/api/indexer/batch_spec.rb +46 -0
- data/spec/api/indexer/dynamic_fields_spec.rb +42 -0
- data/spec/api/indexer/fixed_fields_spec.rb +57 -0
- data/spec/api/indexer/fulltext_spec.rb +43 -0
- data/spec/api/indexer/removal_spec.rb +53 -0
- data/spec/api/indexer/spec_helper.rb +1 -0
- data/spec/api/indexer_spec.rb +14 -0
- data/spec/api/query/advanced_manipulation_examples.rb +35 -0
- data/spec/api/query/connectives_examples.rb +189 -0
- data/spec/api/query/dsl_spec.rb +18 -0
- data/spec/api/query/dynamic_fields_examples.rb +165 -0
- data/spec/api/query/faceting_examples.rb +397 -0
- data/spec/api/query/fulltext_examples.rb +313 -0
- data/spec/api/query/function_spec.rb +70 -0
- data/spec/api/query/geo_examples.rb +68 -0
- data/spec/api/query/highlighting_examples.rb +223 -0
- data/spec/api/query/more_like_this_spec.rb +140 -0
- data/spec/api/query/ordering_pagination_examples.rb +95 -0
- data/spec/api/query/scope_examples.rb +275 -0
- data/spec/api/query/spec_helper.rb +1 -0
- data/spec/api/query/standard_spec.rb +28 -0
- data/spec/api/query/text_field_scoping_examples.rb +30 -0
- data/spec/api/query/types_spec.rb +20 -0
- data/spec/api/search/dynamic_fields_spec.rb +33 -0
- data/spec/api/search/faceting_spec.rb +360 -0
- data/spec/api/search/highlighting_spec.rb +69 -0
- data/spec/api/search/hits_spec.rb +120 -0
- data/spec/api/search/paginated_collection_spec.rb +26 -0
- data/spec/api/search/results_spec.rb +66 -0
- data/spec/api/search/search_spec.rb +23 -0
- data/spec/api/search/spec_helper.rb +1 -0
- data/spec/api/server_spec.rb +91 -0
- data/spec/api/session_proxy/class_sharding_session_proxy_spec.rb +85 -0
- data/spec/api/session_proxy/id_sharding_session_proxy_spec.rb +30 -0
- data/spec/api/session_proxy/master_slave_session_proxy_spec.rb +41 -0
- data/spec/api/session_proxy/sharding_session_proxy_spec.rb +77 -0
- data/spec/api/session_proxy/silent_fail_session_proxy_spec.rb +24 -0
- data/spec/api/session_proxy/spec_helper.rb +9 -0
- data/spec/api/session_proxy/thread_local_session_proxy_spec.rb +50 -0
- data/spec/api/session_spec.rb +220 -0
- data/spec/api/spec_helper.rb +3 -0
- data/spec/api/sunspot_spec.rb +18 -0
- data/spec/ext.rb +11 -0
- data/spec/helpers/indexer_helper.rb +29 -0
- data/spec/helpers/query_helper.rb +38 -0
- data/spec/helpers/search_helper.rb +80 -0
- data/spec/integration/dynamic_fields_spec.rb +55 -0
- data/spec/integration/faceting_spec.rb +238 -0
- data/spec/integration/highlighting_spec.rb +22 -0
- data/spec/integration/indexing_spec.rb +33 -0
- data/spec/integration/keyword_search_spec.rb +317 -0
- data/spec/integration/local_search_spec.rb +64 -0
- data/spec/integration/more_like_this_spec.rb +43 -0
- data/spec/integration/scoped_search_spec.rb +354 -0
- data/spec/integration/spec_helper.rb +7 -0
- data/spec/integration/stored_fields_spec.rb +10 -0
- data/spec/integration/test_pagination.rb +32 -0
- data/spec/mocks/adapters.rb +32 -0
- data/spec/mocks/blog.rb +3 -0
- data/spec/mocks/comment.rb +21 -0
- data/spec/mocks/connection.rb +126 -0
- data/spec/mocks/mock_adapter.rb +30 -0
- data/spec/mocks/mock_class_sharding_session_proxy.rb +24 -0
- data/spec/mocks/mock_record.rb +52 -0
- data/spec/mocks/mock_sharding_session_proxy.rb +15 -0
- data/spec/mocks/photo.rb +11 -0
- data/spec/mocks/post.rb +85 -0
- data/spec/mocks/super_class.rb +2 -0
- data/spec/mocks/user.rb +13 -0
- data/spec/spec_helper.rb +30 -0
- data/sunspot.gemspec +40 -0
- data/tasks/rdoc.rake +27 -0
- data/tasks/schema.rake +19 -0
- data/tasks/todo.rake +4 -0
- metadata +457 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one or more
|
|
2
|
+
# contributor license agreements. See the NOTICE file distributed with
|
|
3
|
+
# this work for additional information regarding copyright ownership.
|
|
4
|
+
# The ASF licenses this file to You under the Apache License, Version 2.0
|
|
5
|
+
# (the "License"); you may not use this file except in compliance with
|
|
6
|
+
# the License. You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
#-----------------------------------------------------------------------
|
|
17
|
+
# a couple of test stopwords to test that the words are really being
|
|
18
|
+
# configured from this file:
|
|
19
|
+
stopworda
|
|
20
|
+
stopwordb
|
|
21
|
+
|
|
22
|
+
#Standard english stop words taken from Lucene's StopAnalyzer
|
|
23
|
+
an
|
|
24
|
+
and
|
|
25
|
+
are
|
|
26
|
+
as
|
|
27
|
+
at
|
|
28
|
+
be
|
|
29
|
+
but
|
|
30
|
+
by
|
|
31
|
+
for
|
|
32
|
+
if
|
|
33
|
+
in
|
|
34
|
+
into
|
|
35
|
+
is
|
|
36
|
+
it
|
|
37
|
+
no
|
|
38
|
+
not
|
|
39
|
+
of
|
|
40
|
+
on
|
|
41
|
+
or
|
|
42
|
+
s
|
|
43
|
+
such
|
|
44
|
+
t
|
|
45
|
+
that
|
|
46
|
+
the
|
|
47
|
+
their
|
|
48
|
+
then
|
|
49
|
+
there
|
|
50
|
+
these
|
|
51
|
+
they
|
|
52
|
+
this
|
|
53
|
+
to
|
|
54
|
+
was
|
|
55
|
+
will
|
|
56
|
+
with
|
|
57
|
+
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# The ASF licenses this file to You under the Apache License, Version 2.0
|
|
2
|
+
# (the "License"); you may not use this file except in compliance with
|
|
3
|
+
# the License. You may obtain a copy of the License at
|
|
4
|
+
#
|
|
5
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
#
|
|
7
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
8
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
9
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
10
|
+
# See the License for the specific language governing permissions and
|
|
11
|
+
# limitations under the License.
|
|
12
|
+
|
|
13
|
+
#-----------------------------------------------------------------------
|
|
14
|
+
#some test synonym mappings unlikely to appear in real input text
|
|
15
|
+
aaa => aaaa
|
|
16
|
+
bbb => bbbb1 bbbb2
|
|
17
|
+
ccc => cccc1,cccc2
|
|
18
|
+
a\=>a => b\=>b
|
|
19
|
+
a\,a => b\,b
|
|
20
|
+
fooaaa,baraaa,bazaaa
|
|
21
|
+
|
|
22
|
+
# Some synonym groups specific to this example
|
|
23
|
+
GB,gib,gigabyte,gigabytes
|
|
24
|
+
MB,mib,megabyte,megabytes
|
|
25
|
+
Television, Televisions, TV, TVs
|
|
26
|
+
#notice we use "gib" instead of "GiB" so any WordDelimiterFilter coming
|
|
27
|
+
#after us won't split it into two words.
|
|
28
|
+
|
|
29
|
+
# Synonym mappings can be used for spelling correction too
|
|
30
|
+
pixima => pixma
|
|
31
|
+
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/solr-1.3/start.jar
ADDED
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
describe Sunspot::Adapters::InstanceAdapter do
|
|
4
|
+
it "finds adapter by superclass" do
|
|
5
|
+
Sunspot::Adapters::InstanceAdapter::for(Model).should be(AbstractModelInstanceAdapter)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
it "finds adapter by mixin" do
|
|
9
|
+
Sunspot::Adapters::InstanceAdapter::for(MixModel).should be(MixInModelInstanceAdapter)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it 'throws NoAdapterError if anonymous module passed in' do
|
|
13
|
+
lambda do
|
|
14
|
+
Sunspot::Adapters::InstanceAdapter::for(Module.new)
|
|
15
|
+
end.should raise_error(Sunspot::NoAdapterError)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe Sunspot::Adapters::DataAccessor do
|
|
20
|
+
it "finds adapter by superclass" do
|
|
21
|
+
Sunspot::Adapters::DataAccessor::for(Model).should be(AbstractModelDataAccessor)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "finds adapter by mixin" do
|
|
25
|
+
Sunspot::Adapters::DataAccessor::for(MixModel).should be(MixInModelDataAccessor)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'throws NoAdapterError if anonymous module passed in' do
|
|
29
|
+
lambda do
|
|
30
|
+
Sunspot::Adapters::DataAccessor::for(Module.new)
|
|
31
|
+
end.should raise_error(Sunspot::NoAdapterError)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
describe "DSL bindings" do
|
|
4
|
+
it 'should give access to calling context\'s methods in search DSL' do
|
|
5
|
+
value = nil
|
|
6
|
+
session.search(Post) do
|
|
7
|
+
value = test_method
|
|
8
|
+
end
|
|
9
|
+
value.should == 'value'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it 'should give access to calling context\'s id method in search DSL' do
|
|
13
|
+
value = nil
|
|
14
|
+
session.search(Post) do
|
|
15
|
+
value = id
|
|
16
|
+
end
|
|
17
|
+
value.should == 16
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'should give access to calling context\'s methods in nested DSL block' do
|
|
21
|
+
value = nil
|
|
22
|
+
session.search(Post) do
|
|
23
|
+
any_of do
|
|
24
|
+
value = test_method
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
value.should == 'value'
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'should give access to calling context\'s methods in double-nested DSL block' do
|
|
31
|
+
value = nil
|
|
32
|
+
session.search(Post) do
|
|
33
|
+
any_of do
|
|
34
|
+
all_of do
|
|
35
|
+
value = test_method
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def test_method
|
|
44
|
+
'value'
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def id
|
|
48
|
+
16
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
require 'bigdecimal'
|
|
3
|
+
|
|
4
|
+
describe 'indexing attribute fields', :type => :indexer do
|
|
5
|
+
it 'should correctly index a stored string attribute field' do
|
|
6
|
+
session.index(post(:title => 'A Title'))
|
|
7
|
+
connection.should have_add_with(:title_ss => 'A Title')
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it 'should correctly index an integer attribute field' do
|
|
11
|
+
session.index(post(:blog_id => 4))
|
|
12
|
+
connection.should have_add_with(:blog_id_i => '4')
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'should correctly index a long attribute field' do
|
|
16
|
+
session.index(Namespaced::Comment.new(:hash => 2**30))
|
|
17
|
+
connection.should have_add_with(:hash_l => '1073741824')
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'should correctly index a float attribute field' do
|
|
21
|
+
session.index(post(:ratings_average => 2.23))
|
|
22
|
+
connection.should have_add_with(:average_rating_ft => '2.23')
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'should correctly index a double attribute field' do
|
|
26
|
+
session.index(Namespaced::Comment.new(:average_rating => 2.23))
|
|
27
|
+
connection.should have_add_with(:average_rating_e => '2.23')
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'should correctly index a trie integer attribute field' do
|
|
31
|
+
session.index(Photo.new(:size => 104856))
|
|
32
|
+
connection.should have_add_with(:size_it => '104856')
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it 'should correctly index a trie float attribute field' do
|
|
36
|
+
session.index(Photo.new(:average_rating => 2.23))
|
|
37
|
+
connection.should have_add_with(:average_rating_ft => '2.23')
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'should correctly index a trie time attribute field' do
|
|
41
|
+
session.index(Photo.new(:created_at => Time.parse('2009-12-16 15:00:00 -0400')))
|
|
42
|
+
connection.should have_add_with(:created_at_dt => '2009-12-16T19:00:00Z')
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it 'should allow indexing by a multiple-value field' do
|
|
46
|
+
session.index(post(:category_ids => [3, 14]))
|
|
47
|
+
connection.should have_add_with(:category_ids_im => ['3', '14'])
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'should not index a single-value field with newlines as multiple' do
|
|
51
|
+
session.index(post(:title => "Multi\nLine"))
|
|
52
|
+
connection.adds.last.first.field_by_name(:title_ss).value.should == "Multi\nLine"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it 'should correctly index a time field' do
|
|
56
|
+
session.index(
|
|
57
|
+
post(:published_at => Time.parse('1983-07-08 05:00:00 -0400'))
|
|
58
|
+
)
|
|
59
|
+
connection.should have_add_with(:published_at_dt => '1983-07-08T09:00:00Z')
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it 'should correctly index a time field that\'s after 32-bit Y2K' do
|
|
63
|
+
session.index(
|
|
64
|
+
post(:published_at => DateTime.parse('2050-07-08 05:00:00 -0400'))
|
|
65
|
+
)
|
|
66
|
+
connection.should have_add_with(:published_at_dt => '2050-07-08T09:00:00Z')
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it 'should correctly index a date field' do
|
|
70
|
+
session.index(post(:expire_date => Date.new(2009, 07, 13)))
|
|
71
|
+
connection.should have_add_with(:expire_date_d => '2009-07-13T00:00:00Z')
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it 'should correctly index a boolean field' do
|
|
75
|
+
session.index(post(:featured => true))
|
|
76
|
+
connection.should have_add_with(:featured_bs => 'true')
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it 'should correctly index a false boolean field' do
|
|
80
|
+
session.index(post(:featured => false))
|
|
81
|
+
connection.should have_add_with(:featured_bs => 'false')
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it 'should not index a nil boolean field' do
|
|
85
|
+
session.index(post)
|
|
86
|
+
connection.should_not have_add_with(:featured_bs)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it 'should index latitude and longitude as a pair' do
|
|
90
|
+
session.index(post(:coordinates => Sunspot::Util::Coordinates.new(40.7, -73.5)))
|
|
91
|
+
connection.should have_add_with(:coordinates_s => 'dr5xx3nytvgs')
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it 'should index latitude and longitude passed as non-Floats' do
|
|
95
|
+
coordinates = Sunspot::Util::Coordinates.new(
|
|
96
|
+
BigDecimal.new('40.7'), BigDecimal.new('-73.5'))
|
|
97
|
+
session.index(post(:coordinates => coordinates))
|
|
98
|
+
connection.should have_add_with(:coordinates_s => 'dr5xx3nytvgs')
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
it 'should correctly index an attribute field with block access' do
|
|
102
|
+
session.index(post(:title => 'The Blog Post'))
|
|
103
|
+
connection.should have_add_with(:sort_title_s => 'blog post')
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it 'should correctly index an attribute field with instance-external block access' do
|
|
107
|
+
session.index(post(:category_ids => [1, 2, 3]))
|
|
108
|
+
connection.should have_add_with(:primary_category_id_i => '1')
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it 'should correctly index a field that is defined on a superclass' do
|
|
112
|
+
Sunspot.setup(SuperClass) { string :author_name }
|
|
113
|
+
session.index(post(:author_name => 'Mat Brown'))
|
|
114
|
+
connection.should have_add_with(:author_name_s => 'Mat Brown')
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
it 'should throw a NoMethodError only if a nonexistent type is defined' do
|
|
118
|
+
lambda { Sunspot.setup(Post) { string :author_name }}.should_not raise_error
|
|
119
|
+
lambda { Sunspot.setup(Post) { bogus :journey }}.should raise_error(NoMethodError)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it 'should throw a NoMethodError if a nonexistent field argument is passed' do
|
|
123
|
+
lambda { Sunspot.setup(Post) { string :author_name, :bogus => :argument }}.should raise_error(ArgumentError)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
it 'should throw an ArgumentError if single-value field tries to index multiple values' do
|
|
127
|
+
lambda do
|
|
128
|
+
Sunspot.setup(Post) { string :author_name }
|
|
129
|
+
session.index(post(:author_name => ['Mat Brown', 'Matthew Brown']))
|
|
130
|
+
end.should raise_error(ArgumentError)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it 'should throw an ArgumentError if specifying more_like_this on type that does not support it' do
|
|
134
|
+
lambda do
|
|
135
|
+
Sunspot.setup(Post) { integer :popularity, :more_like_this => true }
|
|
136
|
+
end.should raise_error(ArgumentError)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
it 'should use a specified field name when the :as option is set' do
|
|
140
|
+
session.index(post(:title => 'A Title'))
|
|
141
|
+
connection.should have_add_with(:legacy_field_s => 'legacy A Title')
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it 'should use a specified field name when the :as option is set for array values' do
|
|
145
|
+
session.index(post(:title => 'Another Title'))
|
|
146
|
+
connection.should have_add_with(:legacy_array_field_sm => ['first string', 'second string'])
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
describe 'batch indexing', :type => :indexer do
|
|
4
|
+
it 'should send all batched adds in a single request' do
|
|
5
|
+
posts = Array.new(2) { Post.new }
|
|
6
|
+
session.batch do
|
|
7
|
+
for post in posts
|
|
8
|
+
session.index(post)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
connection.adds.length.should == 1
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'should add all batched adds' do
|
|
15
|
+
posts = Array.new(2) { Post.new }
|
|
16
|
+
session.batch do
|
|
17
|
+
for post in posts
|
|
18
|
+
session.index(post)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
add = connection.adds.last
|
|
22
|
+
connection.adds.first.map { |add| add.field_by_name(:id).value }.should ==
|
|
23
|
+
posts.map { |post| "Post #{post.id}" }
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'should not index changes to models that happen after index call' do
|
|
27
|
+
post = Post.new
|
|
28
|
+
session.batch do
|
|
29
|
+
session.index(post)
|
|
30
|
+
post.title = 'Title'
|
|
31
|
+
end
|
|
32
|
+
connection.adds.first.first.field_by_name(:title_ss).should be_nil
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it 'should batch an add and a delete' do
|
|
36
|
+
pending 'batching all operations'
|
|
37
|
+
connection.should_not_receive(:add)
|
|
38
|
+
connection.should_not_receive(:remove)
|
|
39
|
+
posts = Array.new(2) { Post.new }
|
|
40
|
+
session.batch do
|
|
41
|
+
session.index(posts[0])
|
|
42
|
+
session.remove(posts[1])
|
|
43
|
+
end
|
|
44
|
+
connection.adds
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
describe 'indexing dynamic fields' do
|
|
4
|
+
it 'indexes string data' do
|
|
5
|
+
session.index(post(:custom_string => { :test => 'string' }))
|
|
6
|
+
connection.should have_add_with(:"custom_string:test_ss" => 'string')
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it 'indexes integer data with virtual accessor' do
|
|
10
|
+
session.index(post(:category_ids => [1, 2]))
|
|
11
|
+
connection.should have_add_with(:"custom_integer:1_i" => '1', :"custom_integer:2_i" => '1')
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'indexes float data' do
|
|
15
|
+
session.index(post(:custom_fl => { :test => 1.5 }))
|
|
16
|
+
connection.should have_add_with(:"custom_float:test_fm" => '1.5')
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'indexes time data' do
|
|
20
|
+
session.index(post(:custom_time => { :test => Time.parse('2009-05-18 18:05:00 -0400') }))
|
|
21
|
+
connection.should have_add_with(:"custom_time:test_d" => '2009-05-18T22:05:00Z')
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'indexes boolean data' do
|
|
25
|
+
session.index(post(:custom_boolean => { :test => false }))
|
|
26
|
+
connection.should have_add_with(:"custom_boolean:test_b" => 'false')
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'indexes multiple values for a field' do
|
|
30
|
+
session.index(post(:custom_fl => { :test => [1.0, 2.1, 3.2] }))
|
|
31
|
+
connection.should have_add_with(:"custom_float:test_fm" => %w(1.0 2.1 3.2))
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'should throw a NoMethodError if dynamic text field defined' do
|
|
35
|
+
lambda do
|
|
36
|
+
Sunspot.setup(Post) do
|
|
37
|
+
dynamic_text :custom_text
|
|
38
|
+
end
|
|
39
|
+
end.should raise_error(NoMethodError)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
describe 'indexing fixed fields', :type => :indexer do
|
|
4
|
+
it 'should index id' do
|
|
5
|
+
session.index post
|
|
6
|
+
connection.should have_add_with(:id => "Post #{post.id}")
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it 'should index type' do
|
|
10
|
+
session.index post
|
|
11
|
+
connection.should have_add_with(:type => ['Post', 'SuperClass', 'MockRecord'])
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'should index class name' do
|
|
15
|
+
session.index post
|
|
16
|
+
connection.should have_add_with(:class_name => 'Post')
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'should index the array of objects supplied' do
|
|
20
|
+
posts = Array.new(2) { Post.new }
|
|
21
|
+
session.index posts
|
|
22
|
+
connection.should have_add_with(
|
|
23
|
+
{ :id => "Post #{posts.first.id}" },
|
|
24
|
+
{ :id => "Post #{posts.last.id}" }
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'should index an array containing more than one type of object' do
|
|
29
|
+
post1, comment, post2 = objects = [Post.new, Namespaced::Comment.new, Post.new]
|
|
30
|
+
session.index objects
|
|
31
|
+
connection.should have_add_with(
|
|
32
|
+
{ :id => "Post #{post1.id}", :type => ['Post', 'SuperClass', 'MockRecord'] },
|
|
33
|
+
{ :id => "Namespaced::Comment #{comment.id}", :type => ['Namespaced::Comment', 'MockRecord'] },
|
|
34
|
+
{ :id => "Post #{post2.id}", :type => ['Post', 'SuperClass', 'MockRecord'] }
|
|
35
|
+
)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'commits immediately after index! called' do
|
|
39
|
+
connection.should_receive(:add).ordered
|
|
40
|
+
connection.should_receive(:commit).ordered
|
|
41
|
+
session.index!(post)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it 'raises an ArgumentError if an attempt is made to index an object that has no configuration' do
|
|
45
|
+
lambda { session.index(Blog.new) }.should raise_error(Sunspot::NoSetupError)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it 'raises a NoAdapterError if class without adapter is indexed' do
|
|
49
|
+
lambda { session.index(User.new) }.should raise_error(Sunspot::NoAdapterError)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it 'raises an ArgumentError if a non-word character is included in the field name' do
|
|
53
|
+
lambda do
|
|
54
|
+
Sunspot.setup(Post) { string :"bad name" }
|
|
55
|
+
end.should raise_error(ArgumentError)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
describe 'indexing fulltext fields' do
|
|
4
|
+
it 'indexes text field' do
|
|
5
|
+
session.index(post(:title => 'A Title'))
|
|
6
|
+
connection.should have_add_with(:title_text => 'A Title')
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it 'indexes stored text field' do
|
|
10
|
+
session.index(post(:body => 'Test body'))
|
|
11
|
+
connection.should have_add_with(:body_textsv => 'Test body')
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'indexes text field with boost' do
|
|
15
|
+
session.index(post(:title => 'A Title'))
|
|
16
|
+
connection.adds.last.first.field_by_name(:title_text).attrs[:boost].should == 2
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'indexes multiple values for a text field' do
|
|
20
|
+
session.index(post(:body => %w(some title)))
|
|
21
|
+
connection.should have_add_with(:body_textsv => %w(some title))
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'indexes text via a block accessor' do
|
|
25
|
+
session.index(post(:title => 'backwards'))
|
|
26
|
+
connection.should have_add_with(:backwards_title_text => 'sdrawkcab')
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'indexes document level boost using block' do
|
|
30
|
+
session.index(post(:ratings_average => 4.0))
|
|
31
|
+
connection.adds.last.first.attrs[:boost].should == 1.25
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'indexes document level boost using attribute' do
|
|
35
|
+
session.index(Namespaced::Comment.new(:boost => 1.5))
|
|
36
|
+
connection.adds.last.first.attrs[:boost].should == 1.5
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'indexes document level boost defined statically' do
|
|
40
|
+
session.index(Photo.new)
|
|
41
|
+
connection.adds.last.first.attrs[:boost].should == 0.75
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
describe 'document removal', :type => :indexer do
|
|
4
|
+
it 'removes an object from the index' do
|
|
5
|
+
session.remove(post)
|
|
6
|
+
connection.should have_delete("Post #{post.id}")
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it 'removes an object by type and id' do
|
|
10
|
+
session.remove_by_id(Post, 1)
|
|
11
|
+
connection.should have_delete('Post 1')
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'removes an object by type and id and immediately commits' do
|
|
15
|
+
connection.should_receive(:delete_by_id).with(['Post 1']).ordered
|
|
16
|
+
connection.should_receive(:commit).ordered
|
|
17
|
+
session.remove_by_id!(Post, 1)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'removes an object from the index and immediately commits' do
|
|
21
|
+
connection.should_receive(:delete_by_id).ordered
|
|
22
|
+
connection.should_receive(:commit).ordered
|
|
23
|
+
session.remove!(post)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'removes everything from the index' do
|
|
27
|
+
session.remove_all
|
|
28
|
+
connection.should have_delete_by_query("*:*")
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'removes everything from the index and immediately commits' do
|
|
32
|
+
connection.should_receive(:delete_by_query).ordered
|
|
33
|
+
connection.should_receive(:commit).ordered
|
|
34
|
+
session.remove_all!
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'removes everything of a given class from the index' do
|
|
38
|
+
session.remove_all(Post)
|
|
39
|
+
connection.should have_delete_by_query("type:Post")
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'correctly escapes namespaced classes when removing everything from the index' do
|
|
43
|
+
connection.should_receive(:delete_by_query).with('type:Namespaced\:\:Comment')
|
|
44
|
+
session.remove_all(Namespaced::Comment)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it 'should remove by query' do
|
|
48
|
+
session.remove(Post) do
|
|
49
|
+
with(:title, 'monkeys')
|
|
50
|
+
end
|
|
51
|
+
connection.should have_delete_by_query("(type:Post AND title_ss:monkeys)")
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.join(File.dirname(__FILE__), '..'))
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
describe 'indexer', :type => :indexer do
|
|
4
|
+
it 'should completely wipe setup if class redefined (reloaded)' do
|
|
5
|
+
Object::ReloadableClass = Class.new(MockRecord)
|
|
6
|
+
Sunspot.setup(ReloadableClass) { string(:title) }
|
|
7
|
+
Object.class_eval { remove_const(:ReloadableClass) }
|
|
8
|
+
Object::ReloadableClass = Class.new(MockRecord)
|
|
9
|
+
Sunspot.setup(ReloadableClass) {}
|
|
10
|
+
lambda do
|
|
11
|
+
Sunspot.search(ReloadableClass) { with(:title, 'title') }
|
|
12
|
+
end.should raise_error(Sunspot::UnrecognizedFieldError)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
shared_examples_for "query with advanced manipulation" do
|
|
4
|
+
describe 'adjust_solr_params' do
|
|
5
|
+
before :each do
|
|
6
|
+
search do
|
|
7
|
+
adjust_solr_params do |params|
|
|
8
|
+
params[:rows] = 40
|
|
9
|
+
params[:qt] = 'complicated'
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "modifies existing param" do
|
|
15
|
+
connection.should have_last_search_with(:rows => 40)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "adds new param" do
|
|
19
|
+
connection.should have_last_search_with(:qt => 'complicated')
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe 'request_handler' do
|
|
24
|
+
before :each do
|
|
25
|
+
connection.expected_handler = :myRequestHandler
|
|
26
|
+
search do
|
|
27
|
+
request_handler :myRequestHandler
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'should use specified request handler' do
|
|
32
|
+
connection.should have_last_search_with({})
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|