Index: openacs-4/packages/search/search.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/search/search.info,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/search/search.info 2 Sep 2001 18:11:39 -0000 1.1 @@ -0,0 +1,36 @@ + + + + + Search + Search + t + f + + + + oracle + postgresql + + Neophytos Demetriou + + + + + + + + + + + + + + + + + + + + + Index: openacs-4/packages/search/sql/postgresql/search-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/search/sql/postgresql/search-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/search/sql/postgresql/search-create.sql 2 Sep 2001 18:11:39 -0000 1.1 @@ -0,0 +1,3 @@ +\i search-tables-create.sql +\i search-packages-create.sql +\i search-sc-create.sql Index: openacs-4/packages/search/sql/postgresql/search-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/search/sql/postgresql/search-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/search/sql/postgresql/search-drop.sql 2 Sep 2001 18:11:39 -0000 1.1 @@ -0,0 +1,3 @@ +\i search-sc-drop.sql +\i search-packages-drop.sql +\i search-tables-drop.sql \ No newline at end of file Index: openacs-4/packages/search/sql/postgresql/search-packages-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/search/sql/postgresql/search-packages-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/search/sql/postgresql/search-packages-create.sql 2 Sep 2001 18:11:39 -0000 1.1 @@ -0,0 +1,39 @@ +-- +-- Search Observer +-- + +create function search_observer__enqueue(integer,varchar) +returns integer as ' +declare + p_object_id alias for $1; + p_event alias for $2; +begin + insert into search_observer_queue ( + object_id, + event + ) values ( + p_object_id, + p_event + ); + + return 0; + +end;' language 'plpgsql'; + + +create function search_observer__dequeue(integer,timestamp,varchar) +returns integer as ' +declare + p_object_id alias for $1; + p_date alias for $2; + p_event alias for $3; +begin + + delete from search_observer_queue + where object_id = p_object_id + and date =p_date + and event = p_event; + + return 0; + +end;' language 'plpgsql'; Index: openacs-4/packages/search/sql/postgresql/search-packages-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/search/sql/postgresql/search-packages-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/search/sql/postgresql/search-packages-drop.sql 2 Sep 2001 18:11:39 -0000 1.1 @@ -0,0 +1,2 @@ +drop function search_observer__dequeue(integer,timestamp,varchar); +drop function search_observer__enqueue(integer,varchar); Index: openacs-4/packages/search/sql/postgresql/search-sc-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/search/sql/postgresql/search-sc-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/search/sql/postgresql/search-sc-create.sql 2 Sep 2001 18:11:39 -0000 1.1 @@ -0,0 +1,182 @@ +-- +-- ACS-SC Contract: FtsEngineDriver +-- + +select acs_sc_contract__new ( + 'FtsEngineDriver', -- contract_name + 'Full Text Search Engine Driver' -- contract_desc +); + + +select acs_sc_msg_type__new ( + 'FtsEngineDriver.Search.InputType', + 'query:string,offset:integer,limit:integer' +); +select acs_sc_msg_type__new ( + 'FtsEngineDriver.Search.OutputType', + 'ids:integer[],stopwords:string[]' +); +select acs_sc_operation__new ( + 'FtsEngineDriver', -- contract_name + 'search', -- operation_name + 'Search', -- operation_desc + 'f', -- operation_iscachable_p + 3, -- operation_nargs + 'FtsEngineDriver.Search.InputType', -- operation_inputtype + 'FtsEngineDriver.Search.OutputType' -- operation_outputtype +); + + + +select acs_sc_msg_type__new ( + 'FtsEngineDriver.Index.InputType', + 'object_id:integer,txt:string,title:string,keywords:string' +); +select acs_sc_msg_type__new ( + 'FtsEngineDriver.Index.OutputType', + '' +); +select acs_sc_operation__new ( + 'FtsEngineDriver', -- contract_name + 'index', -- operation_name + 'Index', -- operation_desc + 'f', -- operation_iscachable_p + 3, -- operation_nargs + 'FtsEngineDriver.Index.InputType', -- operation_inputtype + 'FtsEngineDriver.Index.OutputType' -- operation_outputtype +); + + + +select acs_sc_msg_type__new ( + 'FtsEngineDriver.Unindex.InputType', + 'object_id:integer' +); +select acs_sc_msg_type__new ( + 'FtsEngineDriver.Unindex.OutputType', + '' +); +select acs_sc_operation__new ( + 'FtsEngineDriver', -- contract_name + 'unindex', -- operation_name + 'Unindex', -- operation_desc + 'f', -- operation_iscachable_p + 1, -- operation_nargs + 'FtsEngineDriver.Unindex.InputType', -- operation_inputtype + 'FtsEngineDriver.Unindex.OutputType' -- operation_outputtype +); + + + +select acs_sc_msg_type__new ( + 'FtsEngineDriver.UpdateIndex.InputType', + 'object_id:integer,txt:string,title:string,keywords:string' +); +select acs_sc_msg_type__new ( + 'FtsEngineDriver.UpdateIndex.OutputType', + '' +); +select acs_sc_operation__new ( + 'FtsEngineDriver', -- contract_name + 'update_index', -- operation_name + 'Update Index', -- operation_desc + 'f', -- operation_iscachable_p + 3, -- operation_nargs + 'FtsEngineDriver.UpdateIndex.InputType', -- operation_inputtype + 'FtsEngineDriver.UpdateIndex.OutputType' -- operation_outputtype +); + + + +select acs_sc_msg_type__new ( + 'FtsEngineDriver.Summary.InputType', + 'query:string,txt:string' +); +select acs_sc_msg_type__new ( + 'FtsEngineDriver.Summary.OutputType', + 'summary:string' +); +select acs_sc_operation__new ( + 'FtsEngineDriver', -- contract_name + 'summary', -- operation_name + 'Summary', -- operation_desc + 'f', -- operation_iscachable_p + 2, -- operation_nargs + 'FtsEngineDriver.Summary.InputType', -- operation_inputtype + 'FtsEngineDriver.Summary.OutputType' -- operation_outputtype +); + + + +select acs_sc_msg_type__new ( + 'FtsEngineDriver.Info.InputType', + '' +); +select acs_sc_msg_type__new ( + 'FtsEngineDriver.Info.OutputType', + 'package_key:string,version:version,automatic_and_queries_p:boolean,stopwords_p:boolean' +); +select acs_sc_operation__new ( + 'FtsEngineDriver', -- contract_name + 'info', -- operation_name + 'Information about the driver', -- operation_desc + 'f', -- operation_iscachable_p + 1, -- operation_nargs + 'FtsEngineDriver.Info.InputType', -- operation_inputtype + 'FtsEngineDriver.Info.OutputType' -- operation_outputtype +); + + + + +-- +-- ACS-SC Contract: FtsContentProvider +-- + +select acs_sc_contract__new ( + 'FtsContentProvider', -- contract_name + 'Full Text Search Content Provider' -- contract_desc +); + +select acs_sc_msg_type__new ( + 'FtsContentProvider.Datasource.InputType', + 'object_id:integer' +); +select acs_sc_msg_type__new ( + 'FtsContentProvider.Datasource.OutputType', + 'object_id:integer,title:string,content:string,mime:string,storage:string' +); +select acs_sc_operation__new ( + 'FtsContentProvider', -- contract_name + 'datasource', -- operation_name + 'Data Source', -- operation_desc + 'f', -- operation_iscachable_p + 1, -- operation_nargs + 'FtsContentProvider.Datasource.InputType', -- operation_inputtype + 'FtsContentProvider.Datasource.OutputType' -- operation_outputtype +); + + + +select acs_sc_msg_type__new ( + 'FtsContentProvider.Url.InputType', + 'object_id:integer' +); +select acs_sc_msg_type__new ( + 'FtsContentProvider.Url.OutputType', + 'url:uri' +); +select acs_sc_operation__new ( + 'FtsContentProvider', -- contract_name + 'url', -- operation_name + 'URL', -- operation_desc + 'f', -- operation_iscachable_p + 1, -- operation_nargs + 'FtsContentProvider.Url.InputType', -- operation_inputtype + 'FtsContentProvider.Url.OutputType' -- operation_outputtype +); + + + + + Index: openacs-4/packages/search/sql/postgresql/search-sc-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/search/sql/postgresql/search-sc-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/search/sql/postgresql/search-sc-drop.sql 2 Sep 2001 18:11:39 -0000 1.1 @@ -0,0 +1,20 @@ +select acs_sc_contract__delete('FtsContentProvider'); +select acs_sc_msg_type__delete ('FtsContentProvider.Datasource.InputType'); +select acs_sc_msg_type__delete ('FtsContentProvider.Datasource.OutputType'); + + + +select acs_sc_contract__delete('FtsEngineDriver'); +select acs_sc_msg_type__delete ('FtsEngineDriver.Search.InputType'); +select acs_sc_msg_type__delete ('FtsEngineDriver.Search.OutputType'); +select acs_sc_msg_type__delete ('FtsEngineDriver.Index.InputType'); +select acs_sc_msg_type__delete ('FtsEngineDriver.Index.OutputType'); +select acs_sc_msg_type__delete ('FtsEngineDriver.Unindex.InputType'); +select acs_sc_msg_type__delete ('FtsEngineDriver.Unindex.OutputType'); +select acs_sc_msg_type__delete ('FtsEngineDriver.UpdateIndex.InputType'); +select acs_sc_msg_type__delete ('FtsEngineDriver.UpdateIndex.OutputType'); +select acs_sc_msg_type__delete ('FtsEngineDriver.Summary.InputType'); +select acs_sc_msg_type__delete ('FtsEngineDriver.Summary.OutputType'); +select acs_sc_msg_type__delete ('FtsEngineDriver.Info.InputType'); +select acs_sc_msg_type__delete ('FtsEngineDriver.Info.OutputType'); + Index: openacs-4/packages/search/sql/postgresql/search-tables-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/search/sql/postgresql/search-tables-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/search/sql/postgresql/search-tables-create.sql 2 Sep 2001 18:11:39 -0000 1.1 @@ -0,0 +1,10 @@ +create table search_observer_queue ( + object_id integer + constraint search_observer_queue_object_id_fk + references acs_objects(object_id), + date timestamp default now(), + event varchar(6) + constraint search_observer_queue_event_ck + check (event in ('INSERT','DELETE','UPDATE')), + constraint search_observer_queue_oid_date_un unique(object_id,date) +); Index: openacs-4/packages/search/sql/postgresql/search-tables-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/search/sql/postgresql/search-tables-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/search/sql/postgresql/search-tables-drop.sql 2 Sep 2001 18:11:39 -0000 1.1 @@ -0,0 +1 @@ +drop table search_observer_queue; Index: openacs-4/packages/search/tcl/search-init.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/search/tcl/search-init.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/search/tcl/search-init.tcl 2 Sep 2001 18:11:39 -0000 1.1 @@ -0,0 +1,2 @@ +ad_schedule_proc [ad_parameter -package_id [apm_package_id_from_key search] SearchIndexerInterval] search_indexer + Index: openacs-4/packages/search/tcl/search-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/search/tcl/search-procs.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/search/tcl/search-procs.tcl 2 Sep 2001 18:11:39 -0000 1.1 @@ -0,0 +1,126 @@ +ad_proc search_indexer {} { + @author Neophytos Demetriou +} { + + set driver [ad_parameter -package_id [apm_package_id_from_key search] FtsEngineDriver] + + db_foreach search_observer_queue_entry { + select object_id, date, event + from search_observer_queue + order by date asc + } { + + switch $event { + INSERT { + set object_type [db_exec_plsql get_object_type "select acs_object_util__get_object_type($object_id)"] + array set datasource [acs_sc_call FtsContentProvider datasource [list $object_id] $object_type] + set txt [search_content_filter $datasource(content) $datasource(mime) $datasource(storage)] + acs_sc_call FtsEngineDriver index [list $datasource(object_id) $txt $datasource(title) $datasource(keywords)] $driver + } + DELETE { + acs_sc_call FtsEngineDriver unindex [list $object_id] $driver + } + UPDATE { + set object_type [db_exec_plsql get_object_type "select acs_object_util__get_object_type($object_id)"] + array set datasource [acs_sc_call FtsContentProvider datasource [list $object_id] $object_type] + set txt [search_content_filter $datasource(content) $datasource(mime) $datasource(storage)] + if { $txt != "" } { + acs_sc_call FtsEngineDriver update_index [list $datasource(object_id) $txt $datasource(title) $datasource(keywords)] $driver + } + } + } + + db_exec_plsql search_observer_dequeue_entry { + select search_observer__dequeue( + :object_id, + :date, + :event + ); + } + } +} + + + +ad_proc search_content_filter { + content + mime + storage +} { + @author Neophytos Demetriou +} { + switch $mime { + {text/plain} { + return $content + } + {text/html} { + return $content + } + } + return +} + + +ad_proc search_content_get { + content + mime + storage +} { + @author Neophytos Demetriou + + @param content + holds the filename if storage=file + holds the text data if storage=text + holds the lob_id if storage=lob +} { + switch $storage { + text { + return $content + } + file { + if {[file exists $content]} { + set ofp [open $content r] + set txt [read $ofp] + close $ofp + } else { + error "file: $content doesn't exist" + } + return [DoubleApos $txt] + } + lob { + return $txt + } + } + return +} + + + +ad_proc search_choice_bar { items links values {default ""} } { + @author Neophytos Demetriou +} { + + set count 0 + set return_list [list] + + foreach value $values { + if { [string compare $default $value] == 0 } { + lappend return_list "[lindex $items $count]" + } else { + lappend return_list "[lindex $items $count]" + } + + incr count + } + + if { [llength $return_list] > 0 } { + return "[join $return_list " "]" + } else { + return "" + } + +} + + + + Index: openacs-4/packages/search/www/index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/search/www/index.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/search/www/index.adp 2 Sep 2001 18:11:39 -0000 1.1 @@ -0,0 +1,13 @@ + +

