mongomapper_search 0.0.1
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/LICENSE +22 -0
- data/README.md +102 -0
- data/Rakefile +10 -0
- data/lib/mongomapper_search/query.rb +13 -0
- data/lib/mongomapper_search/search.rb +75 -0
- data/lib/mongomapper_search/util.rb +43 -0
- data/lib/mongomapper_search.rb +3 -0
- data/spec/models/category.rb +6 -0
- data/spec/models/product.rb +13 -0
- data/spec/models/subproduct.rb +7 -0
- data/spec/models/tag.rb +6 -0
- data/spec/models/variant.rb +4 -0
- data/spec/search_spec.rb +150 -0
- data/spec/spec_helper.rb +31 -0
- data/spec/util_spec.rb +41 -0
- metadata +134 -0
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (C) 2011 by Mário Peixoto
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
20
|
+
|
21
|
+
|
22
|
+
Based on mongoid_search, Copyright by Mauricio Zaffari, 2009
|
data/README.md
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
MongoMapper Search
|
2
|
+
============
|
3
|
+
|
4
|
+
MongoMapper Search is a simple full text search implementation for MongoMapper ODM based on mongoid_search (https://github.com/mauriciozaffari/mongoid_search).
|
5
|
+
|
6
|
+
Installation
|
7
|
+
--------
|
8
|
+
|
9
|
+
In your Gemfile:
|
10
|
+
|
11
|
+
gem 'mongomapper_search'
|
12
|
+
|
13
|
+
Then:
|
14
|
+
|
15
|
+
bundle install
|
16
|
+
|
17
|
+
Examples
|
18
|
+
--------
|
19
|
+
|
20
|
+
class Product
|
21
|
+
include MongoMapper::Document
|
22
|
+
include MongoMapper::Search
|
23
|
+
key :brand, String
|
24
|
+
key :name, String
|
25
|
+
|
26
|
+
many :tags
|
27
|
+
belongs_to :category
|
28
|
+
|
29
|
+
search_in :brand, :name, :tags => :name, :category => :name
|
30
|
+
end
|
31
|
+
|
32
|
+
class Tag
|
33
|
+
include MongoMapper::Document
|
34
|
+
key :name, Stirng
|
35
|
+
|
36
|
+
belongs_to :product
|
37
|
+
end
|
38
|
+
|
39
|
+
class Category
|
40
|
+
include MongoMapper::Document
|
41
|
+
key :name, String
|
42
|
+
|
43
|
+
many :products
|
44
|
+
end
|
45
|
+
|
46
|
+
Now when you save a product, you get a _keywords field automatically:
|
47
|
+
|
48
|
+
p = Product.new :brand => "Apple", :name => "iPhone"
|
49
|
+
p.tags << Tag.new(:name => "Amazing")
|
50
|
+
p.tags << Tag.new(:name => "Awesome")
|
51
|
+
p.tags << Tag.new(:name => "Superb")
|
52
|
+
p.save
|
53
|
+
=> true
|
54
|
+
p._keywords
|
55
|
+
|
56
|
+
Now you can run search, which will look in the _keywords field and return all matching results:
|
57
|
+
|
58
|
+
Product.search("apple iphone").size
|
59
|
+
=> 1
|
60
|
+
|
61
|
+
Note that the search is case insensitive, and accept partial searching too:
|
62
|
+
|
63
|
+
Product.search("ipho").size
|
64
|
+
=> 1
|
65
|
+
|
66
|
+
You can use search in a chainable way:
|
67
|
+
|
68
|
+
Product.where(:brand => "Apple").search('iphone').sort(:price.asc)
|
69
|
+
|
70
|
+
|
71
|
+
Options
|
72
|
+
-------
|
73
|
+
|
74
|
+
match:
|
75
|
+
_:any_ - match any occurrence
|
76
|
+
_:all_ - match all ocurrences
|
77
|
+
Default is _:any_.
|
78
|
+
|
79
|
+
search_in :brand, :name, { :tags => :name }, { :match => :any }
|
80
|
+
|
81
|
+
Product.search("apple motorola").size
|
82
|
+
=> 1
|
83
|
+
|
84
|
+
search_in :brand, :name, { :tags => :name }, { :match => :all }
|
85
|
+
|
86
|
+
Product.search("apple motorola").size
|
87
|
+
=> 0
|
88
|
+
|
89
|
+
allow_empty_search:
|
90
|
+
_true_ - match any occurrence
|
91
|
+
_false_ - match all ocurrences
|
92
|
+
Default is _false_.
|
93
|
+
|
94
|
+
search_in :brand, :name, { :tags => :name }, { :allow_empty_search => true }
|
95
|
+
|
96
|
+
Product.search("").size
|
97
|
+
=> 1
|
98
|
+
|
99
|
+
RoadMap
|
100
|
+
----
|
101
|
+
|
102
|
+
- Create a ignore list so the search can ignore some words
|
data/Rakefile
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
module MongoMapper
|
2
|
+
module Search
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
cattr_accessor :search_fields, :allow_empty_search, :stem_keywords, :match
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.included(base)
|
10
|
+
@classes ||= []
|
11
|
+
@classes << base
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.classes
|
15
|
+
@classes
|
16
|
+
end
|
17
|
+
|
18
|
+
module ClassMethods
|
19
|
+
|
20
|
+
def search_in(*args)
|
21
|
+
options = args.last.is_a?(Hash) && [:allow_empty_search, :stem_keywords].include?(args.last.keys.first) ? args.pop : {}
|
22
|
+
self.match = [:any, :all].include?(options[:match]) ? options[:match] : :any
|
23
|
+
self.allow_empty_search = [true, false].include?(options[:allow_empty_search]) ? options[:allow_empty_search] : false
|
24
|
+
self.stem_keywords = [true, false].include?(options[:stem_keywords]) ? options[:allow_empty_search] : false
|
25
|
+
self.search_fields = (self.search_fields || []).concat args
|
26
|
+
|
27
|
+
key :_keywords, Array
|
28
|
+
ensure_index :_keywords, :background => true
|
29
|
+
|
30
|
+
before_save :set_keywords
|
31
|
+
end
|
32
|
+
|
33
|
+
def search(query, options={})
|
34
|
+
return all if query.blank? && allow_empty_search
|
35
|
+
|
36
|
+
keywords = Util.normalize_keywords(query, stem_keywords)
|
37
|
+
|
38
|
+
regexed_keywords = []
|
39
|
+
|
40
|
+
keywords.each do |keyword|
|
41
|
+
regexed_keywords.concat([/#{keyword}/])
|
42
|
+
end
|
43
|
+
|
44
|
+
search_match = options[:match]||self.match
|
45
|
+
|
46
|
+
if search_match == :all
|
47
|
+
where(:_keywords => { "$all" => regexed_keywords })
|
48
|
+
elsif search_match == :any
|
49
|
+
where(:_keywords => regexed_keywords )
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Goes through all documents in the class that includes Mongoid::Search
|
54
|
+
# and indexes the keywords.
|
55
|
+
def index_keywords!
|
56
|
+
all.each { |d| d.index_keywords! }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
module InstanceMethods #:nodoc:
|
61
|
+
# Indexes the document keywords
|
62
|
+
def index_keywords!
|
63
|
+
update_attribute(:_keywords, set_keywords)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
def set_keywords
|
69
|
+
self._keywords = self.search_fields.map do |field|
|
70
|
+
Util.keywords(self, field, stem_keywords)
|
71
|
+
end.flatten.reject{|k| k.nil? || k.empty?}.uniq.sort
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Util
|
2
|
+
|
3
|
+
def self.keywords(klass, field, stem_keywords, ignore_list=[])
|
4
|
+
if field.is_a?(Hash)
|
5
|
+
field.keys.map do |key|
|
6
|
+
attribute = klass.send(key)
|
7
|
+
unless attribute.blank?
|
8
|
+
method = field[key]
|
9
|
+
if attribute.is_a?(Array)
|
10
|
+
if method.is_a?(Array)
|
11
|
+
method.map {|m| attribute.map { |a| Util.normalize_keywords a.send(m), stem_keywords, ignore_list } }
|
12
|
+
else
|
13
|
+
attribute.map(&method).map { |t| Util.normalize_keywords t, stem_keywords, ignore_list }
|
14
|
+
end
|
15
|
+
else
|
16
|
+
Util.normalize_keywords(attribute.send(method), stem_keywords, ignore_list)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
else
|
21
|
+
value = klass[field]
|
22
|
+
value = value.join(' ') if value.respond_to?(:join)
|
23
|
+
Util.normalize_keywords(value, stem_keywords, ignore_list) if value
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.normalize_keywords(text, stem_keywords, ignore_list=[])
|
28
|
+
return [] if text.blank?
|
29
|
+
text = text.to_s.
|
30
|
+
mb_chars.
|
31
|
+
normalize(:kd).
|
32
|
+
to_s.
|
33
|
+
gsub(/[._:;'"`,?|+={}()!@#%^&*<>~\$\-\\\/\[\]]/, ' '). # strip punctuation
|
34
|
+
gsub(/[^[:alnum:]\s]/,''). # strip accents
|
35
|
+
downcase.
|
36
|
+
split(' ').
|
37
|
+
reject { |word| word.size < 2 }
|
38
|
+
text = text.reject { |word| ignore_list.include?(word) } unless ignore_list.blank?
|
39
|
+
text = text.map(&:stem) if stem_keywords
|
40
|
+
text
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class Product
|
2
|
+
include MongoMapper::Document
|
3
|
+
include MongoMapper::Search
|
4
|
+
key :brand, String
|
5
|
+
key :name, String
|
6
|
+
key :attrs, Array
|
7
|
+
|
8
|
+
many :tags
|
9
|
+
many :subproducts
|
10
|
+
belongs_to :category
|
11
|
+
|
12
|
+
search_in :brand, :name, :outlet, :attrs, :tags => :name, :category => :name, :subproducts => [:brand, :name]
|
13
|
+
end
|
data/spec/models/tag.rb
ADDED
data/spec/search_spec.rb
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
4
|
+
|
5
|
+
describe MongoMapper::Search do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
Product.stem_keywords = false
|
9
|
+
@product = Product.create :brand => "Apple",
|
10
|
+
:name => "iPhone",
|
11
|
+
:tags => ["Amazing", "Awesome", "Olé"].map { |tag| Tag.new(:name => tag) },
|
12
|
+
:category => Category.new(:name => "Mobile"),
|
13
|
+
:subproducts => [Subproduct.new(:brand => "Apple", :name => "Craddle")]
|
14
|
+
end
|
15
|
+
|
16
|
+
context "utf-8 characters" do
|
17
|
+
before(:each) {
|
18
|
+
Product.stem_keywords = false
|
19
|
+
@product = Product.create :brand => "Эльбрус",
|
20
|
+
:name => "Процессор",
|
21
|
+
:tags => ["Amazing", "Awesome", "Olé"].map { |tag| Tag.new(:name => tag) },
|
22
|
+
:category => Category.new(:name => "процессоры"),
|
23
|
+
:subproducts => []
|
24
|
+
}
|
25
|
+
|
26
|
+
it "should leave utf8 characters" do
|
27
|
+
@product._keywords.should == ["amazing", "awesome", "ole", "Процессор", "Эльбрус", "процессоры"]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "when references are nil" do
|
32
|
+
context "when instance is being created" do
|
33
|
+
it "should not complain about method missing" do
|
34
|
+
lambda { Product.create! }.should_not raise_error
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
subject { Product.create :brand => "Apple", :name => "iPhone" }
|
39
|
+
|
40
|
+
its(:_keywords) { should == ["apple", "iphone"] }
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should set the _keywords field for array fields also" do
|
44
|
+
@product.attrs = ['lightweight', 'plastic', :red]
|
45
|
+
@product.save!
|
46
|
+
@product._keywords.should include 'lightweight', 'plastic', 'red'
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should inherit _keywords field and build upon" do
|
50
|
+
variant = Variant.create :brand => "Apple",
|
51
|
+
:name => "iPhone",
|
52
|
+
:tags => ["Amazing", "Awesome", "Olé"].map { |tag| Tag.new(:name => tag) },
|
53
|
+
:category => Category.new(:name => "Mobile"),
|
54
|
+
:subproducts => [Subproduct.new(:brand => "Apple", :name => "Craddle")],
|
55
|
+
:color => :white
|
56
|
+
variant._keywords.should include 'white'
|
57
|
+
Variant.search("Apple white").to_a.should eq [variant]
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should set the _keywords field with stemmed words if stem is enabled" do
|
61
|
+
Product.stem_keywords = true
|
62
|
+
@product.save!
|
63
|
+
@product._keywords.should == ["amaz", "appl", "awesom", "craddl", "iphon", "mobil", "ol"]
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should incorporate numbers as keywords" do
|
67
|
+
@product = Product.create :brand => "Ford",
|
68
|
+
:name => "T 1908",
|
69
|
+
:tags => ["Amazing", "First", "Car"].map { |tag| Tag.new(:name => tag) },
|
70
|
+
:category => Category.new(:name => "Vehicle")
|
71
|
+
|
72
|
+
@product.save!
|
73
|
+
@product._keywords.should == ["1908","amazing", "car", "first", "ford", "vehicle"]
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
it "should return results in search" do
|
78
|
+
Product.search("apple").size.should == 1
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should return results in search for dynamic attribute" do
|
82
|
+
@product[:outlet] = "online shop"
|
83
|
+
@product.save!
|
84
|
+
Product.search("online").size.should == 1
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should return results in search even searching a accented word" do
|
88
|
+
Product.search("Ole").size.should == 1
|
89
|
+
Product.search("Olé").size.should == 1
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should return results in search even if the case doesn't match" do
|
93
|
+
Product.search("oLe").size.should == 1
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should return results in search with a partial word" do
|
97
|
+
Product.search("iph").size.should == 1
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should return results for any matching word with default search" do
|
101
|
+
Product.search("apple motorola").size.should == 1
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should not return results when all words do not match, if using :match => :all" do
|
105
|
+
Product.match = :all
|
106
|
+
Product.search("apple motorola").size.should == 0
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should return results for any matching word, using :match => :all, passing :match => :any to .search" do
|
110
|
+
Product.match = :all
|
111
|
+
Product.search("apple motorola", :match => :any).size.should == 1
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should not return results when all words do not match, passing :match => :all to .search" do
|
115
|
+
Product.search("apple motorola", :match => :all).size.should == 0
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should return no results when a blank search is made" do
|
119
|
+
Product.search("").size.should == 0
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should return results when a blank search is made when :allow_empty_search is true" do
|
123
|
+
Product.allow_empty_search = true
|
124
|
+
Product.search("").size.should == 1
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should search for embedded documents" do
|
128
|
+
Product.search("craddle").size.should == 1
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'should work in a chainable fashion' do
|
132
|
+
@product.category.products.where(:brand => 'Apple').search('apple').size.should == 1
|
133
|
+
@product.category.products.where(:brand => 'Apple').search('troll').size.should == 0
|
134
|
+
@product.category.products.search('craddle').where(:brand => 'Apple').size.should == 1
|
135
|
+
@product.category.products.search('craddle').where(:brand => 'Dell').size.should == 0
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'should return the classes that include the search module' do
|
139
|
+
MongoMapper::Search.classes.should == [Product]
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'should have a method to index keywords' do
|
143
|
+
@product.index_keywords!.should == true
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'should have a class method to index all documents keywords' do
|
147
|
+
Product.index_keywords!.should_not include(false)
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
SimpleCov.start
|
3
|
+
|
4
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
5
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
6
|
+
require 'mongo_mapper'
|
7
|
+
require 'database_cleaner'
|
8
|
+
require 'fast_stemmer'
|
9
|
+
require 'yaml'
|
10
|
+
require 'mongomapper_search'
|
11
|
+
|
12
|
+
MongoMapper.connection = Mongo::Connection.new("localhost", 27017)
|
13
|
+
MongoMapper.database = "mongomapper_search_test"
|
14
|
+
|
15
|
+
Dir["#{File.dirname(__FILE__)}/models/*.rb"].each { |file| require file }
|
16
|
+
|
17
|
+
DatabaseCleaner.orm = :mongo_mapper
|
18
|
+
|
19
|
+
RSpec.configure do |config|
|
20
|
+
config.before(:all) do
|
21
|
+
DatabaseCleaner.strategy = :truncation
|
22
|
+
end
|
23
|
+
|
24
|
+
config.before(:each) do
|
25
|
+
DatabaseCleaner.start
|
26
|
+
end
|
27
|
+
|
28
|
+
config.after(:each) do
|
29
|
+
DatabaseCleaner.clean
|
30
|
+
end
|
31
|
+
end
|
data/spec/util_spec.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
3
|
+
|
4
|
+
describe Util do
|
5
|
+
it "should return an empty array if no text is passed" do
|
6
|
+
Util.normalize_keywords("", false, "").should == []
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should return an array of keywords" do
|
10
|
+
Util.normalize_keywords("keyword", false, "").class.should == Array
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should return an array of strings" do
|
14
|
+
Util.normalize_keywords("keyword", false, "").first.class.should == String
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should remove accents from the text passed" do
|
18
|
+
Util.normalize_keywords("café", false, "").should == ["cafe"]
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should downcase the text passed" do
|
22
|
+
Util.normalize_keywords("CaFé", false, "").should == ["cafe"]
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should split whitespaces, hifens, dots, underlines, etc.." do
|
26
|
+
Util.normalize_keywords("CaFé-express.com delicious;come visit, and 'win' an \"iPad\"", false, "").should == ["cafe", "express", "com", "delicious", "come", "visit", "and", "win", "an", "ipad"]
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should stem keywords" do
|
30
|
+
Util.normalize_keywords("A runner running and eating", true, "").should == ["runner", "run", "and", "eat"]
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should ignore keywords with less than two words" do
|
34
|
+
Util.normalize_keywords("A runner running", false, "").should_not include "a"
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should not ignore numbers" do
|
38
|
+
Util.normalize_keywords("Ford T 1908", false, "").should include "1908"
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
metadata
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mongomapper_search
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Mário Peixoto
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-08-18 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: mongo_mapper
|
16
|
+
requirement: &70143029026220 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.9.1
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70143029026220
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: bson_ext
|
27
|
+
requirement: &70143029025740 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.2.0
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70143029025740
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: fast-stemmer
|
38
|
+
requirement: &70143029025260 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 1.0.0
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70143029025260
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: database_cleaner
|
49
|
+
requirement: &70143029024780 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.6.4
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70143029024780
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: rake
|
60
|
+
requirement: &70143029024300 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ~>
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: 0.9.2
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70143029024300
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: &70143029023820 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '2.4'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *70143029023820
|
80
|
+
description: Simple full text search for MongoMapper ODM
|
81
|
+
email:
|
82
|
+
- mario.peixoto@gmail.com
|
83
|
+
executables: []
|
84
|
+
extensions: []
|
85
|
+
extra_rdoc_files: []
|
86
|
+
files:
|
87
|
+
- lib/mongomapper_search/query.rb
|
88
|
+
- lib/mongomapper_search/search.rb
|
89
|
+
- lib/mongomapper_search/util.rb
|
90
|
+
- lib/mongomapper_search.rb
|
91
|
+
- LICENSE
|
92
|
+
- README.md
|
93
|
+
- Rakefile
|
94
|
+
- spec/models/category.rb
|
95
|
+
- spec/models/product.rb
|
96
|
+
- spec/models/subproduct.rb
|
97
|
+
- spec/models/tag.rb
|
98
|
+
- spec/models/variant.rb
|
99
|
+
- spec/search_spec.rb
|
100
|
+
- spec/spec_helper.rb
|
101
|
+
- spec/util_spec.rb
|
102
|
+
homepage: http://github.com/mariopeixoto/mongomapper_search
|
103
|
+
licenses: []
|
104
|
+
post_install_message:
|
105
|
+
rdoc_options: []
|
106
|
+
require_paths:
|
107
|
+
- lib
|
108
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
109
|
+
none: false
|
110
|
+
requirements:
|
111
|
+
- - ! '>='
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
114
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
|
+
none: false
|
116
|
+
requirements:
|
117
|
+
- - ! '>='
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: 1.3.6
|
120
|
+
requirements: []
|
121
|
+
rubyforge_project:
|
122
|
+
rubygems_version: 1.8.7
|
123
|
+
signing_key:
|
124
|
+
specification_version: 3
|
125
|
+
summary: Search implementation for MongoMapper ODM
|
126
|
+
test_files:
|
127
|
+
- spec/models/category.rb
|
128
|
+
- spec/models/product.rb
|
129
|
+
- spec/models/subproduct.rb
|
130
|
+
- spec/models/tag.rb
|
131
|
+
- spec/models/variant.rb
|
132
|
+
- spec/search_spec.rb
|
133
|
+
- spec/spec_helper.rb
|
134
|
+
- spec/util_spec.rb
|