mongoid-searchable 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "http://rubygems.org"
2
+ gemspec
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2011 Jason Coene
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,97 @@
1
+ # Mongoid Searchable
2
+
3
+ Mongoid Searchable provides simple field search for your Mongoid models using the full-text search technique described in the [MongoDB documentation](http://www.mongodb.org/display/DOCS/Full+Text+Search+in+Mongo).
4
+
5
+ ## Getting Started
6
+
7
+ First, add mongoid-searchable to your Gemfile:
8
+
9
+ ```ruby
10
+ gem 'mongoid-searchable'
11
+ ```
12
+
13
+ Next, include the module and tell it how to search your model:
14
+
15
+ ```ruby
16
+ class City
17
+ include Mongoid::Document
18
+ include Mongoid::Searchable
19
+
20
+ field :name, :type => String
21
+ field :population, :type => Integer
22
+ field :boroughs, :type => Array
23
+ field :officials, :type => Hash
24
+
25
+ searchable :name, :population, :boroughs, :officials
26
+ end
27
+ ```
28
+
29
+ You can now use the *search* method on your model to find what you're looking for:
30
+
31
+ ```ruby
32
+ # Create a few example cities
33
+ City.create :name => 'New York, NY', :population => 18_897_109,
34
+ :boroughs => ['Manhattan', 'Brooklyn', 'Queens', 'The Bronx', 'Staten Island'],
35
+ :officials => { 'Mayor' => 'Michael Bloomberg', 'Governor' => 'Andrew Cuomo' }
36
+ City.create :name => 'Rochester, NY', :population => 1_098_201,
37
+ :officials => { 'Mayor' => 'Thomas Richards', 'Governor' => 'Andrew Cuomo' }
38
+ City.create :name => 'Rochester, MN', :population => 186_011,
39
+ :officials => { 'Mayor' => 'Ardell Brede', 'Governor' => 'Mark Dayton' }
40
+
41
+ City.search('ny') # => 2 records
42
+ City.search('rochester') # => 2 records
43
+ City.search('manhattan') # => 1 record
44
+ ```
45
+
46
+ You can also choose to match all or any tokens. The default is to match **all** terms:
47
+
48
+ ```ruby
49
+ City.search('rochester ny') # => 1 record (defaults to all)
50
+ City.search('rochester ny', :match => :any) # => 3 records
51
+ ```
52
+
53
+ We can match partial or exact words as well. The default is to match **partial** words:
54
+
55
+ ```ruby
56
+ City.search('roch') # => 2 records
57
+ City.search('roch', :exact => true) # => 0 records
58
+ ```
59
+
60
+ You can chain other criteria on to your search, as per Mongoid convention:
61
+
62
+ ```ruby
63
+ City.search('ny').where(:population.gt => 2_000_000) # => 1 record
64
+ City.search('rochester').where(:population.lt => 500_000) # => 1 record
65
+ ```
66
+
67
+ ## Customization
68
+
69
+ You can also pass additional arguments to *searchable* to provide more control over the behavior.
70
+
71
+ **Changing the field name:** You can specify the field to use for keyword storage using **as**. The default is to use the *keywords* field:
72
+
73
+ ```ruby
74
+ class Person
75
+ ...
76
+ searchable :name, :as => :search_fields
77
+ ...
78
+ end
79
+ ```
80
+
81
+ **Turning off indexing:** You can also turn off indexing on your keyword field using **index**. This isn't recommended and defaults to *on*:
82
+
83
+ ```ruby
84
+ class Person
85
+ ...
86
+ searchable :name, :index => false
87
+ ...
88
+ end
89
+ ```
90
+
91
+ ## Enhancements and Pull Requests
92
+
93
+ If you find the project useful but it doesn't meet all of your needs, feel free to fork it and send a pull request.
94
+
95
+ ## License
96
+
97
+ MIT license, go wild.
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'bundler'
4
+ require 'rspec/core/rake_task'
5
+
6
+ Bundler::GemHelper.install_tasks
7
+
8
+ desc 'Run all specs in the spec directory'
9
+ RSpec::Core::RakeTask.new(:spec)
10
+
11
+ task :default => :spec
@@ -0,0 +1,5 @@
1
+ module Mongoid
2
+ module Searchable
3
+ VERSION = '0.1.0'
4
+ end
5
+ end
@@ -0,0 +1,88 @@
1
+ require 'mongoid'
2
+
3
+ module Mongoid
4
+
5
+ module Searchable
6
+
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ cattr_accessor :keywords_field, :searchable_fields
11
+ end
12
+
13
+ module ClassMethods
14
+
15
+ def searchable(*fields)
16
+ options = { :as => :keywords, :index => true }.merge(fields.extract_options!)
17
+
18
+ self.keywords_field = options[:as].to_sym
19
+ self.searchable_fields = fields.map(&:to_s)
20
+
21
+ field keywords_field
22
+ index :keywords if options[:index]
23
+
24
+ before_save :build_keywords
25
+
26
+ end
27
+
28
+ def search(query, options={})
29
+ keywords = query.to_s.split(' ').map { |s| s.downcase.gsub(/[^a-z0-9]/, '') }.select { |s| s.length >= 2 }.uniq
30
+ options[:match] ||= :all
31
+ options[:exact] ||= false
32
+
33
+ if options[:exact]
34
+ match = keywords.collect{|k| /^#{Regexp.escape(k)}$/ }
35
+ else
36
+ match = keywords.collect{|k| /#{Regexp.escape(k)}/ }
37
+ end
38
+
39
+ raise "Please define one or more fields as searchable before attempting to search." if keywords_field.nil? or searchable_fields.nil?
40
+
41
+ if keywords.any?
42
+ if options[:match].to_sym == :all
43
+ all_in(keywords_field.to_sym => match)
44
+ elsif options[:match].to_sym == :any
45
+ any_in(keywords_field.to_sym => match)
46
+ else
47
+ where()
48
+ end
49
+ else
50
+ where()
51
+ end
52
+ end
53
+
54
+ end
55
+
56
+ module InstanceMethods
57
+
58
+ def clean_keywords(value)
59
+ words = []
60
+
61
+ if value.is_a?(String) or value.is_a?(Numeric)
62
+ words << value.to_s.split(' ').map { |s| s.downcase.gsub(/[^a-z0-9]/, '') }.select { |s| s.length >= 2 }
63
+ elsif value.is_a?(Array) && value.any?
64
+ value.each do |v|
65
+ words << clean_keywords(v)
66
+ end
67
+ elsif value.is_a?(Hash) && value.any?
68
+ value.each do |k,v|
69
+ words << clean_keywords(v)
70
+ end
71
+ end
72
+
73
+ words.flatten.uniq
74
+ end
75
+
76
+ def build_keywords
77
+ keywords = []
78
+ self.class.searchable_fields.each do |f|
79
+ keywords << clean_keywords(send("#{f}"))
80
+ end
81
+ write_attribute(self.class.keywords_field, keywords.flatten.uniq)
82
+ end
83
+
84
+ end
85
+
86
+ end
87
+
88
+ end
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mongoid-searchable
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jason Coene
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-09-08 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: mongoid
16
+ requirement: &70209780623120 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '2.1'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70209780623120
25
+ - !ruby/object:Gem::Dependency
26
+ name: bson_ext
27
+ requirement: &70209780602240 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: '1.3'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70209780602240
36
+ - !ruby/object:Gem::Dependency
37
+ name: growl
38
+ requirement: &70209780588960 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70209780588960
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ requirement: &70209780575180 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 0.9.2
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70209780575180
58
+ - !ruby/object:Gem::Dependency
59
+ name: rspec
60
+ requirement: &70209780540880 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: '2.6'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70209780540880
69
+ - !ruby/object:Gem::Dependency
70
+ name: guard-rspec
71
+ requirement: &70209780534900 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ version: 0.4.3
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70209780534900
80
+ description: Mongoid Searchable allows you to easily perform full-text search your
81
+ Mongoid models.
82
+ email:
83
+ - jcoene@gmail.com
84
+ executables: []
85
+ extensions: []
86
+ extra_rdoc_files: []
87
+ files:
88
+ - lib/mongoid/searchable/version.rb
89
+ - lib/mongoid/searchable.rb
90
+ - MIT-LICENSE
91
+ - Rakefile
92
+ - Gemfile
93
+ - README.md
94
+ homepage: http://github.com/jcoene/mongoid-searchable
95
+ licenses: []
96
+ post_install_message:
97
+ rdoc_options: []
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ none: false
102
+ requirements:
103
+ - - ! '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ! '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ requirements: []
113
+ rubyforge_project:
114
+ rubygems_version: 1.8.6
115
+ signing_key:
116
+ specification_version: 3
117
+ summary: Simple keyword search for your Mongoid models.
118
+ test_files: []