Search

+@context_bar@ +
+ +
+
+
+ + +
+
+
\ No newline at end of file Index: openacs-4/packages/search/www/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/search/www/Attic/index.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/search/www/index.tcl 2 Sep 2001 18:11:39 -0000 1.1 @@ -0,0 +1,2 @@ +set context_bar [ad_context_bar] +ad_return_template \ No newline at end of file Index: openacs-4/packages/search/www/search-results-bottom.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/search/www/Attic/search-results-bottom.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/search/www/search-results-bottom.adp 2 Sep 2001 18:11:39 -0000 1.1 @@ -0,0 +1,39 @@ + +
+ + Result page: + + + &offset=@offset_previous@>Previous + +  @choice_bar@  + + + Next + +
+
+ +
+ + +
+
+
+ + + + +
+
+
+
+ + +
+ Try your query on: @stw@
+ +
+
+ + \ No newline at end of file Index: openacs-4/packages/search/www/search-results-one.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/search/www/Attic/search-results-one.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/search/www/search-results-one.adp 2 Sep 2001 18:11:39 -0000 1.1 @@ -0,0 +1,12 @@ + + Untitled
+
+ + @title_summary@
+
+ + + +@txt_summary@
+
+@url@

\ No newline at end of file Index: openacs-4/packages/search/www/search-results-top.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/search/www/Attic/search-results-top.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/search/www/search-results-top.adp 2 Sep 2001 18:11:39 -0000 1.1 @@ -0,0 +1,80 @@ + + + @title@ + + +

