Skip to content
Newer
Older
100644 240 lines (157 sloc) 6.98 KB
73aa144 @floere + extracted walkthrough
authored
1 h1. Walkthrough (Draft, for friends & family)
2
3 h2. The Search Server
4
5 h3. Installation
6
7 <pre><code>gem install picky</code></pre>
8
9 Create a new project directory:
10
99967d3 @floere + adapted doc from picky-generate to picky generate
authored
11 <pre><code>picky generate unicorn_server project_name</code></pre>
73aa144 @floere + extracted walkthrough
authored
12
13 Enter the newly created project directory:
14
15 <pre><code>cd project_name</code></pre>
16
17 Edit the @Gemfile@ and
18
19 <pre><code>bundle install</code></pre>
20
21 h3. Configure away!
22
23 In @app/application.rb@ you'll find an example of an application configuration.
24
25 h4. Indexing
26
27 The first block
28
29 <pre><code>indexing do
30 ...
31 end</code></pre>
32
33 is about … indexing, doh ;) Where is the data taken from and how is it processed. @illegal_characters@, @stopwords@, @split_text_on@ are all concerned about normalizing and handling the data.
34
35 The example that is generated is extremely simple. There's lots of configuration options, and they are explained in more detail in the Wiki (TODO).
36
37 @add_index@ is all about defining an index.
38
39 <pre><code>indexes do
40 illegal_characters(/[^äöüa-zA-Z0-9\s\/\-\"\&\.]/)
41 stopwords(/\b(und|der|die|das|mit|im|ein|des|dem|the|of)\b/)
42 split_text_on(/[\s\/\-\"\&\.]/)
9244b90 @floere + new API 2.0
authored
43
73aa144 @floere + extracted walkthrough
authored
44 add_index :books,
45 Sources::DB.new('SELECT id, title, author, isbn13 as isbn FROM books', :file => 'app/db.yml'),
46 field(:title),
47 field(:author),
48 field(:isbn)
49 end</code></pre>
50
51 Let's look at it in detail. Here's the signature:
52
53 <pre><code>add_index(index_identifier, source, *fields, options = {})</code></pre>
54
55 The index identifier
56
57 <pre><code>:books</code></pre>
58
59 is used later, in querying:
60
9244b90 @floere + new API 2.0
authored
61 <pre><code>Search.new(Indexes[:books], Indexes[:dvds])</code></pre>
73aa144 @floere + extracted walkthrough
authored
62
63 Queries use such an index, or a combination thereof.
64
65 @source@ is either a DB Source, or a CSV source.
66
67 <pre><code>Sources::DB.new('SELECT id, some_field, some_other_field FROM some_table', :file => 'filename.yml')</code></pre>
68 The file contains the yml configuration. Or you can pass in a hash with the configuration: @:host => 'localhost', :adapter => :mysql, etc.@.
69
70 @Sources::CSV.new(:some_field, :unused, :some_other_field)@, then a @:file => 'filename.csv'@ with the CSV data.
71
72 The fields @title@, @author@, @isbn@ define the fields that are contained in the index.
73
74 They are pretty simple in the example:
75
76 <pre><code>field(:title, :qualifiers => [:t, :title, :titre]),
77 field(:author, :qualifiers => [:s, :author, :auteur]),
78 field(:isbn, :qualifiers => [:i, :isbn])</code></pre>
79
80 The qualifiers are used when searching, to identify the field. They are all about you already knowing what you are looking for.
81
82 As an example, if you knew you'd be searching an author, you'd query like this:
83
84 <pre><code>author:faulkner</code></pre>
85
86 But the qualifiers aren't even necessary. Per default it uses the field name.
87
88 h4. Querying
89
90 The second block
91
92 <pre><code>indexing do
93 ...
94 end</code></pre>
95
96 defines how query data (the search text you enter) is processed, and also how it is routed.
97
98 There are pretty much the same options as in indexing, like @illegal_characters@, @stopwords@, @split_text_on@.
99
100 But also
101
102 <pre><code>maximum_tokens 5</code></pre>
103
104 that defines how many tokens make it through.
105
106 If you queried for "The red fox jumps over the nice dog", only the first 5 tokens would come through.
107
108 <pre><code>queries do
109 maximum_tokens 5
110 # Note that Picky needs the following characters to
111 # pass through, as they are control characters: *"~:
112 #
113 illegal_characters(/[^a-zA-Z0-9\s\/\-\,\&äöü\"\~\*\:]/)
114 stopwords(/\b(und|der|die|das|mit|ein|des|dem|the|of)\b/)
115 split_text_on(/[\s\/\-\,\&]+/)
9244b90 @floere + new API 2.0
authored
116
117 route %r{^/books}, Search.new(Indexes[:books])
118
73aa144 @floere + extracted walkthrough
authored
119 root 200
120 end</code></pre>
121
122 Routing is quite easy. Use
123
124 <pre><code>route(regexp_or_string, query)</code></pre>
125
9244b90 @floere + new API 2.0
authored
126 to define a route and a searchs that is called.
73aa144 @floere + extracted walkthrough
authored
127
128 Indexes are identified by their index_identifier (see above). Multiple indexes can be used per query, no problem. Just pass them to a @Query@ like this:
129
9244b90 @floere + new API 2.0
authored
130 <pre><code>Search.new(Indexes[:books], Indexes[:dvds], Indexes[:music]) # a comprehensive media search</code></pre>
73aa144 @floere + extracted walkthrough
authored
131
132 h2. The Frontend (Controller etc.)
133
134 To access the search server, the @picky-client@ gem offers a few helpful methods.
135
136 <pre><code>gem install picky-client</code></pre>
137
138 In your Gemfile:
139
140 <pre><code>gem 'picky-client'</code></pre>
141
9688048 @floere ! walkthrough
authored
142 h3. Get a client instance each for a search
73aa144 @floere + extracted walkthrough
authored
143
9688048 @floere ! walkthrough
authored
144 <pre><code>Books = Picky::Client.new :host => 'localhost', :port => 8080, :path => '/books'</code></pre>
73aa144 @floere + extracted walkthrough
authored
145
146 I recommend to put this code in an environment specific file, like e.g. @development.rb@ in Rails.
147
148 h3. Use it in your controller action
149
150 The controller action must return json.
151
152 @Picky::Convenience@ offers a few methods that make handling
153
154 <pre><code># The example uses Sinatra.
155 #
156
157 # For full results, you get the ids from the picky server
158 # and then populate the result with models.
159 #
160 get '/search/full' do
9688048 @floere ! walkthrough
authored
161 results = Books.search params[:query], :ids => params[:ids] :offset => params[:offset]
73aa144 @floere + extracted walkthrough
authored
162 results.extend Picky::Convenience
163 results.populate_with Book do |book|
164 book.to_s
165 end
9244b90 @floere + new API 2.0
authored
166
73aa144 @floere + extracted walkthrough
authored
167 ActiveSupport::JSON.encode results
168 end
169
170 # For live results, can go directly to the search server.
171 #
172 # Or, as shown here, go
173 #
174 get '/search/live' do
9688048 @floere ! walkthrough
authored
175 Books.search_unparsed params[:query], :ids => 0, :offset => params[:offset]
73aa144 @floere + extracted walkthrough
authored
176 end</code></pre>
177
178 h2. In your views
179
180 h3. Haml
181
182 <pre><code>= Picky::Helper.interface(options = {})</pre></code>
183
184 <pre><code>= Picky::Helper.cached_interface(options = {})</pre></code>
185
186 The options are:
187
188 <pre><code>:button # Default: 'search'
189 :no_results # Default: 'Sorry, no results found!'
190 :more # Default: 'more'
191 </pre></code>
192
193 Generates a search interface structure (with results) with a div#picky around it all.
194
195 h3. Javascript
196
197 TODO Extract JS files, make them installable through @picky-client install javascripts@
198
199 The simplest setup we can think of:
200
201 <pre><code>new PickyClient({
202 live: '/books/live',
203 full: '/books/full'
204 });</code></pre>
205
206 But it can be customized quite a bit:
207
208 <pre><code>pickyClient = new PickyClient({
209 live: '/books/live',
210 full: '/books/full',
211 showResultsLimit: 10, // Optional. Default is 10.
9244b90 @floere + new API 2.0
authored
212
73aa144 @floere + extracted walkthrough
authored
213 before: function(params, query, offset) { }, // Optional. Before Picky sends any data. Return modified params.
214 success: function(data, query) { }, // Optional. Just after Picky receives data. (Gets a PickyData object)
215 after: function(data, query) { }, // Optional. After Picky has handled the data and updated the view.
9244b90 @floere + new API 2.0
authored
216
73aa144 @floere + extracted walkthrough
authored
217 // This is used to generate the correct query strings, localized. E.g. "subject:war".
218 // Optional. If you don't give these, the field identifier given in the Picky server is used.
219 //
220 qualifiers: {
221 en:{
222 subjects: 'subject'
223 }
224 },
225 // This is used to explain the preceding word in the suggestion text, localized. E.g. "Peter (author)".
226 // Optional. Default are the field identifiers from the Picky server.
227 //
228 explanations: {
229 en:{
230 title: 'titled',
231 author: 'written by',
232 isbn: 'ISBN-13',
233 year: 'published in',
234 publisher: 'published by',
235 subjects: 'topics'
236 }
237 }
238 });
239 pickyClient.insert('italy');
240 </code></pre>
Something went wrong with that request. Please try again.