Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 510 lines (345 sloc) 22.537 kB
50b955f @nertzy Add the beginnings of a README
nertzy authored
1 = pg_search
2
3 * http://github.com/casecommons/pg_search/
4
30daa11 Remove extra colons from README
Grant Hutchins & Rachel Heaton authored
5 == DESCRIPTION
50b955f @nertzy Add the beginnings of a README
nertzy authored
6
7 PgSearch builds named scopes that take advantage of PostgreSQL's full text search
8
92bd18e @nertzy Add link to blog post
nertzy authored
9 Read the blog post introducing PgSearch at http://bit.ly/pg_search
10
30daa11 Remove extra colons from README
Grant Hutchins & Rachel Heaton authored
11 == INSTALL
50b955f @nertzy Add the beginnings of a README
nertzy authored
12
13 gem install pg_search
14
15 === Rails 3
16
17 In Gemfile
18
19 gem 'pg_search'
20
553fee8 @nertzy Add information about the 0.2 series
nertzy authored
21 === Rails 2
22
23 The newest versions of PgSearch no longer support Rails 2. However, the 0.2 series still works. It's not actively maintained, but submissions are welcome for backports and bugfixes.
24
25 The 0.2 branch lives at https://github.com/Casecommons/pg_search/tree/0.2-stable
26
13cb6f0 Use a Railtie to load rake tasks
Grant Hutchins & Peter Jaros authored
27 === Other ActiveRecord-based projects
28
ed97020 @nertzy Rails projects don't need to include tasks.rb
nertzy authored
29 In addition to installing and requiring the gem, you may want to include the PgSearch rake tasks in your Rakefile. This isn't necessary for Rails projects, which gain the Rake tasks via a Railtie.
13cb6f0 Use a Railtie to load rake tasks
Grant Hutchins & Peter Jaros authored
30
31 load "pg_search/tasks.rb"
32
0511156 Adding more documentation
Grant Hutchins & Rachel Heaton authored
33 == USAGE
34
35 To add PgSearch to an ActiveRecord model, simply include the PgSearch module.
36
37 class Shape < ActiveRecord::Base
38 include PgSearch
39 end
40
b72d530 @nertzy Documentation for multi-search
nertzy authored
41 === Multi-search vs. search scopes
42
43 pg_search supports two different techniques for searching, multi-search and search scopes.
44
45 The first technique is multi-search, in which records of many different Active Record classes can be mixed together into one global search index across your entire application. Most sites that want to support a generic search page will want to use this feature.
46
47 The other technique is search scopes, which allow you to do more advanced searching against only one Active Record class. This is more useful for building things like autocompleters or filtering a list of items in a faceted search.
48
49 === Multi-search
50
51 ==== Setup
52
53 Before using multi-search, you must generate and run a migration to create the pg_search_documents database table.
54
7cdbced @nertzy Convert rake tasks into generators
nertzy authored
55 $ rails g pg_search:migration:multisearch
b72d530 @nertzy Documentation for multi-search
nertzy authored
56 $ rake db:migrate
57
58 ==== multisearchable
59
60 To add a model to the global search index for your application, call multisearchable in its class definition.
61
62 class EpicPoem < ActiveRecord::Base
63 include PgSearch
64 multisearchable :against => [:title, :author]
65 end
66
67 class Flower < ActiveRecord::Base
68 include PgSearch
69 multisearchable :against => :color
70 end
71
72 Whenever a record is created, updated, or destroyed, an Active Record callback will fire, leading to the creation of a corresponding PgSearch::Document record in the pg_search_documents table. The :against option can be one or several methods which will be called on the record to generate its search text.
73
74 ==== Multi-search associations
75
76 Two associations are built automatically. On the original record, there is a has_one :pg_search_document association pointing to the PgSearch::Document record, and on the PgSearch::Document record there is a belongs_to :searchable polymorphic association pointing back to the original record.
77
78 odyssey = EpicPoem.create!(:title => "Odyssey", :author => "Homer")
79 search_document = odyssey.pg_search_document #=> PgSearch::Document instance
80 search_document.searchable #=> #<EpicPoem id: 1, title: "Odyssey", author: "Homer">
81
82 ==== Searching in the global search index
83
d6ce97c PgSearch.multisearch now has options
Grant Hutchins & Joe Moore authored
84 To fetch the PgSearch::Document entries for all of the records that match a given query, use PgSearch.multisearch.
b72d530 @nertzy Documentation for multi-search
nertzy authored
85
86 odyssey = EpicPoem.create!(:title => "Odyssey", :author => "Homer")
87 rose = Flower.create!(:color => "Red")
88 PgSearch.multisearch("Homer") #=> [#<PgSearch::Document searchable: odyssey>]
89 PgSearch.multisearch("Red") #=> [#<PgSearch::Document searchable: rose>]
90
91 ==== Chaining method calls onto the results
92
93 PgSearch.multisearch returns an ActiveRecord::Relation, just like scopes do, so you can chain scope calls to the end. This works with gems like Kaminari that add scope methods. Just like with regular scopes, the database will only receive SQL requests when necessary.
94
95 PgSearch.multisearch("Bertha").limit(10)
96 PgSearch.multisearch("Juggler").where(:searchable_type => "Occupation")
97 PgSearch.multisearch("Alamo").page(3).per_page(30)
98 PgSearch.mulitsearch("Diagonal").find_each do |document|
99 puts document.searchable.updated_at
100 end
101
d6ce97c PgSearch.multisearch now has options
Grant Hutchins & Joe Moore authored
102 ==== Configuring multi-search
103
84da89d @mrhaddad Update README
mrhaddad authored
104 PgSearch.multisearch can be configured using the same options as `pg_search_scope` (explained in more detail below). Just set the PgSearch.multisearch_options in an initializer:
d6ce97c PgSearch.multisearch now has options
Grant Hutchins & Joe Moore authored
105
84da89d @mrhaddad Update README
mrhaddad authored
106 PgSearch.multisearch_options = {
d6ce97c PgSearch.multisearch now has options
Grant Hutchins & Joe Moore authored
107 :using => [:tsearch, :trigram],
108 :ignoring => :accents
109 }
110
b72d530 @nertzy Documentation for multi-search
nertzy authored
111 ==== Rebuilding search documents for a given class
112
113 If you change the :against option on a class, add multisearchable to a class that already has records in the database, or remove multisearchable from a class in order to remove it from the index, you will find that the pg_search_documents table could become out-of-sync with the actual records in your other tables.
114
115 The index can also become out-of-sync if you ever modify records in a way that does not trigger Active Record callbacks. For instance, the #update_attribute instance method and the .update_all class method both skip callbacks and directly modify the database.
116
117 To remove all of the documents for a given class, you can simply delete all of the PgSearch::Document records.
118
119 PgSearch::Document.delete_all(:searchable_type => "Animal")
120
121 Run this Rake task to regenerate all of the documents for a given class.
122
f702e62 @maxdemarzi Documentation update: rake command expects MODEL instead of CLASS
maxdemarzi authored
123 $ rake pg_search:multisearch:rebuild MODEL=BlogPost
b72d530 @nertzy Documentation for multi-search
nertzy authored
124
125 Currently this is only supported for :against methods that directly map to Active Record attributes. Until that is fixed, you could also manually rebuild all of the documents.
126
127 PgSearch::Document.delete_all(:searchable_type => "Ingredient")
128 Ingredient.find_each { |record| record.update_pg_search_document }
129
130 ==== Disabling multi-search indexing temporarily
131
132 If you have a large bulk operation to perform, such as importing a lot of records from an external source, you might want to speed things up by turning off indexing temporarily. You could then use one of the techniques above to rebuild the search documents off-line.
133
134 PgSearch.disable_multisearch do
135 Movie.import_from_xml_file(File.open("movies.xml"))
136 end
137
0511156 Adding more documentation
Grant Hutchins & Rachel Heaton authored
138 === pg_search_scope
139
140 You can use pg_search_scope to build a search scope. The first parameter is a scope name, and the second parameter is an options hash. The only required option is :against, which tells pg_search_scope which column or columns to search against.
141
142 ==== Searching against one column
143
144 To search against a column, pass a symbol as the :against option.
145
146 class BlogPost < ActiveRecord::Base
147 include PgSearch
148 pg_search_scope :search_by_title, :against => :title
149 end
150
151 We now have an ActiveRecord scope named search_by_title on our BlogPost model. It takes one parameter, a search query string.
152
153 BlogPost.create!(:title => "Recent Developments in the World of Pastrami")
154 BlogPost.create!(:title => "Prosciutto and You: A Retrospective")
155 BlogPost.search_by_title("pastrami") # => [#<BlogPost id: 2, title: "Recent Developments in the World of Pastrami">]
156
157 ==== Searching against multiple columns
158
159 Just pass an Array if you'd like to search more than one column.
160
161 class Person < ActiveRecord::Base
162 include PgSearch
163 pg_search_scope :search_by_full_name, :against => [:first_name, :last_name]
164 end
165
166 Now our search query can match either or both of the columns.
167
168 person_1 = Person.create!(:first_name => "Grant", :last_name => "Hill")
169 person_2 = Person.create!(:first_name => "Hugh", :last_name => "Grant")
170
171 Person.search_by_full_name("Grant") # => [person_1, person_2]
172 Person.search_by_full_name("Grant Hill") # => [person_1]
173
3fae8e9 Document dynamic search scopes
Grant Hutchins & Rachel Heaton authored
174 ==== Dynamic search scopes
175
176 Just like with Active Record named scopes, you can pass in a Proc object that returns a hash of options. For instance, the following scope takes a parameter that dynamically chooses which column to search against.
177
178 Important: The returned hash must include a :query key. Its value does not necessary have to be dynamic. You could choose to hard-code it to a specific value if you wanted.
179
180 class Person < ActiveRecord::Base
181 include PgSearch
182 pg_search_scope :search_by_name, lambda do |name_part, query|
183 raise ArgumentError unless [:first, :last].include?(name_part)
184 {
185 :against => name_part,
186 :query => query
187 }
188 end
189 end
190
191 person_1 = Person.create!(:first_name => "Grant", :last_name => "Hill")
192 person_2 = Person.create!(:first_name => "Hugh", :last_name => "Grant")
193
194 Person.search_by_name :first, "Grant" # => [person_1]
195 Person.search_by_name :last, "Grant" # => [person_2]
196
0511156 Adding more documentation
Grant Hutchins & Rachel Heaton authored
197 ==== Searching through associations
198
5ff3fa3 @nertzy Backport array_agg() to PostgreSQL 8.3 and earlier
nertzy authored
199 It is possible to search columns on associated models. Note that if you do this, it will be impossible to speed up searches with database indexes. However, it is supported as a quick way to try out cross-model searching.
200
7cdbced @nertzy Convert rake tasks into generators
nertzy authored
201 In PostgreSQL 8.3 and earlier, you must install a utility function into your database. To generate and run a migration for this, run:
5ff3fa3 @nertzy Backport array_agg() to PostgreSQL 8.3 and earlier
nertzy authored
202
7cdbced @nertzy Convert rake tasks into generators
nertzy authored
203 $ rails g pg_search:migration:associated_against
204 $ rake db:migrate
5ff3fa3 @nertzy Backport array_agg() to PostgreSQL 8.3 and earlier
nertzy authored
205
206 This migration is safe to run against newer versions of PostgreSQL as well. It will essentially do nothing.
207
208 You can pass a Hash into the :associated_against option to set up searching through associations. The keys are the names of the associations and the value works just like an :against option for the other model. Right now, searching deeper than one association away is not supported. You can work around this by setting up a series of :through associations to point all the way through.
0511156 Adding more documentation
Grant Hutchins & Rachel Heaton authored
209
210 class Cracker < ActiveRecord::Base
7aaf61e Fix a typo in README
Grant Hutchins & Rachel Heaton authored
211 has_many :cheeses
0511156 Adding more documentation
Grant Hutchins & Rachel Heaton authored
212 end
213
214 class Cheese < ActiveRecord::Base
215 end
216
217 class Salami < ActiveRecord::Base
218 include PgSearch
3fae8e9 Document dynamic search scopes
Grant Hutchins & Rachel Heaton authored
219
0511156 Adding more documentation
Grant Hutchins & Rachel Heaton authored
220 belongs_to :cracker
221 has_many :cheeses, :through => :cracker
3fae8e9 Document dynamic search scopes
Grant Hutchins & Rachel Heaton authored
222
0511156 Adding more documentation
Grant Hutchins & Rachel Heaton authored
223 pg_search_scope :tasty_search, :associated_against => {
224 :cheeses => [:kind, :brand],
225 :cracker => :kind
226 }
227 end
228
229 salami_1 = Salami.create!
230 salami_2 = Salami.create!
231 salami_3 = Salami.create!
232
233 limburger = Cheese.create!(:kind => "Limburger")
234 brie = Cheese.create!(:kind => "Brie")
235 pepper_jack = Cheese.create!(:kind => "Pepper Jack")
236
237 Cracker.create!(:kind => "Black Pepper", :cheeses => [brie], :salami => salami_1)
238 Cracker.create!(:kind => "Ritz", :cheeses => [limburger, pepper_jack], :salami => salami_2)
239 Cracker.create!(:kind => "Graham", :cheeses => [limburger], :salami => salami_3)
3fae8e9 Document dynamic search scopes
Grant Hutchins & Rachel Heaton authored
240
0511156 Adding more documentation
Grant Hutchins & Rachel Heaton authored
241 Salami.tasty_search("pepper") # => [salami_1, salami_2]
242
243 === Searching using different search features
244
f872548 @nertzy Update README to reflect change from :features to :using
nertzy authored
245 By default, pg_search_scope uses the built-in {PostgreSQL text search}[http://www.postgresql.org/docs/current/static/textsearch-intro.html]. If you pass the :using option to pg_search_scope, you can choose alternative search techniques.
0511156 Adding more documentation
Grant Hutchins & Rachel Heaton authored
246
247 class Beer < ActiveRecord::Base
248 include PgSearch
f872548 @nertzy Update README to reflect change from :features to :using
nertzy authored
249 pg_search_scope :search_name, :against => :name, :using => [:tsearch, :trigram, :dmetaphone]
0511156 Adding more documentation
Grant Hutchins & Rachel Heaton authored
250 end
251
252 The currently implemented features are
253
825788c Fix links
Grant Hutchins & Rachel Heaton authored
254 * :tsearch - {Full text search}[http://www.postgresql.org/docs/current/static/textsearch-intro.html] (built-in with 8.3 and later, available as a contrib package for some earlier versions)
255 * :trigram - {Trigram search}[http://www.postgresql.org/docs/current/static/pgtrgm.html], which requires the trigram contrib package
256 * :dmetaphone - {Double Metaphone search}[http://www.postgresql.org/docs/9.0/static/fuzzystrmatch.html#AEN120188], which requires the fuzzystrmatch contrib package
0511156 Adding more documentation
Grant Hutchins & Rachel Heaton authored
257
258 ==== :tsearch (Full Text Search)
259
260 PostgreSQL's built-in full text search supports weighting, prefix searches, and stemming in multiple languages.
261
262 ===== Weighting
263 Each searchable column can be given a weight of "A", "B", "C", or "D". Columns with earlier letters are weighted higher than those with later letters. So, in the following example, the title is the most important, followed by the subtitle, and finally the content.
264
265 class NewsArticle < ActiveRecord::Base
266 include PgSearch
ab1827d Update README to remove Rails 2 and fix typos.
Grant Hutchins & Ian Zabel authored
267 pg_search_scope :search_full_text, :against => {
3fae8e9 Document dynamic search scopes
Grant Hutchins & Rachel Heaton authored
268 :title => 'A',
269 :subtitle => 'B',
0511156 Adding more documentation
Grant Hutchins & Rachel Heaton authored
270 :content => 'C'
271 }
272 end
3fae8e9 Document dynamic search scopes
Grant Hutchins & Rachel Heaton authored
273
0511156 Adding more documentation
Grant Hutchins & Rachel Heaton authored
274 You can also pass the weights in as an array of arrays, or any other structure that responds to #each and yields either a single symbol or a symbol and a weight. If you omit the weight, a default will be used.
275
276 class NewsArticle < ActiveRecord::Base
277 include PgSearch
ab1827d Update README to remove Rails 2 and fix typos.
Grant Hutchins & Ian Zabel authored
278 pg_search_scope :search_full_text, :against => [
3fae8e9 Document dynamic search scopes
Grant Hutchins & Rachel Heaton authored
279 [:title, 'A'],
280 [:subtitle, 'B'],
0511156 Adding more documentation
Grant Hutchins & Rachel Heaton authored
281 [:content, 'C']
282 ]
283 end
284
285 class NewsArticle < ActiveRecord::Base
286 include PgSearch
ab1827d Update README to remove Rails 2 and fix typos.
Grant Hutchins & Ian Zabel authored
287 pg_search_scope :search_full_text, :against => [
3fae8e9 Document dynamic search scopes
Grant Hutchins & Rachel Heaton authored
288 [:title, 'A'],
289 {:subtitle => 'B'},
0511156 Adding more documentation
Grant Hutchins & Rachel Heaton authored
290 :content
291 ]
292 end
293
9220f96 @nertzy Update README
nertzy authored
294 ===== :prefix (PostgreSQL 8.4 and newer only)
aaff48c Add documentation for :prefix
Grant Hutchins & Rachel Heaton authored
295
296 PostgreSQL's full text search matches on whole words by default. If you want to search for partial words, however, you can set :prefix to true. Since this is a :tsearch-specific option, you should pass it to :tsearch directly, as shown in the following example.
297
298 class Superhero < ActiveRecord::Base
299 include PgSearch
300 pg_search_scope :whose_name_starts_with,
301 :against => :name,
302 :using => {
303 :tsearch => {:prefix => true}
304 }
305 end
306
307 batman = Superhero.create :name => 'Batman'
308 batgirl = Superhero.create :name => 'Batgirl'
309 robin = Superhero.create :name => 'Robin'
310
311 Superhero.whose_name_starts_with("Bat") # => [batman, batgirl]
0511156 Adding more documentation
Grant Hutchins & Rachel Heaton authored
312
5df6e50 Documentation for :dictionary
Grant Hutchins & Rachel Heaton authored
313 ===== :dictionary
314
b28c311 @nertzy Add note to README about "simple" being the default dictionary for :t…
nertzy authored
315 PostgreSQL full text search also support multiple dictionaries for stemming. You can learn more about how dictionaries work by reading the {PostgreSQL documention}[http://www.postgresql.org/docs/current/static/textsearch-dictionaries.html]. If you use one of the language dictionaries, such as "english", then variants of words (e.g. "jumping" and "jumped") will match each other. If you don't want stemming, you should pick the "simple" dictionary which does not do any stemming. If you don't specify a dictionary, the "simple" dictionary will be used.
5df6e50 Documentation for :dictionary
Grant Hutchins & Rachel Heaton authored
316
317 class BoringTweet < ActiveRecord::Base
318 include PgSearch
319 pg_search_scope :kinda_matching,
320 :against => :text,
321 :using => {
322 :tsearch => {:dictionary => "english"}
323 }
324 pg_search_scope :literally_matching,
325 :against => :text,
326 :using => {
327 :tsearch => {:dictionary => "simple"}
328 }
329 end
330
331 sleepy = BoringTweet.create! :text => "I snoozed my alarm for fourteen hours today. I bet I can beat that tomorrow! #sleepy"
332 sleeping = BoringTweet.create! :text => "You know what I like? Sleeping. That's what. #enjoyment"
333 sleeper = BoringTweet.create! :text => "Have you seen Woody Allen's movie entitled Sleeper? Me neither. #boycott"
334
335 BoringTweet.kinda_matching("sleeping") # => [sleepy, sleeping, sleeper]
336 BoringTweet.literally_matching("sleeping") # => [sleeping]
337
68e2406 @nertzy Documentation for :normalization
nertzy authored
338 ===== :normalization
339
340 PostgreSQL supports multiple algorithms for ranking results against queries. For instance, you might want to consider overall document size or the distance between multiple search terms in the original text. This option takes an integer, which is passed directly to PostgreSQL. According to the latest {PostgreSQL documentation}[http://www.postgresql.org/docs/current/static/textsearch-controls.html], the supported algorithms are:
341
342 0 (the default) ignores the document length
343 1 divides the rank by 1 + the logarithm of the document length
344 2 divides the rank by the document length
345 4 divides the rank by the mean harmonic distance between extents
346 8 divides the rank by the number of unique words in document
347 16 divides the rank by 1 + the logarithm of the number of unique words in document
348 32 divides the rank by itself + 1
349
350 This integer is a bitmask, so if you want to combine algorithms, you can add their numbers together. (e.g. to use algorithms 1, 8, and 32, you would pass 1 + 8 + 32 = 41)
351
352 class BigLongDocument < ActiveRecord::Base
353 include PgSearch
354 pg_search_scope :regular_search,
355 :against => :text
356
357 pg_search_scope :short_search,
358 :against => :text,
359 :using => {
360 :tsearch => {:normalization => 2}
361 }
362
363 long = BigLongDocument.create!(:text => "Four score and twenty years ago")
364 short = BigLongDocument.create!(:text => "Four score")
365
366 BigLongDocument.regular_search("four score") #=> [long, short]
367 BigLongDocument.short_search("four score") #=> [short, long]
368
fc72793 @Ferdev Add :any_word option to :tsearch search feature
Ferdev authored
369 ===== :any_word
370
371 Setting this attribute to true will perform a search which will return all models containing any word in the search terms.
372
373 class Number < ActiveRecord::Base
374 include PgSearch
375 pg_search_scope :search_any_word,
376 :against => :text,
377 :using => {
378 :tsearch => {:any_word => true}
379 }
380
381 pg_search_scope :search_all_words,
382 :against => :text
383 end
384
385 one = Number.create! :text => 'one'
386 two = Number.create! :text => 'two'
387 three = Number.create! :text => 'three'
388
389 Number.search_any_word('one two three') # => [one, two, three]
390 Number.search_all_words('one two three') # => []
391
1e15f96 Documentation for :dmetaphone
Grant Hutchins & Rachel Heaton authored
392 ==== :dmetaphone (Double Metaphone soundalike search)
393
394 {Double Metaphone}[http://en.wikipedia.org/wiki/Double_Metaphone] is an algorithm for matching words that sound alike even if they are spelled very differently. For example, "Geoff" and "Jeff" sound identical and thus match. Currently, this is not a true double-metaphone, as only the first metaphone is used for searching.
395
7cdbced @nertzy Convert rake tasks into generators
nertzy authored
396 Double Metaphone support is currently available as part of the {fuzzystrmatch contrib package}[http://www.postgresql.org/docs/current/static/fuzzystrmatch.html] that must be installed before this feature can be used. In addition to the contrib package, you must install a utility function into your database. To generate and run a migration for this, run:
1e15f96 Documentation for :dmetaphone
Grant Hutchins & Rachel Heaton authored
397
7cdbced @nertzy Convert rake tasks into generators
nertzy authored
398 $ rails g pg_search:migration:dmetaphone
399 $ rake db:migrate
1e15f96 Documentation for :dmetaphone
Grant Hutchins & Rachel Heaton authored
400
401 The following example shows how to use :dmetaphone.
402
403 class Word < ActiveRecord::Base
404 include PgSearch
405 pg_search_scope :that_sounds_like,
406 :against => :spelling,
407 :using => :dmetaphone
408 end
409
410 four = Word.create! :spelling => 'four'
411 far = Word.create! :spelling => 'far'
412 fur = Word.create! :spelling => 'fur'
413 five = Word.create! :spelling => 'five'
414
415 Word.that_sounds_like("fir") # => [four, far, fur]
416
dd87a9e Documentation for :trigram
Grant Hutchins & Rachel Heaton authored
417 ==== :trigram (Trigram search)
418
419 Trigram search works by counting how many three-letter substrings (or "trigrams") match between the query and the text. For example, the string "Lorem ipsum" can be split into the following trigrams:
420
421 [" Lo", "Lor", "ore", "rem", "em ", "m i", " ip", "ips", "psu", "sum", "um ", "m "]
422
423 Trigram search has some ability to work even with typos and misspellings in the query or text.
424
825788c Fix links
Grant Hutchins & Rachel Heaton authored
425 Trigram support is currently available as part of the {pg_trgm contrib package}[http://www.postgresql.org/docs/current/static/pgtrgm.html] that must be installed before this feature can be used.
dd87a9e Documentation for :trigram
Grant Hutchins & Rachel Heaton authored
426
427
428 class Website < ActiveRecord::Base
429 include PgSearch
430 pg_search_scope :kinda_spelled_like,
431 :against => :name,
432 :using => :trigram
433 end
434
435 yahooo = Website.create! :name => "Yahooo!"
436 yohoo = Website.create! :name => "Yohoo!"
437 gogle = Website.create! :name => "Gogle"
438 facebook = Website.create! :name => "Facebook"
439
440 Website.kinda_spelled_like("Yahoo!") # => [yahooo, yohoo]
441
9220f96 @nertzy Update README
nertzy authored
442 === Ignoring accent marks (PostgreSQL 9.0 and newer only)
693149d Add documentation for :ignoring => :accents
Grant Hutchins & Rachel Heaton authored
443
444 Most of the time you will want to ignore accent marks when searching. This makes it possible to find words like "piñata" when searching with the query "pinata". If you set a pg_search_scope to ignore accents, it will ignore accents in both the searchable text and the query terms.
445
446 Ignoring accents uses the {unaccent contrib package}[http://www.postgresql.org/docs/current/static/unaccent.html] that must be installed before this feature can be used.
447
448
449 class SpanishQuestion < ActiveRecord::Base
450 include PgSearch
451 pg_search_scope :gringo_search,
452 :against => :word,
453 :ignoring => :accents
454 end
455
456 what = SpanishQuestion.create(:word => "Qué")
457 how_many = SpanishQuestion.create(:word => "Cuánto")
458 how = SpanishQuestion.create(:word => "Cómo")
459
460 SpanishQuestion.gringo_search("Que") # => [what]
461 SpanishQuestion.gringo_search("Cüåñtô") # => [how_many]
462
12ceb8d @krishicks Add tsvector_column option to pg_search_scope.
krishicks authored
463 === Using tsvector columns
464
465 PostgreSQL allows you the ability to search against a column with type tsvector instead of using an expression; this speeds up searching dramatically as it offloads creation of the tsvector that the tsquery is evaluated against.
466
467 To use this functionality you'll need to do a few things:
468
469 * Create a column of type tsvector that you'd like to search against. If you want to search using multiple search methods, for example tsearch and dmetaphone, you'll need a column for each.
470 * Create a trigger function that will update the column(s) using the expression appropriate for that type of search. See: http://www.postgresql.org/docs/current/static/textsearch-features.html#TEXTSEARCH-UPDATE-TRIGGERS
471 * Should you have any pre-existing data in the table, update the newly-created tsvector columns with the expression that your trigger function uses.
472 * Add the option to pg_search_scope, e.g:
473
7e8528b @nertzy Fix formatting of README for tsvector columns
nertzy authored
474 pg_search_scope :fast_content_search,
475 :against => :content,
476 :using => {
477 dmetaphone: {
478 tsvector_column: 'tsvector_content_dmetaphone'
479 },
480 tsearch: {
481 dictionary: 'english',
482 tsvector_column: 'tsvector_content_tsearch'
483 }
484 trigram: {} # trigram does not use tsvectors
12ceb8d @krishicks Add tsvector_column option to pg_search_scope.
krishicks authored
485 }
486
487 Please note that the :against column is only used when the tsvector_column is not present for the search type.
488
50b955f @nertzy Add the beginnings of a README
nertzy authored
489 == REQUIREMENTS
490
294b243 @nertzy Update requirements
nertzy authored
491 * ActiveRecord 3
492 * PostgreSQL
493 * PostgreSQL contrib packages for certain features
50b955f @nertzy Add the beginnings of a README
nertzy authored
494
63569b0 @nertzy Add an attribution to Aaron Patterson's gem
nertzy authored
495 == ATTRIBUTIONS
496
497 PgSearch would not have been possible without inspiration from
498 {texticle}[https://github.com/tenderlove/texticle]. Thanks to
499 {Aaron Patterson}[http://tenderlovemaking.com/]!
500
df22a4e Reword the README for the Pivotal Tracker project
Grant Hutchins & Sean Moon authored
501 == CONTRIBUTIONS AND FEEDBACK
c6b0427 Add links to Tracker and Google Group
Grant Hutchins & Sean Moon authored
502
df22a4e Reword the README for the Pivotal Tracker project
Grant Hutchins & Sean Moon authored
503 Welcomed! Feel free to join and contribute to our {public Pivotal Tracker project}[https://www.pivotaltracker.com/projects/228645] where we manage new feature ideas and bugs.
c6b0427 Add links to Tracker and Google Group
Grant Hutchins & Sean Moon authored
504
505 We also have a {Google Group}[http://groups.google.com/group/casecommons-dev] for discussing pg_search and other Case Commons open source projects.
506
30daa11 Remove extra colons from README
Grant Hutchins & Rachel Heaton authored
507 == LICENSE
50b955f @nertzy Add the beginnings of a README
nertzy authored
508
0511156 Adding more documentation
Grant Hutchins & Rachel Heaton authored
509 MIT
Something went wrong with that request. Please try again.