@title@

+@context_bar@ + + + + + + + + + + + + +
+
+ + + + +
+
+ + + The "AND" operator is unnecessary -- we include all search terms by default. + [details] + + +
+ + + "@stopwords@" is a very common word and was not included in your search. + [details] + + +
+ + + The following words are very common and were not included in your search: @stopwords@. + [details] + + +
+ + +

Your search - @query@ - did not match any documents. +
No pages were found containing "@query@". +

Suggestions: + +
+ +
+ + +
+ + Searched for: @query@ + + + + Results @low@-@high@ of about @count@. + Search took @elapsed@ seconds. + +
+
+
+ + \ No newline at end of file Index: openacs-4/packages/search/www/search.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/search/www/search.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/search/www/search.tcl 2 Sep 2001 18:11:39 -0000 1.1 @@ -0,0 +1,128 @@ +ad_page_contract { + @author Neophytos Demetriou + @creation-date September 01, 2001 + @cvs-id $Id: search.tcl,v 1.1 2001/09/02 18:11:39 neophytosd Exp $ +} { + q:notnull,trim + {offset 0} +} -errors { + q:notnull {You must specify some keywords.} +} + +ns_startcontent -type "text/html" +set this_dir [file dirname [ad_conn file]] +set template_top_file "$this_dir/search-results-top" +set template_one_file "$this_dir/search-results-one" +set template_bottom_file "$this_dir/search-results-bottom" + + +set package_id [ad_conn package_id] +set driver [ad_parameter -package_id $package_id FtsEngineDriver] +array set info [acs_sc_call FtsEngineDriver info [list] $driver] +set limit [ad_parameter -package_id $package_id LimitDefault] + +set title "Search Results" +set context_bar [ad_context_bar {Search Results}] + +set q [string tolower $q] +if { $offset < 0 } { set offset 0 } +set t0 [clock clicks -milliseconds] +array set result [acs_sc_call FtsEngineDriver search [list $q $offset $limit] $driver] +set tend [clock clicks -milliseconds] +set elapsed [format "%.02f" [expr double(abs($tend - $t0)) / 1000.0]] + +if { $offset >= $result(count) } { set offset [expr ($result(count) / $limit) * $limit] } + +set low [expr $offset + 1] +set high [expr $offset + $limit] +if { $high > $result(count) } { set high $result(count) } + + +if { $info(automatic_and_queries_p) && ([lsearch -exact $q and] > 0) } { + set and_queries_notice_p 1 +} else { + set and_queries_notice_p 0 +} + +set template_top [template::adp_parse $template_top_file [list \ + title $title \ + context_bar $context_bar \ + query $q \ + nquery [llength $q] \ + and_queries_notice_p $and_queries_notice_p \ + stopwords $result(stopwords) \ + nstopwords [llength $result(stopwords)] \ + low $low \ + high $high \ + count $result(count) \ + elapsed $elapsed]] + +ns_write $template_top + + for { set __i [expr 0] } { $__i < [expr $high - $low +1] } { incr __i } { + + set object_id [lindex $result(ids) $__i] + set object_type [db_exec_plsql get_object_type "select acs_object_util__get_object_type($object_id)"] + array set datasource [acs_sc_call FtsContentProvider datasource [list $object_id] $object_type] + + set txt [search_content_filter $datasource(content) $datasource(mime) $datasource(storage)] + set title_summary [acs_sc_call FtsEngineDriver summary [list $q $datasource(title)] $driver] + set txt_summary [acs_sc_call FtsEngineDriver summary [list $q $txt] $driver] + set url [acs_sc_call FtsContentProvider url [list $object_id] $object_type] + + + set template_one [template::adp_parse $template_one_file [list \ + title_summary $title_summary \ + txt_summary $txt_summary \ + url $url]] + + ns_write $template_one + + } + + set urlencoded_query [ad_urlencode $q] + set from_result_page 1 + set current_result_page [expr ($low / $limit) + 1] + set to_result_page [expr ($result(count) / $limit) + 1] + + set items [list] + set links [list] + set values [list] + for { set __i $from_result_page } { $__i <= $to_result_page} { incr __i } { + lappend items $__i + if { $__i == 1 } { + lappend links "search?q=${urlencoded_query}" + } else { + lappend links "search?q=${urlencoded_query}&offset=[expr ($__i - 1) * $limit]" + } + lappend values $__i + } + + set search_the_web [ad_parameter -package_id $package_id SearchTheWeb] + if [llength $search_the_web] { + set stw "" + foreach {url site} $search_the_web { + append stw "$site " + } + } + +set template_bottom [template::adp_parse $template_bottom_file [list \ + query $q \ + count $result(count) \ + urlencoded_query $urlencoded_query \ + from_result_page $from_result_page \ + current_result_page $current_result_page \ + to_result_page $to_result_page \ + offset_previous [expr $offset - $limit] \ + choice_bar [search_choice_bar $items $links $values $current_result_page] \ + offset_next [expr $offset + $limit] \ + stw $stw\ + ]] + +ns_write $template_bottom + + + + + + Index: openacs-4/packages/search/www/test.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/search/www/test.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/search/www/test.adp 2 Sep 2001 18:11:39 -0000 1.1 @@ -0,0 +1 @@ + \ No newline at end of file Index: openacs-4/packages/search/www/help/basics.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/search/www/help/basics.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/search/www/help/basics.html 2 Sep 2001 18:11:39 -0000 1.1 @@ -0,0 +1,64 @@ + + + +The Basics of Our Search + + + +
+ +

