mongoid-giza 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.travis.yml +6 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +152 -0
- data/Rakefile +11 -0
- data/lib/mongoid/giza.rb +160 -0
- data/lib/mongoid/giza/configuration.rb +136 -0
- data/lib/mongoid/giza/dynamic_index.rb +37 -0
- data/lib/mongoid/giza/index.rb +101 -0
- data/lib/mongoid/giza/index/attribute.rb +39 -0
- data/lib/mongoid/giza/index/field.rb +27 -0
- data/lib/mongoid/giza/indexer.rb +33 -0
- data/lib/mongoid/giza/models/giza_id.rb +27 -0
- data/lib/mongoid/giza/railtie.rb +17 -0
- data/lib/mongoid/giza/search.rb +83 -0
- data/lib/mongoid/giza/version.rb +5 -0
- data/lib/mongoid/giza/xml_pipe2.rb +67 -0
- data/mongoid-giza.gemspec +32 -0
- data/spec/mongoid/giza/configuration_spec.rb +340 -0
- data/spec/mongoid/giza/dynamic_index_spec.rb +32 -0
- data/spec/mongoid/giza/index/attribute_spec.rb +36 -0
- data/spec/mongoid/giza/index/field_spec.rb +25 -0
- data/spec/mongoid/giza/index_spec.rb +162 -0
- data/spec/mongoid/giza/indexer_spec.rb +87 -0
- data/spec/mongoid/giza/models/giza_id_spec.rb +30 -0
- data/spec/mongoid/giza/search_spec.rb +100 -0
- data/spec/mongoid/giza/xml_pipe2_spec.rb +98 -0
- data/spec/mongoid/giza_spec.rb +282 -0
- data/spec/spec_helper.rb +51 -0
- metadata +227 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 150e88a193d198b7ee59e633753808457f01f9d0
|
4
|
+
data.tar.gz: dd2c1cc23492df7aa5e1c3e9c3fd6b13a578486a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 632f8929ab2a00803101594e1dc0e0bdd98164ef984797bb889eaaa4d90ebfef1250e7c94ad3f00f2eadab1313b4b36b49dd9d2969010b585df34a6b10f2bff1
|
7
|
+
data.tar.gz: 5eadf9661bc8697db39111932e5677ed1df5199269cef298fc2cf0788a95de779d1c8a63e3f783bb9877556ce9e3f9d553ecfd07f24ef6f8ef3602fcb5dc6d7e
|
data/.gitignore
ADDED
@@ -0,0 +1,21 @@
|
|
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
|
18
|
+
.ruby-gemset
|
19
|
+
.ruby-version
|
20
|
+
.rspec
|
21
|
+
turbulence
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 YADEV Team
|
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,152 @@
|
|
1
|
+
# Mongoid::Giza [![Build Status](https://travis-ci.org/yadevteam/mongoid-giza.png)](https://travis-ci.org/yadevteam/mongoid-giza) [![Code Climate](https://codeclimate.com/github/yadevteam/mongoid-giza.png)](https://codeclimate.com/github/yadevteam/mongoid-giza) [![Coverage Status](https://coveralls.io/repos/yadevteam/mongoid-giza/badge.png)](https://coveralls.io/r/yadevteam/mongoid-giza)
|
2
|
+
|
3
|
+
Mongoid layer for the Sphinx fulltext search server that supports block fields and dynamic indexes
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem "mongoid-giza"
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install mongoid-giza
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
:warning: **Before proceeding is extremely recommended to read the [Sphinx documentation](http://sphinxsearch.com/docs/current.html) if you are not yet familiar with it. Reading up to chapter 5 is enought to get you going.**
|
22
|
+
|
23
|
+
### Setting up indexes on models
|
24
|
+
|
25
|
+
Use a `sphinx_index` block to create a new index.
|
26
|
+
|
27
|
+
The `sphinx_index` method may receive optional settings that will be set in this index's section or in its source section on the generated sphinx configuration file.
|
28
|
+
These settings take precedence to the defaults defined in `giza.yml`.
|
29
|
+
|
30
|
+
A model may have more than one index, but they need to have different names.
|
31
|
+
If two or more indexes have the same name the last one to be defined is the one which will exist.
|
32
|
+
|
33
|
+
An index name is the name of the class it's defined on unless overwritten by the `name` method inside the index definition block.
|
34
|
+
|
35
|
+
Besides `name`, `field`, `attribute` and `criteria` are the methods avaible inside the index definition block.
|
36
|
+
|
37
|
+
Both `field` and `attribute` take a name as first parameter that may match with a Mongoid field. In this case the value of the field will be used when indexing the objects.
|
38
|
+
The `attribute` method may receive a second paramenter that defines the type of the attribute. If it is ommited, than the type of the Mongoid field will be used.
|
39
|
+
|
40
|
+
At last, both methods may take an block with the object as parameter. The return of the block will be used as the value of the field or attribute when indexing.
|
41
|
+
|
42
|
+
The `criteria` method receives a `Mongoid::Criteria` that will be used to select the objects that will be indexed.
|
43
|
+
It's `Class.all` by default.
|
44
|
+
|
45
|
+
**Example:** Creating a index on the person model
|
46
|
+
|
47
|
+
```
|
48
|
+
class Person
|
49
|
+
include Mongoid::Document
|
50
|
+
include Mongoid::Giza
|
51
|
+
|
52
|
+
field :name
|
53
|
+
field :age, type: Integer
|
54
|
+
|
55
|
+
sphinx_index(enable_star: 1) do
|
56
|
+
field :name
|
57
|
+
field :bio do |person|
|
58
|
+
"#{person.name.capitalize} was born #{person.age.years.days} ago"
|
59
|
+
end
|
60
|
+
attribute :age
|
61
|
+
end
|
62
|
+
end
|
63
|
+
```
|
64
|
+
|
65
|
+
#### Dynamic Indexes
|
66
|
+
|
67
|
+
Because of the schemaless nature of MongoDB, sometimes you may find problems mapping your mongo models to sphinx indexes.
|
68
|
+
To circunvent this limitation Mongoid::Giza supports dynamic indexes.
|
69
|
+
|
70
|
+
When you define a dynamic index, it will generate a regular index based on your definition for each object of the class.
|
71
|
+
This allows the creation of different indexes for objects of the same model that have different dynamic fields.
|
72
|
+
|
73
|
+
Although it's not necessary, dynamic indexes are better used together with a `criteria`,
|
74
|
+
so it's possible to control which objects of the class will be indexed on each determined index.
|
75
|
+
|
76
|
+
To create a dynamic index all that needs to be done is pass the object to the `sphin_index` block.
|
77
|
+
|
78
|
+
**Example:** Creating a dynamic index on the person model.
|
79
|
+
This dynamic index will generate one index for each job that is associated to a person.
|
80
|
+
On each index only the people that have that job will be indexed.
|
81
|
+
Finally each dynamic attribute of the job will be a field on its index.
|
82
|
+
|
83
|
+
```
|
84
|
+
class Job
|
85
|
+
include Mongoid::Document
|
86
|
+
|
87
|
+
field :name
|
88
|
+
# each job object has specific dynamic fields
|
89
|
+
|
90
|
+
has_many :people
|
91
|
+
end
|
92
|
+
|
93
|
+
class Person
|
94
|
+
include Mongoid::Document
|
95
|
+
include Mongoid::Giza
|
96
|
+
|
97
|
+
field :name
|
98
|
+
field :age, type: Integer
|
99
|
+
|
100
|
+
belongs_to :job
|
101
|
+
|
102
|
+
sphinx_index do |person|
|
103
|
+
name person.job.name
|
104
|
+
criteria Person.where(job: person.job)
|
105
|
+
person.job.attributes.except("name").each do |attr, val|
|
106
|
+
field attr.to_sym
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
```
|
111
|
+
|
112
|
+
### Searching
|
113
|
+
|
114
|
+
Use the `search` block on the class that have the indexes where the search should run.
|
115
|
+
It returns a result array, where each position of the array is a [riddle result hash](http://rdoc.info/github/pat/riddle/Riddle/Client#query-instance_method), plus a key with the class name, that has the `Mongoid::Criteria` that selects the matching objects from the mongo database.
|
116
|
+
|
117
|
+
Inside the `search` block use the `fulltext` method to perform a fulltext search.
|
118
|
+
If multiple `fulltext` are called inside a `search` block, then each one will generate a separated query and will return a new position o the results array.
|
119
|
+
|
120
|
+
To filter your search using the attributes defined on the index creation, use the `with` and `without` methods, that accept the name of the attribute and the value or range.
|
121
|
+
|
122
|
+
To order the results, use the `order_by` method, that receives the *attribute* used for sorting and a Symbol, that can be either `:asc` or `:desc`.
|
123
|
+
|
124
|
+
Every other [Riddle::Client](http://rdoc.info/github/pat/riddle/Riddle/Client) setter is avaible without the **=**, to maintain the DSL syntax consistent.
|
125
|
+
|
126
|
+
**Example:** Searching on the person class
|
127
|
+
|
128
|
+
```
|
129
|
+
results = Person.search do
|
130
|
+
fulltext "john"
|
131
|
+
with :age 18..40
|
132
|
+
order_by :age :asc
|
133
|
+
end
|
134
|
+
|
135
|
+
results.first[:Person].each do |person|
|
136
|
+
puts "#{person.name} is #{person.age} years old"
|
137
|
+
end
|
138
|
+
```
|
139
|
+
|
140
|
+
## TODO
|
141
|
+
|
142
|
+
* Support delta indexing
|
143
|
+
* Support RT indexes
|
144
|
+
* Support distributed indexes
|
145
|
+
|
146
|
+
## Contributing
|
147
|
+
|
148
|
+
1. Fork it
|
149
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
150
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
151
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
152
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/lib/mongoid/giza.rb
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
require "docile"
|
2
|
+
require "mongoid"
|
3
|
+
require "riddle"
|
4
|
+
require "mongoid/giza/configuration"
|
5
|
+
require "mongoid/giza/dynamic_index"
|
6
|
+
require "mongoid/giza/index"
|
7
|
+
require "mongoid/giza/index/field"
|
8
|
+
require "mongoid/giza/index/attribute"
|
9
|
+
require "mongoid/giza/indexer"
|
10
|
+
require "mongoid/giza/models/giza_id"
|
11
|
+
require "mongoid/giza/railtie" if defined?(Rails)
|
12
|
+
require "mongoid/giza/search"
|
13
|
+
require "mongoid/giza/version"
|
14
|
+
require "mongoid/giza/xml_pipe2"
|
15
|
+
|
16
|
+
module Mongoid
|
17
|
+
|
18
|
+
# Module that should be included in a Mongoid::Document in order to
|
19
|
+
# index fields of documents of this class
|
20
|
+
#
|
21
|
+
# @example Creating a simple index with a full-text field (named fts) and an attribute (named attr)
|
22
|
+
# class Person
|
23
|
+
# include Mongoid::Document
|
24
|
+
# include Mongoid::Giza
|
25
|
+
#
|
26
|
+
# field :name
|
27
|
+
# field :age, type: Integer
|
28
|
+
#
|
29
|
+
# sphinx_index do
|
30
|
+
# field :name
|
31
|
+
# attribute :age
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# @example Searching the previously defined index for people named John between 18 and 59 years old
|
36
|
+
# results = Person.search do
|
37
|
+
# fulltext "john"
|
38
|
+
# with age: 18..59
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# results.first[:Person].first # => First object that matched
|
42
|
+
module Giza
|
43
|
+
extend ActiveSupport::Concern
|
44
|
+
|
45
|
+
included do
|
46
|
+
Mongoid::Giza::GizaID.create(id: name.to_sym)
|
47
|
+
@giza_configuration = Configuration.instance
|
48
|
+
@static_sphinx_indexes = {}
|
49
|
+
@generated_sphinx_indexes = {}
|
50
|
+
@dynamic_sphinx_indexes = []
|
51
|
+
end
|
52
|
+
|
53
|
+
# Retrives the sphinx compatible id of the object.
|
54
|
+
# If the id does not exists yet, it will be generated
|
55
|
+
#
|
56
|
+
# @return [Integer] the object's integer id generated by Giza
|
57
|
+
def giza_id
|
58
|
+
set(:giza_id, GizaID.next_id(self.class.name.to_sym)) if self[:giza_id].nil?
|
59
|
+
self[:giza_id]
|
60
|
+
end
|
61
|
+
|
62
|
+
module ClassMethods
|
63
|
+
attr_reader :static_sphinx_indexes, :generated_sphinx_indexes, :dynamic_sphinx_indexes
|
64
|
+
|
65
|
+
# Class method that defines a index relative to the current class' objects.
|
66
|
+
# If an argument is given in the block then a dynamic index will be created.
|
67
|
+
# Otherwise it will create a static index.
|
68
|
+
#
|
69
|
+
# @param settings [Hash] optional settings for the index and it's source
|
70
|
+
# @param block [Proc] a block that will be evaluated on an {Mongoid::Giza::Index}
|
71
|
+
def sphinx_index(settings = {}, &block)
|
72
|
+
if block_given?
|
73
|
+
if block.arity > 0
|
74
|
+
add_dynamic_sphinx_index(settings, block)
|
75
|
+
else
|
76
|
+
add_static_sphinx_index(settings, block)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Adds an dynamic index to the class.
|
82
|
+
# Will also automatically generate the dynamic index for each object of the class
|
83
|
+
#
|
84
|
+
# @param settings [Hash] settings for the index and it's source
|
85
|
+
# @param block [Proc] a block that will be evaluated on an {Mongoid::Giza::Index}.
|
86
|
+
# The block receives one argument that is the current object of the class for which the index will be generated
|
87
|
+
def add_dynamic_sphinx_index(settings, block)
|
88
|
+
dynamic_index = DynamicIndex.new(self, settings, block)
|
89
|
+
dynamic_sphinx_indexes << dynamic_index
|
90
|
+
process_dynamic_sphinx_index(dynamic_index)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Adds an static index to the class
|
94
|
+
#
|
95
|
+
# @param settings [Hash] settings for the index and it's source
|
96
|
+
# @param block [Proc] a block that will be evaluated on an {Mongoid::Giza::Index}.
|
97
|
+
def add_static_sphinx_index(settings, block)
|
98
|
+
index = Index.new(self, settings)
|
99
|
+
Docile.dsl_eval(index, &block)
|
100
|
+
static_sphinx_indexes[index.name] = index
|
101
|
+
@giza_configuration.add_index(index)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Generates the indexes from the dynamic index and
|
105
|
+
# registers them on the class and on the configuration
|
106
|
+
#
|
107
|
+
# @param dynamic_index [Mongoid::Giza::DynamicIndex] the dynamic index which will generate the static indexes from
|
108
|
+
def process_dynamic_sphinx_index(dynamic_index)
|
109
|
+
generated = dynamic_index.generate!
|
110
|
+
generated_sphinx_indexes.merge!(generated)
|
111
|
+
generated.each { |name, index| @giza_configuration.add_index(index, true) }
|
112
|
+
end
|
113
|
+
|
114
|
+
# Class method that implements a search DSL using a {Mongoid::Giza::Search} object.
|
115
|
+
# The search will run on indexes defined on the class unless it's overwritten using {Mongoid::Giza::Search#indexes=}
|
116
|
+
#
|
117
|
+
# @param block [Proc] a block that will be evaluated on a {Mongoid::Giza::Search}
|
118
|
+
#
|
119
|
+
# @return [Array] an Array with Riddle result hashes containing an additional key with the name of the class.
|
120
|
+
# The value of this aditional key is a Mongoid::Criteria that return the actual objects of the match
|
121
|
+
def search(&block)
|
122
|
+
search = Mongoid::Giza::Search.new(@giza_configuration.searchd.address, @giza_configuration.searchd.port, *sphinx_indexes_names)
|
123
|
+
Docile.dsl_eval(search, &block)
|
124
|
+
results = search.run
|
125
|
+
results.each { |result| result[name.to_sym] = self.in(giza_id: result[:matches].map { |match| match[:doc] }) }
|
126
|
+
end
|
127
|
+
|
128
|
+
# Regenerates all dynamic indexes of the class
|
129
|
+
def regenerate_dynamic_sphinx_indexes
|
130
|
+
generated_sphinx_indexes.clear
|
131
|
+
dynamic_sphinx_indexes.each { |dynamic_index| process_dynamic_sphinx_index(dynamic_index) }
|
132
|
+
end
|
133
|
+
|
134
|
+
# Execute the indexing routines of the indexes defined on the class.
|
135
|
+
# This means (re)create the sphinx configuration file and then execute the indexer program on it.
|
136
|
+
# If no index names are supplied than all indexes defined on the class will be indexed.
|
137
|
+
# If none of the index names supplied are on this class then nothing is indexed
|
138
|
+
#
|
139
|
+
# @param names [Array] a list of index names of this class that will be indexed
|
140
|
+
def sphinx_indexer!(*names)
|
141
|
+
indexes_names = names.length > 0 ? sphinx_indexes_names.select { |name| names.include? name } : sphinx_indexes_names
|
142
|
+
Mongoid::Giza::Indexer.instance.index!(*indexes_names) if indexes_names.length > 0
|
143
|
+
end
|
144
|
+
|
145
|
+
# Retrieves all the sphinx indexes defined on this class, static and dynamic
|
146
|
+
#
|
147
|
+
# @return [Array] an Array of indexes from the current class {Mongoid::Giza::Index}
|
148
|
+
def sphinx_indexes
|
149
|
+
static_sphinx_indexes.merge(generated_sphinx_indexes)
|
150
|
+
end
|
151
|
+
|
152
|
+
# Retrieves all the names of sphinx indexes defined on this class, static and dynamic
|
153
|
+
#
|
154
|
+
# @return [Array] an Array of names of indexes from the current class {Mongoid::Giza::Index}
|
155
|
+
def sphinx_indexes_names
|
156
|
+
static_sphinx_indexes.merge(generated_sphinx_indexes).keys
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
require "erb"
|
2
|
+
require "ostruct"
|
3
|
+
require "yaml"
|
4
|
+
|
5
|
+
module Mongoid
|
6
|
+
module Giza
|
7
|
+
|
8
|
+
# Holds the configuration of the module
|
9
|
+
class Configuration < Riddle::Configuration
|
10
|
+
include Singleton
|
11
|
+
|
12
|
+
attr_reader :source, :index, :file
|
13
|
+
|
14
|
+
# Creates the configuration instance
|
15
|
+
def initialize
|
16
|
+
super
|
17
|
+
@source = Riddle::Configuration::XMLSource.new(:source, :xmlpipe2)
|
18
|
+
@index = Riddle::Configuration::Index.new(:index, @source)
|
19
|
+
@file = OpenStruct.new(output_path: "./sphinx.conf")
|
20
|
+
@static_indexes = {}
|
21
|
+
@generated_indexes = {}
|
22
|
+
end
|
23
|
+
|
24
|
+
# Loads a YAML file with settings defined.
|
25
|
+
# Settings that are not recognized are ignored
|
26
|
+
#
|
27
|
+
# @param path [String] path to the YAML file which contains the settings defined
|
28
|
+
# @param env [String] environment whoose settings will be loaded
|
29
|
+
def load(path, env)
|
30
|
+
YAML.load(File.open(path).read)[env].each do |section_name, settings|
|
31
|
+
section = instance_variable_get("@#{section_name}")
|
32
|
+
if !section.nil?
|
33
|
+
settings.each do |setting, value|
|
34
|
+
method = "#{setting}="
|
35
|
+
section.send(method, value) if section.respond_to?(method)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Adds an index to the sphinx configuration,
|
42
|
+
# so this index can be rendered on the configuration file
|
43
|
+
#
|
44
|
+
# @param index [Mongoid::Giza::Index] the index that will be added to the configuration
|
45
|
+
# @param generated [TrueClass, FalseClass] determines if this index was generated from a {Mongoid::Giza::DynamicIndex}
|
46
|
+
def add_index(index, generated = false)
|
47
|
+
riddle_index = create_index(index)
|
48
|
+
if generated
|
49
|
+
position = register_index(riddle_index, @generated_indexes)
|
50
|
+
else
|
51
|
+
position = register_index(riddle_index, @static_indexes)
|
52
|
+
end
|
53
|
+
indices[position] = riddle_index
|
54
|
+
end
|
55
|
+
|
56
|
+
# Creates a new Riddle::Index based on the given {Mongoid::Giza::Index}
|
57
|
+
#
|
58
|
+
# @param index [Mongoid::Giza::Index] the index to generate the configuration from
|
59
|
+
#
|
60
|
+
# @return [Riddle::Configuration::Index] the created riddle index
|
61
|
+
def create_index(index)
|
62
|
+
source = Riddle::Configuration::XMLSource.new(index.name, :xmlpipe2)
|
63
|
+
riddle_index = Riddle::Configuration::Index.new(index.name, source)
|
64
|
+
apply_default_settings(@index, riddle_index, index)
|
65
|
+
apply_default_settings(@source, source, index)
|
66
|
+
apply_user_settings(index, riddle_index)
|
67
|
+
apply_user_settings(index, source)
|
68
|
+
riddle_index.path = File.join(riddle_index.path, index.name.to_s)
|
69
|
+
riddle_index.charset_type = "utf-8"
|
70
|
+
riddle_index
|
71
|
+
end
|
72
|
+
|
73
|
+
# Adds the riddle index to it's respective collection
|
74
|
+
#
|
75
|
+
# @param index [Riddle::Configuration::Index] the index that will be registrated
|
76
|
+
# @param indexes [Hash] the collection which will hold this index
|
77
|
+
#
|
78
|
+
# @return [Integer] the position where this index should be inserted on the configuration indices array
|
79
|
+
def register_index(index, indexes)
|
80
|
+
position = indexes.has_key?(index.name) ? indices.index(indexes[index.name]) : indices.length
|
81
|
+
indexes[index.name] = index
|
82
|
+
position
|
83
|
+
end
|
84
|
+
|
85
|
+
# Applies the settings defined on an object loaded from the configuration to a Riddle::Configuration::Index or Riddle::Configuration::XMLSource instance.
|
86
|
+
# Used internally by {#add_index} so you should never need to call it directly
|
87
|
+
#
|
88
|
+
# @param default [Riddle::Configuration::Index, Riddle::Configuration::XMLSource] the object that holds the global settings values
|
89
|
+
# @param section [Riddle::Configuration::Index, Riddle::Configuration::XMLSource] the object that settings are being set
|
90
|
+
def apply_default_settings(default, section, index)
|
91
|
+
default.class.settings.each do |setting|
|
92
|
+
method = "#{setting}="
|
93
|
+
value = interpolate_string(default.send("#{setting}"), index)
|
94
|
+
section.send(method, value) if !value.nil? and section.respond_to?(method)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Applies the settings defined on a {Mongoid::Giza::Index} to the Riddle::Configuration::Index or Riddle::Configuration::XMLSource.
|
99
|
+
# Used internally by {#add_index} so you should never need to call it directly
|
100
|
+
#
|
101
|
+
# @param index [Mongoid::Giza::Index] the index where the settings were defined
|
102
|
+
# @param section [Riddle::Configuration::Index, Riddle::Configuration::XMLSource] where the settings will be applied
|
103
|
+
def apply_user_settings(index, section)
|
104
|
+
index.settings.each do |setting, value|
|
105
|
+
method = "#{setting}="
|
106
|
+
section.send(method, interpolate_string(value, index)) if section.respond_to?(method)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# Interpolates a value if it's a String using ERB.
|
111
|
+
# Useful for defining dynamic settings.
|
112
|
+
# The ERB template may reference to the current {Mongoid::Giza::Index} and it's methods
|
113
|
+
#
|
114
|
+
# @param value [String] the ERB template that will be interpolated
|
115
|
+
# @param index [Mongoid::Giza::Index] the index that will be accessible from the template
|
116
|
+
#
|
117
|
+
# @return [Object] if value was a String and contains ERB syntax than it will beinterpolated and returned.
|
118
|
+
# Otherwise it will return the original value
|
119
|
+
def interpolate_string(value, index)
|
120
|
+
namespace = OpenStruct.new(index: index)
|
121
|
+
value.is_a?(String) ? ERB.new(value).result(namespace.instance_eval { binding }) : value
|
122
|
+
end
|
123
|
+
|
124
|
+
# Renders the configuration to the output_path
|
125
|
+
def render
|
126
|
+
File.open(@file.output_path, "w") { |file| file.write(super) }
|
127
|
+
end
|
128
|
+
|
129
|
+
# Removes all Riddle::Index from the indices Array that where created from a generated {Mongoid::Giza::Index}
|
130
|
+
def clear_generated_indexes
|
131
|
+
@generated_indexes.each { |name, index| indices.delete(index) }
|
132
|
+
@generated_indexes = {}
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|