quest_search 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README +33 -0
- data/Rakefile +1 -0
- data/lib/quest/quest_on.rb +79 -0
- data/lib/quest/version.rb +3 -0
- data/lib/quest.rb +5 -0
- data/quest.gemspec +24 -0
- metadata +56 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
= Quest
|
2
|
+
|
3
|
+
Extremely naive full text search implementation for ActiveRecord based on naive-search by Tomas Jogin (http://github.com/tjogin/naive-search). Orders results by relevance and gives you detailed info on the search results. Works like this:
|
4
|
+
|
5
|
+
* Every word in a search query is matched against each text field in your database using +like+.
|
6
|
+
* The returned results are then re-ordered based on how well they match the query and the words the query is made up of.
|
7
|
+
* As opposed to naive-search quest doesn't re-organize your fields into an index column in your database. Instead it searches after each word in each field that you specify. This may result in huge overhead when searching big databases.
|
8
|
+
|
9
|
+
== Installation
|
10
|
+
|
11
|
+
gem install quest
|
12
|
+
|
13
|
+
== Usage
|
14
|
+
|
15
|
+
class Person < ActiveRecord::Base
|
16
|
+
quest_on :name, :surname, :description
|
17
|
+
end
|
18
|
+
|
19
|
+
This makes the specified fields searchable like so:
|
20
|
+
|
21
|
+
Person.quest_for 'my query'
|
22
|
+
|
23
|
+
Optionally, you can specify the order and limit of results to return from the database:
|
24
|
+
|
25
|
+
class Person < ActiveRecord::Base
|
26
|
+
quest_on :name, :surname, :description, :order => "id desc", :limit => 20
|
27
|
+
end
|
28
|
+
|
29
|
+
Note that the search results will still be re-ordered based on fuzzy "relevance", this simply specifies how many results to retrieve from the database, and in which order. Also note that small limits combined with broad searches yields terrible results. The default limit is 1 000.
|
30
|
+
|
31
|
+
== License
|
32
|
+
|
33
|
+
This project uses MIT-LICENSE.
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Quest
|
2
|
+
module QuestOn
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
def quest_on(*fields)
|
7
|
+
if fields.size.zero?
|
8
|
+
raise "No arguments given, please specify which fields should be indexed and searched."
|
9
|
+
end
|
10
|
+
|
11
|
+
options = fields.extract_options!
|
12
|
+
|
13
|
+
@order = options[:order] || "id desc"
|
14
|
+
@limit = options[:limit] || 1000
|
15
|
+
|
16
|
+
cattr_accessor :quest_fields
|
17
|
+
|
18
|
+
self.quest_fields = fields
|
19
|
+
end
|
20
|
+
|
21
|
+
def quest_for(query, page_no = 1, page_size = nil)
|
22
|
+
words = query.to_s.split " "
|
23
|
+
conditions = words.map do |w|
|
24
|
+
self.quest_fields.map do |f|
|
25
|
+
replace_bind_variables("#{f} like ?", ["%#{w}%"])
|
26
|
+
end.join " OR "
|
27
|
+
end.join " OR "
|
28
|
+
|
29
|
+
self.where(conditions).order(@order).limit(@limit).sort do |a, b|
|
30
|
+
b.points_for(query) <=> a.points_for(query)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def points_for(query)
|
36
|
+
query = query.to_s.downcase
|
37
|
+
@quest_relevance ||= {}
|
38
|
+
return @quest_relevance[query] if @quest_relevance[query]
|
39
|
+
words = query.split " "
|
40
|
+
|
41
|
+
self.search_word_matches = []
|
42
|
+
self.search_word_matches_count = 0
|
43
|
+
self.search_word_total_matches_count = 0
|
44
|
+
|
45
|
+
points = words.map do |w|
|
46
|
+
matches = 0
|
47
|
+
|
48
|
+
points = self.quest_fields.map do |field|
|
49
|
+
content = self.send(field).to_s.downcase
|
50
|
+
|
51
|
+
matches = content.scan(w).size
|
52
|
+
|
53
|
+
# one point for partial word matches
|
54
|
+
(content.scan(w).size +
|
55
|
+
# one point for partial query matches
|
56
|
+
content.scan(query).size +
|
57
|
+
# two points for exact word match
|
58
|
+
(content == w ? 2 : 0) +
|
59
|
+
# two points for exact query match
|
60
|
+
(content == query ? 2 : 0))
|
61
|
+
end.sum
|
62
|
+
|
63
|
+
if matches != 0
|
64
|
+
self.search_word_matches.push [ 'word' => w, 'count' => matches ]
|
65
|
+
self.search_word_matches_count += 1
|
66
|
+
self.search_word_total_matches_count += matches
|
67
|
+
end
|
68
|
+
|
69
|
+
points
|
70
|
+
end.sum
|
71
|
+
|
72
|
+
self.relevance = points
|
73
|
+
|
74
|
+
@quest_relevance[query] = points
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
ActiveRecord::Base.send :include, Quest::QuestOn
|
data/lib/quest.rb
ADDED
data/quest.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "quest/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "quest_search"
|
7
|
+
s.version = Quest::VERSION
|
8
|
+
s.authors = ["Fredrik Sundström"]
|
9
|
+
s.email = ["fredrik.sundstrom@gmail.com"]
|
10
|
+
s.homepage = "http://github.com/fredriksundstrom/quest"
|
11
|
+
s.summary = "Extremely naive full text search implementation for ActiveRecord based on naive-search by Tomas Jogin (http://github.com/tjogin/naive-search). Orders results by relevance and gives you detailed info on the search results."
|
12
|
+
s.description = "Quest is a gem that lets you search your model in a simple and intuitive way."
|
13
|
+
|
14
|
+
s.rubyforge_project = "quest"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
# s.add_development_dependency "rspec"
|
23
|
+
# s.add_runtime_dependency "rest-client"
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: quest_search
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Fredrik Sundström
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-11-22 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Quest is a gem that lets you search your model in a simple and intuitive
|
15
|
+
way.
|
16
|
+
email:
|
17
|
+
- fredrik.sundstrom@gmail.com
|
18
|
+
executables: []
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- .gitignore
|
23
|
+
- Gemfile
|
24
|
+
- README
|
25
|
+
- Rakefile
|
26
|
+
- lib/quest.rb
|
27
|
+
- lib/quest/quest_on.rb
|
28
|
+
- lib/quest/version.rb
|
29
|
+
- quest.gemspec
|
30
|
+
homepage: http://github.com/fredriksundstrom/quest
|
31
|
+
licenses: []
|
32
|
+
post_install_message:
|
33
|
+
rdoc_options: []
|
34
|
+
require_paths:
|
35
|
+
- lib
|
36
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ! '>='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
requirements: []
|
49
|
+
rubyforge_project: quest
|
50
|
+
rubygems_version: 1.8.11
|
51
|
+
signing_key:
|
52
|
+
specification_version: 3
|
53
|
+
summary: Extremely naive full text search implementation for ActiveRecord based on
|
54
|
+
naive-search by Tomas Jogin (http://github.com/tjogin/naive-search). Orders results
|
55
|
+
by relevance and gives you detailed info on the search results.
|
56
|
+
test_files: []
|