The Basics of Our Search

+ + + +

Basic Search

+

To enter a query, just type in a few descriptive words +and hit the 'enter' key (or click on the Search button) for a +list of relevant pages.

+

Our search uses sophisticated text-matching techniques to find pages that +are both important and relevant to your search. For instance, when our search +analyzes a page, it assigns higher relevance to pages in which +your query terms appear near each other.

+ + +

Automatic "and" Queries

+

By default, our search only returns pages that include all of your search +terms. There is no need to include "and" between terms. +To restrict a search further, just include more terms.

+ + +

What is a stop word?

+

Our search ignores common words and characters (known as stop words) as +they tend to slow down searches without improving the quality of the +results. Terms such as "where" and "how", as well +as certain single digits and single letters, are not included in searches.

+ + +

See your search terms in context

+

Each search result contains at least one excerpt from the found +web page, which shows how your search terms are used in context on that +page. Your search terms are bolded so you can tell at a glance whether +the result is a page you want to visit.

+ +

Does our search use stemming?

+Our search allows to find same words with different +endings. For example, it will also try to find the word "test" if +"testing" or "tests" is given in search query. + +

Does capitalization matter?

+

The searches are not case sensitive. All letters, regardless +of how you type them, will be understood as lower case. For example, +searches for "george washington", "George Washington", and "gEoRgE wAsHiNgToN" + will all return the same results.

+ +
+ + +