Module: CouchRest::Mixins::Indexer::ClassMethods
- Defined in:
- lib/mixins/indexer.rb
Overview
Patches to the CouchRest ExtendedDocument module: Adds the “fulltext_index” method for enabling indexing and defining the fields to include as a domain specific extention. This method also assures the existence of a special design document used to generate indexes from.
An additional save callback sets an ID like “Post-123123” (class name plus pure numeric ID compatible with Sphinx) for new objects).
Last but not least method “by_fulltext_index” is defined allowing a full text search like “foo @title bar” within the context of the current class.
Samples:
class Post < CouchRest::ExtendedDocument
use_database SERVER.default_database
property :title
property :body
fulltext_index :title, :body
end
Post.by_fulltext_index('first')
=> [...]
post = Post.by_fulltext_index('this is @title post').first
post.title
=> "First Post"
post.class
=> Post
Instance Method Summary collapse
-
#assure_existing_couch_index ⇒ Object
Defines a design document with the functions needed to lookup modified documents.
-
#by_fulltext_index(query, options = {}) ⇒ Object
Searches for an object of this model class (e.g. Post, Comment) and the requested query string.
-
#fulltext_index(*keys) ⇒ Object
Method for enabling fulltext indexing and for defining the fields to include.
-
#multi_get(ids) ⇒ Object
Returns objects for all provided keys not reducing lookup to a certain type.
Instance Method Details
#assure_existing_couch_index ⇒ Object
Defines a design document with the functions needed to lookup modified documents. If the current version is to old, a new version of the design document is stored.
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 |
# File 'lib/mixins/indexer.rb', line 202 def assure_existing_couch_index if (doc = database.get("_design/CouchSphinxIndex") rescue nil) return if (ver = doc['version']) and ver == CouchSphinx::VERSION database.delete_doc(doc) end all_couchrests = { :map => 'function(doc) { if(doc["couchrest-type"] && (doc["created_at"] || doc["updated_at"])) { var date = doc["updated_at"]; if(date == null) date = doc["created_at"]; emit(doc._id, doc); } }' } = { :map => 'function(doc) { if(doc["couchrest-type"] && (doc["created_at"] || doc["updated_at"])) { var date = doc["updated_at"]; if(date == null) date = doc["created_at"]; emit(Date.parse(date), doc); } }' } database.save_doc({ "_id" => "_design/CouchSphinxIndex", :lib_version => CouchSphinx::VERSION, :views => { :all_couchrests => all_couchrests, :couchrests_by_timestamp => } }) end |
#by_fulltext_index(query, options = {}) ⇒ Object
Searches for an object of this model class (e.g. Post, Comment) and the requested query string. The query string may contain any query provided by Sphinx.
Call CouchRest::ExtendedDocument.by_fulltext_index() to query without reducing to a single class type.
Parameters:
- query
-
Query string like “foo @title bar”
- options
-
Additional options to set
Options:
- :match_mode
-
Optional Riddle match mode (defaults to :extended)
- :limit
-
Optional Riddle limit (Riddle default)
- :max_matches
-
Optional Riddle max_matches (Riddle default)
- :sort_by
-
Optional Riddle sort order (also sets sort_mode to :extended)
- :raw
-
Flag to return only IDs and do not lookup objects (defaults to false)
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/mixins/indexer.rb', line 137 def by_fulltext_index(query, = {}) if self == ExtendedDocument client = Riddle::Client.new else client = Riddle::Client.new(fulltext_opts[:server], fulltext_opts[:port]) query = query + " @couchrest-type #{self}" end client.match_mode = [:match_mode] || :extended if (limit = [:limit]) client.limit = limit end if (max_matches = [:max_matches]) client.max_matches = matches end if (sort_by = [:sort_by]) client.sort_mode = :extended client.sort_by = sort_by end result = client.query(query) if result and result[:status] == 0 and (matches = result[:matches]) keys = matches.collect { |row| (CouchSphinx::MultiAttribute.decode( row[:attributes]['csphinx-class']) + '-' + row[:doc].to_s) rescue nil }.compact return keys if [:raw] return multi_get(keys) else return [] end end |
#fulltext_index(*keys) ⇒ Object
Method for enabling fulltext indexing and for defining the fields to include.
Parameters:
- keys
-
Array of field keys to include plus options Hash
Options:
- :server
-
Server name (defaults to localhost)
- :port
-
Server port (defaults to 3312)
- :idsize
-
Number of bits for the ID to generate (defaults to 32)
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/mixins/indexer.rb', line 74 def fulltext_index(*keys) opts = keys.pop if keys.last.is_a?(Hash) opts ||= {} # Handle some options: Future use... :-) # Save the keys to index and the options for later use in callback. # Helper method cattr_accessor is already bootstrapped by couchrest # gem. cattr_accessor :fulltext_keys cattr_accessor :fulltext_opts self.fulltext_keys = keys self.fulltext_opts = opts # We add a few new functions to CouchDB for retrieving modified # documents... assure_existing_couch_index # Overwrite setting of new ID to do something compatible with # Sphinx. If an ID already exists, we try to match it with our # Schema and cowardly ignore if not. save_callback :before do |object| if object.id.nil? idsize = fulltext_opts[:idsize] || 32 limit = (1 << idsize) - 1 while true id = rand(limit) candidate = "#{self.class.to_s}-#{id}" begin object.class.get(candidate) # Resource not found exception if available rescue RestClient::ResourceNotFound object['_id'] = candidate break end end end end end |
#multi_get(ids) ⇒ Object
Returns objects for all provided keys not reducing lookup to a certain type. Casts to a CouchRest object if possible.
Parameters:
- ids
-
Array of document IDs to retrieve
183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/mixins/indexer.rb', line 183 def multi_get(ids) result = CouchRest.post(SERVER.default_database.to_s + '/_all_docs?include_docs=true', :keys => ids) return result['rows'].collect { |row| row = row['doc'] if row['couchrest-type'].nil? if row and (class_name = row['couchrest-type']) eval(class_name.to_s).new(row) rescue row else row end } end |