sunspot_stats 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in sunspot_stats.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Duccio Giovannelli
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,59 @@
1
+ # Sunspot Stats
2
+
3
+ Sunspot is a Ruby library for expressive, powerful interaction with the Solr search engine. I use the latest version [2.0.0.pre.120417](https://rubygems.org/gems/sunspot/versions/2.0.0.pre.120417) but i need the statsComponent in order to get the sum on a given indexed field.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'sunspot_stats'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install sunspot_stats
18
+
19
+ ## Usage
20
+
21
+ The statComponent let you to have *min*, *max*, *count*, *missing*, *sum*, *sumOfsquare*, *mean* and *stdev*.
22
+
23
+ ### An usage example
24
+
25
+ ```ruby
26
+ Model.search do
27
+ #Filters
28
+ ...
29
+ #Facets
30
+ ...
31
+ #Stats
32
+ stat(:your_field, :facet => :your_facet_filed, :type => "min")
33
+ ...
34
+ end
35
+ ```
36
+
37
+ **:facet** and **:type** are optional the default type is the "sum" (you can pass: *min*, *max*, *count*, *missing*, *sum*, *sumOfsquare*, *mean*, *stdev* as string)
38
+
39
+ Remember to stats on a non multi valued field and update to the solr3.6, because the solr3.5 has a bug with stats.
40
+
41
+ the Sunspot::SearchStatRow has the method *stat_field* and the *value*.
42
+
43
+ If you enable faceting on stats the stat_field is the facet and the value is the type defined.
44
+
45
+ [Upgrade solr in sunspot](https://github.com/sunspot/sunspot/wiki/Upgrading-sunspot_solr-Solr-Instance)
46
+
47
+ ### Boolean Searches
48
+
49
+ Usually Suspot use the dismax for searches, here we extend to edismax to manage also boolean logic searches
50
+
51
+ a OR (b AND c) works.
52
+
53
+ ## Contributing
54
+
55
+ 1. Fork it
56
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
57
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
58
+ 4. Push to the branch (`git push origin my-new-feature`)
59
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,22 @@
1
+ module Sunspot
2
+ module DSL
3
+ #
4
+ # Provides an API for areas of the query DSL that operate on specific
5
+ # fields. This functionality is provided by the query DSL and the dynamic
6
+ # query DSL.
7
+ #
8
+ class FieldQuery < Scope
9
+ def initialize(search, query, setup) #:nodoc:
10
+ @search, @query = search, query
11
+ super(query.scope, setup)
12
+ end
13
+
14
+ def stat(field_name, options = {})
15
+ field = @setup.field(field_name)
16
+ options[:facet] = @setup.field(options[:facet]) if options[:facet].present?
17
+ stat = @query.add_stat(Sunspot::Query::FieldStat.new(field, options))
18
+ @search.add_field_stat(field, options)
19
+ end
20
+ end
21
+ end
22
+ end
data/lib/edismax.rb ADDED
@@ -0,0 +1,20 @@
1
+ OriginalDismax = Sunspot::Query::Dismax
2
+
3
+ class PatchedDismax < OriginalDismax
4
+
5
+ def to_params
6
+ params = super
7
+ params[:defType] = 'edismax'
8
+ params
9
+ end
10
+
11
+ def to_subquery
12
+ query = super
13
+ query = query.sub '{!dismax', '{!edismax'
14
+ query
15
+ end
16
+
17
+ end
18
+
19
+ Sunspot::Query.send :remove_const, :Dismax
20
+ Sunspot::Query::Dismax = PatchedDismax
@@ -0,0 +1,31 @@
1
+ module Sunspot
2
+ module Query
3
+ #
4
+ # A FieldStat stats by the unique values of a given field.
5
+ #
6
+ class FieldStat
7
+
8
+ def initialize(field, options = {})
9
+ if field.multiple?
10
+ raise(ArgumentError, "#{field.name} cannot be used for stats because it is a multiple-value field")
11
+ end
12
+ @field = field
13
+ @options = options
14
+ @sort = SortComposite.new
15
+ end
16
+
17
+ def add_sort(sort)
18
+ @sort << sort
19
+ end
20
+
21
+ def to_params
22
+ params = {
23
+ :stats => 'true',
24
+ :"stats.field" => @field.indexed_name
25
+ }
26
+ params.merge!({:"stats.facet" => @options[:facet].indexed_name}) if @options[:facet].present?
27
+ params
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,12 @@
1
+ module Sunspot
2
+ module Query #:nodoc:
3
+ class CommonQuery
4
+
5
+ def add_stat(stat)
6
+ @components << stat
7
+ stat
8
+ end
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,46 @@
1
+ module Sunspot
2
+ module Search
3
+ class StatFacet
4
+
5
+ def initialize(field, search, options)
6
+ @field, @search, @options = field, search, options
7
+ end
8
+
9
+ def field_name
10
+ @field.name
11
+ end
12
+
13
+ def rows
14
+ @options[:type] ||= "sum"
15
+ @sort = false
16
+ @rows ||=
17
+ begin
18
+ if !@search.stat_response['stats_fields'].nil?
19
+ if @options[:facet].present?
20
+ stat = @search.stat_response['stats_fields'][@field.indexed_name]
21
+ data = stat.nil? ? [] : stat['facets'][@options[:facet].indexed_name]
22
+ @sort = true
23
+ else
24
+ data = @search.stat_response['stats_fields'].to_a
25
+ end
26
+ end
27
+
28
+ rows = []
29
+
30
+ data.collect do |stat, value|
31
+ rows << StatRow.new(stat, value[@options[:type]], self)
32
+ end
33
+
34
+ if @options[:sort] == :type
35
+ rows.sort! { |lrow, rrow| rrow.count <=> lrow.count }
36
+ else
37
+ rows.sort! { |lrow, rrow| lrow.stat_field <=> rrow.stat_field }
38
+ end if @sort
39
+ rows
40
+ rescue Exception => e
41
+ puts "Error: #{e}"
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,28 @@
1
+ module Sunspot
2
+ module Search
3
+ class StatRow
4
+ attr_reader :stat_field, :value
5
+ attr_writer :instance #:nodoc:
6
+
7
+ def initialize(stat_field, value, stat) #:nodoc:
8
+ @stat_field, @value, @stat = stat_field, value, stat
9
+ end
10
+
11
+ #
12
+ # Return the instance referenced by this stat row. Only valid for field
13
+ # stats whose fields are defined with the :references key.
14
+ #
15
+
16
+ def instance
17
+ if !defined?(@instance)
18
+ @stat.populate_instances
19
+ end
20
+ @instance
21
+ end
22
+
23
+ def inspect
24
+ "<Sunspot::Search::StatRow:#{stat_field.inspect} (#{value})>"
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,57 @@
1
+ require 'sunspot/search/paginated_collection'
2
+ require 'sunspot/search/hit_enumerable'
3
+
4
+ module Sunspot
5
+ module Search #:nodoc:
6
+
7
+ #
8
+ # This class encapsulates the results of a Solr search. It provides access
9
+ # to search results, total result count, facets, and pagination information.
10
+ # Instances of Search are returned by the Sunspot.search and
11
+ # Sunspot.new_search methods.
12
+ #
13
+ class AbstractSearch
14
+ #
15
+ # Retrieve all facet objects defined for this search, in order they were
16
+ # defined. To retrieve an individual facet by name, use #facet()
17
+ #
18
+ attr_reader :stats
19
+
20
+ def initialize(connection, setup, query, configuration) #:nodoc:
21
+ @connection, @setup, @query = connection, setup, query
22
+ @query.paginate(1, configuration.pagination.default_per_page)
23
+
24
+ @stats = []
25
+ @stats_by_name = {}
26
+
27
+ @facets = []
28
+ @facets_by_name = {}
29
+
30
+ @groups_by_name = {}
31
+ @groups = []
32
+ end
33
+
34
+
35
+ def stat(name)
36
+ if name
37
+ @stats_by_name[name.to_sym]
38
+ end
39
+ end
40
+
41
+ def stat_response #:nodoc:
42
+ @solr_result['stats']
43
+ end
44
+
45
+ def add_field_stat(field, options = {}) #:nodoc:
46
+ name = (options[:name] || field.name)
47
+ add_stat(name, StatFacet.new(field, self, options))
48
+ end
49
+
50
+ def add_stat(name, stat)
51
+ @stats << stat
52
+ @stats_by_name[name.to_sym] = stat
53
+ end
54
+
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,15 @@
1
+ require "sunspot_stats/version"
2
+
3
+ %w(field_query).each do |file|
4
+ require File.join(File.dirname(__FILE__), "dsl", file)
5
+ end
6
+
7
+
8
+ %w(stat_search stat_row stat_facet).each do |file|
9
+ require File.join(File.dirname(__FILE__), "search", file)
10
+ end
11
+
12
+ %w(stat_query field_stat).each do |file|
13
+ require(File.join(File.dirname(__FILE__), 'query', file))
14
+ end
15
+
@@ -0,0 +1,3 @@
1
+ module SunspotStats
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/sunspot_stats/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["duccio giovannelli"]
6
+ gem.email = ["giovannelli@extendi.it"]
7
+ gem.description = <<-TEXT
8
+ Sunspot is a library providing a powerful, all-ruby API for the Solr search engine. This gem extend sunspot adding the
9
+ statsComponent feature, which returns simple statistics for indexed numeric fields within the DocSet. Usually Suspot use the dismax
10
+ for searches, here we extend to edismax to manage also boolean logic searches.
11
+ TEXT
12
+ gem.summary = "Added the statsComponent to sunspot"
13
+ gem.homepage = "https://github.com/giovannelli/sunspot_stats"
14
+ gem.files = `git ls-files`.split($\)
15
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
16
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
17
+ gem.name = "sunspot_stats"
18
+ gem.require_paths = ["lib"]
19
+ gem.version = SunspotStats::VERSION
20
+
21
+ gem.add_dependency "sunspot", "~> 2.0.0.pre.120417"
22
+ gem.add_development_dependency "rspec"
23
+
24
+ gem.rdoc_options << '--webcvs=http://github.com/giovannelli/sunspot_stats/tree/master/%s' <<
25
+ '--title' << 'Sunspot Stat - StatsComponent for sunspot - API Documentation' <<
26
+ '--main' << 'README.rdoc'
27
+ end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sunspot_stats
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 2
9
+ version: 0.0.2
10
+ platform: ruby
11
+ authors:
12
+ - duccio giovannelli
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2012-07-14 00:00:00 +02:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: sunspot
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 2
29
+ - 0
30
+ - 0
31
+ - pre
32
+ - 120417
33
+ version: 2.0.0.pre.120417
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: rspec
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ segments:
44
+ - 0
45
+ version: "0"
46
+ type: :development
47
+ version_requirements: *id002
48
+ description: " Sunspot is a library providing a powerful, all-ruby API for the Solr search engine. This gem extend sunspot adding the \n statsComponent feature, which returns simple statistics for indexed numeric fields within the DocSet. Usually Suspot use the dismax\n for searches, here we extend to edismax to manage also boolean logic searches.\n"
49
+ email:
50
+ - giovannelli@extendi.it
51
+ executables: []
52
+
53
+ extensions: []
54
+
55
+ extra_rdoc_files: []
56
+
57
+ files:
58
+ - .gitignore
59
+ - Gemfile
60
+ - LICENSE
61
+ - README.md
62
+ - Rakefile
63
+ - lib/dsl/field_query.rb
64
+ - lib/edismax.rb
65
+ - lib/query/field_stat.rb
66
+ - lib/query/stat_query.rb
67
+ - lib/search/stat_facet.rb
68
+ - lib/search/stat_row.rb
69
+ - lib/search/stat_search.rb
70
+ - lib/sunspot_stats.rb
71
+ - lib/sunspot_stats/version.rb
72
+ - sunspot_stats.gemspec
73
+ has_rdoc: true
74
+ homepage: https://github.com/giovannelli/sunspot_stats
75
+ licenses: []
76
+
77
+ post_install_message:
78
+ rdoc_options:
79
+ - --webcvs=http://github.com/giovannelli/sunspot_stats/tree/master/%s
80
+ - --title
81
+ - Sunspot Stat - StatsComponent for sunspot - API Documentation
82
+ - --main
83
+ - README.rdoc
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ segments:
91
+ - 0
92
+ version: "0"
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ segments:
98
+ - 0
99
+ version: "0"
100
+ requirements: []
101
+
102
+ rubyforge_project:
103
+ rubygems_version: 1.3.6
104
+ signing_key:
105
+ specification_version: 3
106
+ summary: Added the statsComponent to sunspot
107
+ test_files: []
108
+