thinking-sphinx 5.5.1 → 5.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +6 -7
- data/Appraisals +6 -0
- data/CHANGELOG.markdown +19 -0
- data/README.textile +4 -4
- data/bin/loadsphinx +15 -4
- data/lib/thinking_sphinx/active_record/base.rb +23 -4
- data/lib/thinking_sphinx/active_record/filter_reflection.rb +1 -1
- data/lib/thinking_sphinx/active_record/log_subscriber.rb +16 -4
- data/lib/thinking_sphinx/commands/clear_real_time.rb +1 -1
- data/lib/thinking_sphinx/commands/clear_sql.rb +1 -1
- data/lib/thinking_sphinx/configuration/minimum_fields.rb +8 -8
- data/lib/thinking_sphinx/masks/scopes_mask.rb +6 -0
- data/lib/thinking_sphinx/processor.rb +34 -8
- data/lib/thinking_sphinx/search/context.rb +1 -0
- data/lib/thinking_sphinx/search.rb +2 -2
- data/lib/thinking_sphinx/test.rb +1 -1
- data/lib/thinking_sphinx.rb +4 -0
- data/spec/acceptance/attribute_access_spec.rb +4 -4
- data/spec/acceptance/excerpts_spec.rb +2 -2
- data/spec/acceptance/grouping_by_attributes_spec.rb +20 -20
- data/spec/acceptance/real_time_updates_spec.rb +61 -1
- data/spec/acceptance/searching_across_models_spec.rb +7 -0
- data/spec/acceptance/searching_with_filters_spec.rb +8 -8
- data/spec/acceptance/searching_within_a_model_spec.rb +14 -0
- data/spec/acceptance/sorting_search_results_spec.rb +15 -15
- data/spec/acceptance/sphinx_scopes_spec.rb +23 -16
- data/spec/internal/app/indices/article_index.rb +6 -0
- data/spec/internal/app/indices/book_index.rb +1 -1
- data/spec/internal/app/models/book.rb +5 -5
- data/spec/internal/db/schema.rb +1 -1
- data/spec/thinking_sphinx/active_record/callbacks/update_callbacks_spec.rb +1 -1
- data/spec/thinking_sphinx/active_record/interpreter_spec.rb +5 -5
- data/spec/thinking_sphinx/commands/clear_real_time_spec.rb +2 -2
- data/spec/thinking_sphinx/commands/clear_sql_spec.rb +2 -2
- data/spec/thinking_sphinx/configuration/minimum_fields_spec.rb +12 -2
- data/spec/thinking_sphinx/excerpter_spec.rb +3 -2
- data/spec/thinking_sphinx/index_spec.rb +2 -2
- data/spec/thinking_sphinx/middlewares/sphinxql_spec.rb +4 -4
- data/spec/thinking_sphinx/panes/excerpts_pane_spec.rb +1 -1
- data/spec/thinking_sphinx/real_time/interpreter_spec.rb +5 -5
- data/spec/thinking_sphinx_spec.rb +2 -2
- data/thinking-sphinx.gemspec +3 -3
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9312857a98ecddb77183d29a5967d0a7b9bd1e5aecd4ba058931281d15ae073c
|
4
|
+
data.tar.gz: 2cad1197f8f6f99fd8007cc532d4ae0709bae06e3ecd6b064a443817842753f5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '08c9725de4f436fbcf36b71a91940e5920d03b40f237dacd64a7e6ecd8dceffc917b9da353992e677538ddee12cf34b9065bf70bbbfcb698b9dfa5c68e51305c'
|
7
|
+
data.tar.gz: 43a8d688ca74d7e7bdb1d30368aa6ae5908b84250b0e60e37cd484143d91ac2cd2dbde8ab8115aa7538e09ff6619de13ba1c95c603baa224e77c8d46bb7d075f
|
data/.github/workflows/ci.yml
CHANGED
@@ -4,14 +4,13 @@ on: [push, pull_request]
|
|
4
4
|
|
5
5
|
jobs:
|
6
6
|
sphinx:
|
7
|
-
runs-on:
|
7
|
+
runs-on: ubuntu-22.04
|
8
8
|
|
9
9
|
strategy:
|
10
10
|
fail-fast: false
|
11
11
|
matrix:
|
12
|
-
os: [ 'ubuntu-18.04' ]
|
13
12
|
ruby: [ '2.7', '3.0', '3.1', '3.2' ]
|
14
|
-
rails: [ '5_0', '5_1', '5_2', '6_0', '6_1', '7_0' ]
|
13
|
+
rails: [ '5_0', '5_1', '5_2', '6_0', '6_1', '7_0', '7_1' ]
|
15
14
|
database: [ 'mysql2', 'postgresql' ]
|
16
15
|
sphinx_version: [ '2.2.11', '3.4.1' ]
|
17
16
|
sphinx_engine: [ 'sphinx' ]
|
@@ -58,7 +57,7 @@ jobs:
|
|
58
57
|
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
59
58
|
|
60
59
|
steps:
|
61
|
-
- uses: actions/checkout@
|
60
|
+
- uses: actions/checkout@v4
|
62
61
|
- uses: ./.github/actions/test
|
63
62
|
with:
|
64
63
|
ruby-version: ${{ matrix.ruby }}
|
@@ -69,15 +68,15 @@ jobs:
|
|
69
68
|
timeout-minutes: 12
|
70
69
|
|
71
70
|
manticore:
|
72
|
-
runs-on: ubuntu-
|
71
|
+
runs-on: ubuntu-22.04
|
73
72
|
|
74
73
|
strategy:
|
75
74
|
fail-fast: false
|
76
75
|
matrix:
|
77
76
|
ruby: [ '2.7', '3.0', '3.1', '3.2' ]
|
78
|
-
rails: [ '5_0', '5_1', '5_2', '6_0', '6_1', '7_0' ]
|
77
|
+
rails: [ '5_0', '5_1', '5_2', '6_0', '6_1', '7_0', '7_1' ]
|
79
78
|
database: [ 'mysql2', 'postgresql' ]
|
80
|
-
sphinx_version: [ '
|
79
|
+
sphinx_version: [ '4.0.2', '6.0.0' ]
|
81
80
|
sphinx_engine: [ 'manticore' ]
|
82
81
|
exclude:
|
83
82
|
- ruby: '3.0'
|
data/Appraisals
CHANGED
@@ -45,3 +45,9 @@ appraise 'rails_7_0' do
|
|
45
45
|
gem 'mysql2', '~> 0.5.0', :platform => :ruby
|
46
46
|
gem 'pg', '~> 1.0', :platform => :ruby
|
47
47
|
end if RUBY_PLATFORM != 'java' && RUBY_VERSION.to_f >= 2.7
|
48
|
+
|
49
|
+
appraise 'rails_7_1' do
|
50
|
+
gem 'rails', '~> 7.1.0'
|
51
|
+
gem 'mysql2', '~> 0.5.0', :platform => :ruby
|
52
|
+
gem 'pg', '~> 1.0', :platform => :ruby
|
53
|
+
end if RUBY_PLATFORM != 'java' && RUBY_VERSION.to_f >= 2.7
|
data/CHANGELOG.markdown
CHANGED
@@ -2,6 +2,25 @@
|
|
2
2
|
|
3
3
|
All notable changes to this project (at least, from v3.0.0 onwards) are documented in this file.
|
4
4
|
|
5
|
+
## 5.6.0 - 2024-07-07
|
6
|
+
|
7
|
+
### Added
|
8
|
+
|
9
|
+
* Support for Manticore 6.0 ([#1242](https://github.com/pat/thinking-sphinx/pull/1242))
|
10
|
+
* `sphinx`-prefixed search methods, in case the standard `search` is overridden from something unrelated. ([#1265](https://github.com/pat/thinking-sphinx/pull/1265))
|
11
|
+
* `none` / `search_none` scopes that can be chained to searches and will return no results.
|
12
|
+
* Added `ThinkingSphinx::Processor#sync` to synchronise updates/deletions based on a real-time index's scope, by @akostadinov in [@1258](https://github.com/pat/thinking-sphinx/pull/1258).
|
13
|
+
|
14
|
+
### Changed
|
15
|
+
|
16
|
+
* Improved Rails 7.1 support, by @jdelstrother in [#1252](https://github.com/pat/thinking-sphinx/pull/1252).
|
17
|
+
|
18
|
+
### Fixed
|
19
|
+
|
20
|
+
* Handle both SQL and RT indices correctly for inheritance column checks, by @akostadinov in [#1249](https://github.com/pat/thinking-sphinx/pull/1249).
|
21
|
+
* Ensure tests and CI work with recent Manticore versions, by @jdelstrother in [#1263](https://github.com/pat/thinking-sphinx/pull/1263).
|
22
|
+
* Use `rm -rf` to delete test and temporary directories (instead of `rm -r`).
|
23
|
+
|
5
24
|
## 5.5.1 - 2022-12-31
|
6
25
|
|
7
26
|
[Release Notes](https://github.com/pat/thinking-sphinx/releases/tag/v5.5.1)
|
data/README.textile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
h1. Thinking Sphinx
|
2
2
|
|
3
|
-
Thinking Sphinx is a library for connecting ActiveRecord to the Sphinx full-text search tool, and integrates closely with Rails (but also works with other Ruby web frameworks). The current release is v5.
|
3
|
+
Thinking Sphinx is a library for connecting ActiveRecord to the Sphinx full-text search tool, and integrates closely with Rails (but also works with other Ruby web frameworks). The current release is v5.6.0.
|
4
4
|
|
5
5
|
h2. Upgrading
|
6
6
|
|
@@ -31,7 +31,7 @@ The current release of Thinking Sphinx works with the following versions of its
|
|
31
31
|
|_. Library |_. Minimum |_. Tested Against |
|
32
32
|
| Ruby | v2.4 | v2.4, v2.5, v2.6, v2.7, v3.0, v3.1, v3.2 |
|
33
33
|
| Sphinx | v2.2.11 | v2.2.11, v3.4.1 |
|
34
|
-
| Manticore | v2.8 |
|
34
|
+
| Manticore | v2.8 | v4.0, v6.0 |
|
35
35
|
| ActiveRecord | v4.2 | v4.2..v7.0 |
|
36
36
|
|
37
37
|
It _might_ work with older versions of Ruby, but it's highly recommended to update to a supported release.
|
@@ -42,7 +42,7 @@ h3. Sphinx or Manticore
|
|
42
42
|
|
43
43
|
If you're using Sphinx, v2.2.11 is recommended even though it's quite old, as it works well with PostgreSQL databases (but if you're using MySQL - or real-time indices - then v3.3.1 should also be fine).
|
44
44
|
|
45
|
-
If you're opting for Manticore instead, v2.8 or newer works, but
|
45
|
+
If you're opting for Manticore instead, v2.8 or newer works, but v4 or newer is recommended as that's what is actively tested against. The v4.2 and 5.0 releases had bugs with facet searching, but that's been fixed in Manticore v6.0.
|
46
46
|
|
47
47
|
h3. Rails and ActiveRecord
|
48
48
|
|
@@ -81,4 +81,4 @@ You can then run the unit tests with @rake spec:unit@, the acceptance tests with
|
|
81
81
|
|
82
82
|
h2. Licence
|
83
83
|
|
84
|
-
Copyright (c) 2007-
|
84
|
+
Copyright (c) 2007-2024, Thinking Sphinx is developed and maintained by Pat Allan, and is released under the open MIT Licence. Many thanks to "all who have contributed patches":https://github.com/pat/thinking-sphinx/contributors.
|
data/bin/loadsphinx
CHANGED
@@ -70,15 +70,26 @@ load_manticore () {
|
|
70
70
|
url="https://repo.manticoresearch.com/repository/manticoresearch_focal/dists/focal/main/binary-amd64/manticore_3.5.4-210107-f70faec5_amd64.deb";;
|
71
71
|
4.0.2)
|
72
72
|
url="https://repo.manticoresearch.com/repository/manticoresearch_focal/dists/focal/main/binary-amd64/manticore_4.0.2-210921-af497f245_amd64.deb";;
|
73
|
+
4.2.0)
|
74
|
+
url="https://repo.manticoresearch.com/repository/manticoresearch_focal/dists/focal/main/binary-amd64/manticore_4.2.0-211223-15e927b28_amd64.deb";;
|
75
|
+
6.0.0)
|
76
|
+
url="skipped";;
|
73
77
|
*)
|
74
78
|
echo "No Manticore version $version available"
|
75
79
|
exit 1;;
|
76
80
|
esac
|
77
81
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
+
if [ "$version" == "6.0.0" ]; then
|
83
|
+
curl --location https://repo.manticoresearch.com/manticore-repo.noarch.deb -o repo.deb
|
84
|
+
sudo dpkg -i repo.deb
|
85
|
+
sudo apt update
|
86
|
+
sudo apt install manticore
|
87
|
+
else
|
88
|
+
sudo apt-get install default-libmysqlclient-dev
|
89
|
+
curl --location $url -o manticore.deb
|
90
|
+
sudo dpkg -i ./manticore.deb
|
91
|
+
sudo apt-get install -f
|
92
|
+
fi
|
82
93
|
}
|
83
94
|
|
84
95
|
if [ "$engine" == "sphinx" ]; then
|
@@ -4,6 +4,21 @@ module ThinkingSphinx::ActiveRecord::Base
|
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
6
|
included do
|
7
|
+
# Avoid method collisions for public Thinking Sphinx methods added to all
|
8
|
+
# ActiveRecord models. The `sphinx_`-prefixed versions will always exist,
|
9
|
+
# and the non-prefixed versions will be added if a method of that name
|
10
|
+
# doesn't already exist.
|
11
|
+
#
|
12
|
+
# If a method is overwritten later by something else, that's also fine - the
|
13
|
+
# prefixed versions will still be there.
|
14
|
+
class_module = ThinkingSphinx::ActiveRecord::Base::ClassMethods
|
15
|
+
class_module.public_instance_methods.each do |method_name|
|
16
|
+
short_method = method_name.to_s.delete_prefix("sphinx_").to_sym
|
17
|
+
next if methods.include?(short_method)
|
18
|
+
|
19
|
+
define_singleton_method(short_method, method(method_name))
|
20
|
+
end
|
21
|
+
|
7
22
|
if ActiveRecord::VERSION::STRING.to_i >= 5
|
8
23
|
[
|
9
24
|
::ActiveRecord::Reflection::HasManyReflection,
|
@@ -25,24 +40,28 @@ module ThinkingSphinx::ActiveRecord::Base
|
|
25
40
|
end
|
26
41
|
|
27
42
|
module ClassMethods
|
28
|
-
def
|
43
|
+
def sphinx_facets(query = nil, options = {})
|
29
44
|
merge_search ThinkingSphinx.facets, query, options
|
30
45
|
end
|
31
46
|
|
32
|
-
def
|
47
|
+
def sphinx_search(query = nil, options = {})
|
33
48
|
merge_search ThinkingSphinx.search, query, options
|
34
49
|
end
|
35
50
|
|
36
|
-
def
|
51
|
+
def sphinx_search_count(query = nil, options = {})
|
37
52
|
search_for_ids(query, options).total_entries
|
38
53
|
end
|
39
54
|
|
40
|
-
def
|
55
|
+
def sphinx_search_for_ids(query = nil, options = {})
|
41
56
|
ThinkingSphinx::Search::Merger.new(
|
42
57
|
search(query, options)
|
43
58
|
).merge! nil, :ids_only => true
|
44
59
|
end
|
45
60
|
|
61
|
+
def sphinx_search_none
|
62
|
+
merge_search ThinkingSphinx.search, nil, none: true
|
63
|
+
end
|
64
|
+
|
46
65
|
private
|
47
66
|
|
48
67
|
def default_sphinx_scope?
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
class ThinkingSphinx::ActiveRecord::FilterReflection
|
4
4
|
ReflectionGenerator = case ActiveRecord::VERSION::STRING.to_f
|
5
|
-
when 5.2..7.
|
5
|
+
when 5.2..7.1
|
6
6
|
ThinkingSphinx::ActiveRecord::Depolymorph::OverriddenReflection
|
7
7
|
when 4.1..5.1
|
8
8
|
ThinkingSphinx::ActiveRecord::Depolymorph::AssociationReflection
|
@@ -2,24 +2,36 @@
|
|
2
2
|
|
3
3
|
class ThinkingSphinx::ActiveRecord::LogSubscriber < ActiveSupport::LogSubscriber
|
4
4
|
def guard(event)
|
5
|
-
identifier =
|
5
|
+
identifier = colored_text "Sphinx"
|
6
6
|
warn " #{identifier} #{event.payload[:guard]}"
|
7
7
|
end
|
8
8
|
|
9
9
|
def message(event)
|
10
|
-
identifier =
|
10
|
+
identifier = colored_text "Sphinx"
|
11
11
|
debug " #{identifier} #{event.payload[:message]}"
|
12
12
|
end
|
13
13
|
|
14
14
|
def query(event)
|
15
|
-
identifier =
|
15
|
+
identifier = colored_text("Sphinx Query (%.1fms)" % event.duration)
|
16
16
|
debug " #{identifier} #{event.payload[:query]}"
|
17
17
|
end
|
18
18
|
|
19
19
|
def caution(event)
|
20
|
-
identifier =
|
20
|
+
identifier = colored_text "Sphinx"
|
21
21
|
warn " #{identifier} #{event.payload[:caution]}"
|
22
22
|
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
if Rails.gem_version >= Gem::Version.new("7.1.0")
|
27
|
+
def colored_text(text)
|
28
|
+
color text, GREEN, bold: true
|
29
|
+
end
|
30
|
+
else
|
31
|
+
def colored_text(text)
|
32
|
+
color text, GREEN, true
|
33
|
+
end
|
34
|
+
end
|
23
35
|
end
|
24
36
|
|
25
37
|
ThinkingSphinx::ActiveRecord::LogSubscriber.attach_to :thinking_sphinx
|
@@ -7,7 +7,7 @@ class ThinkingSphinx::Commands::ClearRealTime < ThinkingSphinx::Commands::Base
|
|
7
7
|
Dir["#{index.path}.*"].each { |path| FileUtils.rm path }
|
8
8
|
end
|
9
9
|
|
10
|
-
FileUtils.
|
10
|
+
FileUtils.rm_rf(binlog_path) if File.exist?(binlog_path)
|
11
11
|
end
|
12
12
|
|
13
13
|
private
|
@@ -7,7 +7,7 @@ class ThinkingSphinx::Commands::ClearSQL < ThinkingSphinx::Commands::Base
|
|
7
7
|
Dir["#{index.path}.*"].each { |path| FileUtils.rm path }
|
8
8
|
end
|
9
9
|
|
10
|
-
FileUtils.
|
10
|
+
FileUtils.rm_rf Dir["#{configuration.indices_location}/ts-*.tmp"]
|
11
11
|
end
|
12
12
|
|
13
13
|
private
|
@@ -18,19 +18,19 @@ class ThinkingSphinx::Configuration::MinimumFields
|
|
18
18
|
attr_reader :indices
|
19
19
|
|
20
20
|
def field_collections
|
21
|
-
|
22
|
-
|
23
|
-
end
|
24
|
-
|
25
|
-
def indices_of_type(type)
|
26
|
-
indices.select { |index| index.type == type }
|
21
|
+
indices_without_inheritance_of_type('plain').collect(&:sources).flatten +
|
22
|
+
indices_without_inheritance_of_type('rt')
|
27
23
|
end
|
28
24
|
|
29
25
|
def inheritance_columns?(index)
|
30
26
|
index.model.table_exists? && index.model.column_names.include?(index.model.inheritance_column)
|
31
27
|
end
|
32
28
|
|
33
|
-
def
|
34
|
-
|
29
|
+
def indices_without_inheritance_of_type(type)
|
30
|
+
indices_without_inheritance.select { |index| index.type == type }
|
31
|
+
end
|
32
|
+
|
33
|
+
def indices_without_inheritance
|
34
|
+
indices.reject(&method(:inheritance_columns?))
|
35
35
|
end
|
36
36
|
end
|
@@ -26,6 +26,12 @@ class ThinkingSphinx::Masks::ScopesMask
|
|
26
26
|
search query, options.merge(:ids_only => true)
|
27
27
|
end
|
28
28
|
|
29
|
+
def none
|
30
|
+
ThinkingSphinx::Search::Merger.new(@search).merge! nil, :none => true
|
31
|
+
end
|
32
|
+
|
33
|
+
alias_method :search_none, :none
|
34
|
+
|
29
35
|
private
|
30
36
|
|
31
37
|
def apply_scope(scope, *args)
|
@@ -1,6 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class ThinkingSphinx::Processor
|
4
|
+
# @param instance [ActiveRecord::Base] an ActiveRecord object
|
5
|
+
# @param model [Class] the ActiveRecord model of the instance
|
6
|
+
# @param id [Integer] the instance indices primary key (might be different from model primary key)
|
4
7
|
def initialize(instance: nil, model: nil, id: nil)
|
5
8
|
raise ArgumentError if instance.nil? && (model.nil? || id.nil?)
|
6
9
|
|
@@ -12,16 +15,27 @@ class ThinkingSphinx::Processor
|
|
12
15
|
def delete
|
13
16
|
return if instance&.new_record?
|
14
17
|
|
15
|
-
indices.each { |index|
|
16
|
-
ThinkingSphinx::Deletion.perform(
|
17
|
-
index, id || instance.public_send(index.primary_key)
|
18
|
-
)
|
19
|
-
}
|
18
|
+
indices.each { |index| perform_deletion(index) }
|
20
19
|
end
|
21
20
|
|
21
|
+
# Will insert instance into all matching indices
|
22
22
|
def upsert
|
23
23
|
real_time_indices.each do |index|
|
24
|
-
|
24
|
+
found = loaded_instance(index)
|
25
|
+
ThinkingSphinx::RealTime::Transcriber.new(index).copy found if found
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Will upsert or delete instance into all matching indices based on index scope
|
30
|
+
def sync
|
31
|
+
real_time_indices.each do |index|
|
32
|
+
found = find_in(index)
|
33
|
+
|
34
|
+
if found
|
35
|
+
ThinkingSphinx::RealTime::Transcriber.new(index).copy found
|
36
|
+
else
|
37
|
+
ThinkingSphinx::Deletion.perform(index, index_id(index))
|
38
|
+
end
|
25
39
|
end
|
26
40
|
end
|
27
41
|
|
@@ -35,11 +49,23 @@ class ThinkingSphinx::Processor
|
|
35
49
|
).to_a
|
36
50
|
end
|
37
51
|
|
38
|
-
def
|
39
|
-
|
52
|
+
def find_in(index)
|
53
|
+
index.scope.find_by(index.primary_key => index_id(index))
|
54
|
+
end
|
55
|
+
|
56
|
+
def loaded_instance(index)
|
57
|
+
instance || find_in(index)
|
40
58
|
end
|
41
59
|
|
42
60
|
def real_time_indices
|
43
61
|
indices.select { |index| index.is_a? ThinkingSphinx::RealTime::Index }
|
44
62
|
end
|
63
|
+
|
64
|
+
def perform_deletion(index)
|
65
|
+
ThinkingSphinx::Deletion.perform(index, index_id(index))
|
66
|
+
end
|
67
|
+
|
68
|
+
def index_id(index)
|
69
|
+
id || instance.public_send(index.primary_key)
|
70
|
+
end
|
45
71
|
end
|
@@ -12,7 +12,7 @@ class ThinkingSphinx::Search < Array
|
|
12
12
|
[
|
13
13
|
:classes, :conditions, :excerpts, :geo, :group_by, :ids_only,
|
14
14
|
:ignore_scopes, :indices, :limit, :masks, :max_matches, :middleware,
|
15
|
-
:offset, :order, :order_group_by, :page, :per_page, :populate,
|
15
|
+
:none, :offset, :order, :order_group_by, :page, :per_page, :populate,
|
16
16
|
:retry_stale, :select, :skip_sti, :sql, :star, :with, :with_all, :without,
|
17
17
|
:without_ids
|
18
18
|
] +
|
@@ -92,7 +92,7 @@ class ThinkingSphinx::Search < Array
|
|
92
92
|
def populate
|
93
93
|
return self if @populated
|
94
94
|
|
95
|
-
middleware.call [context]
|
95
|
+
middleware.call [context] unless options[:none]
|
96
96
|
@populated = true
|
97
97
|
|
98
98
|
self
|
data/lib/thinking_sphinx/test.rb
CHANGED
data/lib/thinking_sphinx.rb
CHANGED
@@ -4,17 +4,17 @@ require 'acceptance/spec_helper'
|
|
4
4
|
|
5
5
|
describe 'Accessing attributes directly via search results', :live => true do
|
6
6
|
it "allows access to attribute values" do
|
7
|
-
Book.create! :title => 'American Gods', :
|
7
|
+
Book.create! :title => 'American Gods', :publishing_year => 2001
|
8
8
|
index
|
9
9
|
|
10
10
|
search = Book.search('gods')
|
11
11
|
search.context[:panes] << ThinkingSphinx::Panes::AttributesPane
|
12
12
|
|
13
|
-
expect(search.first.sphinx_attributes['
|
13
|
+
expect(search.first.sphinx_attributes['publishing_year']).to eq(2001)
|
14
14
|
end
|
15
15
|
|
16
16
|
it "provides direct access to the search weight/relevance scores" do
|
17
|
-
Book.create! :title => 'American Gods', :
|
17
|
+
Book.create! :title => 'American Gods', :publishing_year => 2001
|
18
18
|
index
|
19
19
|
|
20
20
|
search = Book.search 'gods', :select => "*, weight()"
|
@@ -37,7 +37,7 @@ describe 'Accessing attributes directly via search results', :live => true do
|
|
37
37
|
end
|
38
38
|
|
39
39
|
it "can enumerate with the weight" do
|
40
|
-
gods = Book.create! :title => 'American Gods', :
|
40
|
+
gods = Book.create! :title => 'American Gods', :publishing_year => 2001
|
41
41
|
index
|
42
42
|
|
43
43
|
search = Book.search 'gods', :select => "*, weight()"
|
@@ -5,7 +5,7 @@ require 'acceptance/spec_helper'
|
|
5
5
|
|
6
6
|
describe 'Accessing excerpts for methods on a search result', :live => true do
|
7
7
|
it "returns excerpts for a given method" do
|
8
|
-
Book.create! :title => 'American Gods', :
|
8
|
+
Book.create! :title => 'American Gods', :publishing_year => 2001
|
9
9
|
index
|
10
10
|
|
11
11
|
search = Book.search('gods')
|
@@ -16,7 +16,7 @@ describe 'Accessing excerpts for methods on a search result', :live => true do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
it "handles UTF-8 text for excerpts" do
|
19
|
-
Book.create! :title => 'Война и миръ', :
|
19
|
+
Book.create! :title => 'Война и миръ', :publishing_year => 1869
|
20
20
|
index
|
21
21
|
|
22
22
|
search = Book.search 'миръ'
|
@@ -4,36 +4,36 @@ require 'acceptance/spec_helper'
|
|
4
4
|
|
5
5
|
describe 'Grouping search results by attributes', :live => true do
|
6
6
|
it "groups by the provided attribute" do
|
7
|
-
snuff = Book.create! :title => 'Snuff', :
|
8
|
-
earth = Book.create! :title => 'The Long Earth', :
|
9
|
-
dodger = Book.create! :title => 'Dodger', :
|
7
|
+
snuff = Book.create! :title => 'Snuff', :publishing_year => 2011
|
8
|
+
earth = Book.create! :title => 'The Long Earth', :publishing_year => 2012
|
9
|
+
dodger = Book.create! :title => 'Dodger', :publishing_year => 2012
|
10
10
|
|
11
11
|
index
|
12
12
|
|
13
|
-
expect(Book.search(:group_by => :
|
13
|
+
expect(Book.search(:group_by => :publishing_year).to_a).to eq([snuff, earth])
|
14
14
|
end
|
15
15
|
|
16
16
|
it "allows sorting within the group" do
|
17
|
-
snuff = Book.create! :title => 'Snuff', :
|
18
|
-
earth = Book.create! :title => 'The Long Earth', :
|
19
|
-
dodger = Book.create! :title => 'Dodger', :
|
17
|
+
snuff = Book.create! :title => 'Snuff', :publishing_year => 2011
|
18
|
+
earth = Book.create! :title => 'The Long Earth', :publishing_year => 2012
|
19
|
+
dodger = Book.create! :title => 'Dodger', :publishing_year => 2012
|
20
20
|
|
21
21
|
index
|
22
22
|
|
23
|
-
expect(Book.search(:group_by => :
|
23
|
+
expect(Book.search(:group_by => :publishing_year, :order_group_by => 'title ASC').to_a).
|
24
24
|
to eq([snuff, dodger])
|
25
25
|
end
|
26
26
|
|
27
27
|
it "allows enumerating by count" do
|
28
|
-
snuff = Book.create! :title => 'Snuff', :
|
29
|
-
earth = Book.create! :title => 'The Long Earth', :
|
30
|
-
dodger = Book.create! :title => 'Dodger', :
|
28
|
+
snuff = Book.create! :title => 'Snuff', :publishing_year => 2011
|
29
|
+
earth = Book.create! :title => 'The Long Earth', :publishing_year => 2012
|
30
|
+
dodger = Book.create! :title => 'Dodger', :publishing_year => 2012
|
31
31
|
|
32
32
|
index
|
33
33
|
|
34
34
|
expectations = [[snuff, 1], [earth, 2]]
|
35
35
|
|
36
|
-
Book.search(:group_by => :
|
36
|
+
Book.search(:group_by => :publishing_year).each_with_count do |book, count|
|
37
37
|
expectation = expectations.shift
|
38
38
|
|
39
39
|
expect(book).to eq(expectation.first)
|
@@ -42,15 +42,15 @@ describe 'Grouping search results by attributes', :live => true do
|
|
42
42
|
end
|
43
43
|
|
44
44
|
it "allows enumerating by group" do
|
45
|
-
snuff = Book.create! :title => 'Snuff', :
|
46
|
-
earth = Book.create! :title => 'The Long Earth', :
|
47
|
-
dodger = Book.create! :title => 'Dodger', :
|
45
|
+
snuff = Book.create! :title => 'Snuff', :publishing_year => 2011
|
46
|
+
earth = Book.create! :title => 'The Long Earth', :publishing_year => 2012
|
47
|
+
dodger = Book.create! :title => 'Dodger', :publishing_year => 2012
|
48
48
|
|
49
49
|
index
|
50
50
|
|
51
51
|
expectations = [[snuff, 2011], [earth, 2012]]
|
52
52
|
|
53
|
-
Book.search(:group_by => :
|
53
|
+
Book.search(:group_by => :publishing_year).each_with_group do |book, group|
|
54
54
|
expectation = expectations.shift
|
55
55
|
|
56
56
|
expect(book).to eq(expectation.first)
|
@@ -59,14 +59,14 @@ describe 'Grouping search results by attributes', :live => true do
|
|
59
59
|
end
|
60
60
|
|
61
61
|
it "allows enumerating by group and count" do
|
62
|
-
snuff = Book.create! :title => 'Snuff', :
|
63
|
-
earth = Book.create! :title => 'The Long Earth', :
|
64
|
-
dodger = Book.create! :title => 'Dodger', :
|
62
|
+
snuff = Book.create! :title => 'Snuff', :publishing_year => 2011
|
63
|
+
earth = Book.create! :title => 'The Long Earth', :publishing_year => 2012
|
64
|
+
dodger = Book.create! :title => 'Dodger', :publishing_year => 2012
|
65
65
|
|
66
66
|
index
|
67
67
|
|
68
68
|
expectations = [[snuff, 2011, 1], [earth, 2012, 2]]
|
69
|
-
search = Book.search(:group_by => :
|
69
|
+
search = Book.search(:group_by => :publishing_year)
|
70
70
|
|
71
71
|
search.each_with_group_and_count do |book, group, count|
|
72
72
|
expectation = expectations.shift
|
@@ -28,7 +28,7 @@ describe 'Updates to records in real-time indices', :live => true do
|
|
28
28
|
expect(Admin::Person.search('Mort').to_a).to eq([person])
|
29
29
|
end
|
30
30
|
|
31
|
-
it "can use
|
31
|
+
it "can use direct interface for upserting records" do
|
32
32
|
Admin::Person.connection.execute <<~SQL
|
33
33
|
INSERT INTO admin_people (name, created_at, updated_at)
|
34
34
|
VALUES ('Pat', now(), now());
|
@@ -52,4 +52,64 @@ describe 'Updates to records in real-time indices', :live => true do
|
|
52
52
|
|
53
53
|
expect(Admin::Person.search('Patrick').to_a).to eq([instance])
|
54
54
|
end
|
55
|
+
|
56
|
+
it "can use direct interface for processing records outside scope" do
|
57
|
+
Article.connection.execute <<~SQL
|
58
|
+
INSERT INTO articles (title, published, created_at, updated_at)
|
59
|
+
VALUES ('Nice Title', TRUE, now(), now());
|
60
|
+
SQL
|
61
|
+
|
62
|
+
article = Article.last
|
63
|
+
|
64
|
+
ThinkingSphinx::Processor.new(model: article.class, id: article.id).sync
|
65
|
+
|
66
|
+
expect(ThinkingSphinx.search('Nice', :indices => ["published_articles_core"])).to include(article)
|
67
|
+
|
68
|
+
Article.connection.execute <<~SQL
|
69
|
+
UPDATE articles SET published = FALSE WHERE title = 'Nice Title';
|
70
|
+
SQL
|
71
|
+
ThinkingSphinx::Processor.new(model: article.class, id: article.id).sync
|
72
|
+
|
73
|
+
expect(ThinkingSphinx.search('Nice', :indices => ["published_articles_core"])).to be_empty
|
74
|
+
end
|
75
|
+
|
76
|
+
it "can use direct interface for processing deleted records" do
|
77
|
+
Article.connection.execute <<~SQL
|
78
|
+
INSERT INTO articles (title, published, created_at, updated_at)
|
79
|
+
VALUES ('Nice Title', TRUE, now(), now());
|
80
|
+
SQL
|
81
|
+
|
82
|
+
article = Article.last
|
83
|
+
ThinkingSphinx::Processor.new(:instance => article).sync
|
84
|
+
|
85
|
+
expect(ThinkingSphinx.search('Nice', :indices => ["published_articles_core"])).to include(article)
|
86
|
+
|
87
|
+
Article.connection.execute <<~SQL
|
88
|
+
DELETE FROM articles where title = 'Nice Title';
|
89
|
+
SQL
|
90
|
+
|
91
|
+
ThinkingSphinx::Processor.new(:instance => article).sync
|
92
|
+
|
93
|
+
expect(ThinkingSphinx.search('Nice', :indices => ["published_articles_core"])).to be_empty
|
94
|
+
end
|
95
|
+
|
96
|
+
it "syncs records in real-time index with alternate ids" do
|
97
|
+
Album.connection.execute <<~SQL
|
98
|
+
INSERT INTO albums (id, name, artist, integer_id)
|
99
|
+
VALUES ('#{("a".."z").to_a.sample}', 'Sing to the Moon', 'Laura Mvula', #{rand(10000)});
|
100
|
+
SQL
|
101
|
+
|
102
|
+
album = Album.last
|
103
|
+
ThinkingSphinx::Processor.new(:model => Album, id: album.integer_id).sync
|
104
|
+
|
105
|
+
expect(ThinkingSphinx.search('Laura', :indices => ["album_real_core"])).to include(album)
|
106
|
+
|
107
|
+
Article.connection.execute <<~SQL
|
108
|
+
DELETE FROM albums where id = '#{album.id}';
|
109
|
+
SQL
|
110
|
+
|
111
|
+
ThinkingSphinx::Processor.new(:instance => album).sync
|
112
|
+
|
113
|
+
expect(ThinkingSphinx.search('Laura', :indices => ["album_real_core"])).to be_empty
|
114
|
+
end
|
55
115
|
end
|