SWISH-CONFIG(1)

๐Ÿ“ฆ
version 2.4.7 ยท 2 versions
, in debian bookworm, debian trixie, ubuntu jammy, ubuntu noble, ubuntu questing, ubuntu resolute, ubuntu stonking

๐ŸŽ€ NAME ๐ŸŽ€

Okay bestie, welcome to SWISH-CONFIG(1) ๐Ÿ’–, the Swish-E Documentation page that spills all the tea on configuration file directives โœจ

SWISH-CONFIG โ€” Configuration File Directives ๐Ÿ’…

๐ŸŒธ OVERVIEW ๐ŸŒธ

This doc is the full menu of every configuration directive you can use in Swish-e. Literally everything, no cap ๐Ÿซถ

๐Ÿฆ‹ CONFIGURATION FILE ๐Ÿฆ‹

So the config file is where you get main character control ๐Ÿ‘‘ It decides what files Swish-e indexes, how they get indexed, and where the index gets written ๐Ÿ“

The config file is a plain text file made of comments, blank lines, and config directives. The order of the directives doesn't matter, so the vibes can be all over the place ๐ŸŒˆ Some directives can be used more than once. Others are one-and-done, and if you add another one, it just overwrites the one before it, so be careful ๐Ÿ’€ Directive case doesn't matter either, so upper, lower, or mixed case are all giving โœจ

Comments are any line that starts with a "#":

# This is a comment

As of 2.4.3 you can continue a line by putting a backslash as the very last character on the line ๐Ÿ”—:

IgnoreWords \
    am \
    the \
    foo

Directives can take more than one parameter. If a single parameter has whitespace in it, wrap it in quotes (single or double) ๐Ÿ’– Inside quotes, a backslash escapes the next character:

ReplaceRules append "foo bar"   <- define "foo bar" as a single parameter

If you need a quote character inside the value, either backslash-escape it or wrap the whole thing in quotes of the other type ๐Ÿ™ˆ

Backslashes also have a special job in regular expressions ๐Ÿฅน:

FileFilterMatch pdftotext "'%p' -" /\.pdf$/

That makes the dot a real dot instead of "match any character" ๐Ÿฆ– If you put the regex in quotes, you have to use double-backslashes:

FileFilterMatch pdftotext "'%p' -" "/\\.pdf$/"

Swish-e turns the double backslash into a single backslash before passing the parameter to the regular expression compiler ๐Ÿงš

Commented example config files live in the conf directory of the Swish-e distribution ๐Ÿ“‚

Some command line arguments can override directives in the config file. For how to run Swish-e, check out SWISH-RUN ๐Ÿƒโ€โ™€๏ธ, and for how to search your index (with examples!), check the SWISH-SEARCH page ๐Ÿ”

You hand the config file to Swish-e with the "-c" switch, like so:

swish-e -c myconfig.conf

You can also split your directives across different config files ๐Ÿฐ That way you can have one master config for lots of indexes and smaller configs for each separate index. Specify the different config files on the command line with "-c" (see SWISH-RUN), or pull in another config file with the IncludeConfigFile directive below ๐Ÿ’…

Usually the directives are grouped in some logical order. Directives that control the source of the documents go first, then the directives that control how each document is filtered or how its words get indexed. (The directives below are grouped in this order ๐Ÿ“‹)

  • "Administrative Headers Directives" โ€” add administrative info to the header of the index file ๐Ÿ“
  • "Document Source Directives" โ€” pick the source documents and the location of the index file ๐Ÿ“‚
  • "Document Contents Directives" โ€” control how a document's content gets indexed ๐Ÿงพ
  • "Directives for the File Access method only" โ€” only applicable to the File Access indexing method ๐Ÿ“
  • "Directives for the HTTP Access Method Only" โ€” likewise, these only apply to the HTTP Access method ๐ŸŒ
  • "Directives for the prog Access Method Only" โ€” these only apply to the prog Access method โš™๏ธ
  • "Document Filter Directives" โ€” a special section about using document filters with Swish-e ๐Ÿงน

๐Ÿ’– Alphabetical Listing of Directives ๐Ÿ’–

Here's the full alphabetical lineup. Every single one, no skipping ๐Ÿ’…

  • AbsoluteLinks [yesโŽชNO]
  • BeginCharacters *string of characters*
  • BumpPositionCounterCharacters *string*
  • Buzzwords [*list of buzzwords*โŽชFile: path]
  • CompressPositions [yesโŽชNO]
  • ConvertHTMLEntities [YESโŽชno]
  • DefaultContents [TXTโŽชHTMLโŽชXMLโŽชTXT2โŽชHTML2โŽชXML2โŽชTXT*โŽชHTML*โŽชXML*]
  • Delay *seconds*
  • DontBumpPositionOnEndTags *list of names*
  • DontBumpPositionOnStartTags *list of names*
  • EnableAltSearchSyntax [yesโŽชNO]
  • EndCharacters *string of characters*
  • EquivalentServer *server alias*
  • ExtractPath *metaname* [replaceโŽชremoveโŽชprependโŽชappendโŽชregex]
  • FileFilter *suffix* *program* [options]
  • FileFilterMatch *program* *options* *regex* [*regex* ...]
  • FileInfoCompression [yesโŽชNO]
  • FileMatch [containsโŽชisโŽชregex] *regular expression*
  • FileRules [containsโŽชisโŽชregex] *regular expression*
  • FuzzyIndexingMode [NONEโŽชStemmingโŽชSoundexโŽชMetaphoneโŽชDoubleMetaphone]
  • FollowSymLinks [yesโŽชNO]
  • HTMLLinksMetaName *metaname*
  • IgnoreFirstChar *string of characters*
  • IgnoreLastChar *string of characters*
  • IgnoreLimit *integer integer*
  • IgnoreMetaTags *list of names*
  • IgnoreNumberChars *list of characters*
  • IgnoreTotalWordCountWhenRanking [YESโŽชno]
  • IgnoreWords [*list of stop words*โŽชFile: path]
  • ImageLinksMetaName *metaname*
  • IncludeConfigFile
  • IndexAdmin *text*
  • IndexAltTagMetaName *tagname*โŽชas-text
  • IndexComments [yesโŽชNO]
  • IndexContents [TXTโŽชHTMLโŽชXMLโŽชTXT2โŽชHTML2โŽชXML2โŽชTXT*โŽชHTML*โŽชXML*] *file extensions*
  • IndexDescription *text*
  • IndexDir [URLโŽชdirectories or files]
  • IndexFile *path*
  • IndexName *text*
  • IndexOnly *list of file suffixes*
  • IndexPointer *text*
  • IndexReport [0โŽช1โŽช2โŽช3]
  • MaxDepth *integer*
  • MaxWordLimit *integer*
  • MetaNameAlias *meta name* *list of aliases*
  • MetaNames *list of names*
  • MinWordLimit *integer*
  • NoContents *list of file suffixes*
  • obeyRobotsNoIndex [yesโŽชNO]
  • ParserWarnLevel [0โŽช1โŽช2โŽช3]
  • PreSortedIndex *list of property names*
  • PropCompressionLevel [0-9]
  • PropertyNameAlias *property name* *list of aliases*
  • PropertyNames *list of meta names*
  • PropertyNamesCompareCase *list of meta names*
  • PropertyNamesIgnoreCase *list of meta names*
  • PropertyNamesNoStripChars *list of meta names*
  • PropertyNamesDate *list of meta names*
  • PropertyNamesNumeric *list of meta names*
  • PropertyNamesMaxLength integer *list of meta names*
  • PropertyNamesSortKeyLength integer *list of meta names*
  • ReplaceRules [replaceโŽชremoveโŽชprependโŽชappendโŽชregex]
  • ResultExtFormatName name -x format string
  • SpiderDirectory *path*
  • StoreDescription [XML <tag>โŽชHTML <meta>โŽชTXT size]
  • SwishProgParameters *list of parameters*
  • SwishSearchDefaultRule [<AND-WORD>โŽช<or-word>]
  • TmpDir *path*
  • TranslateCharacters [*string1 string2*โŽช:ascii7:]
  • TruncateDocSize *number of characters*
  • UndefinedMetaTags [errorโŽชignoreโŽชINDEXโŽชauto]
  • UndefinedXMLAttributes [DISABLEโŽชerrorโŽชignoreโŽชindexโŽชauto]
  • UseStemming [yesโŽชNO]
  • UseSoundex [yesโŽชNO]
  • UseWords [*list of words*โŽชFile: path]
  • WordCharacters *string of characters*
  • XMLClassAttributes *list of XML attribute names*

โœจ Directives that Control Swish โœจ

These config directives control the general behavior of Swish-e ๐ŸŽ›๏ธ

๐Ÿฆ‹ IncludeConfigFile *path to config file*

This directive lets you pull in config directives that live in another file ๐Ÿซถ

IncludeConfigFile /usr/local/swish/conf/site_config.config

๐ŸŒˆ IndexReport [0โŽช1โŽช2โŽช3]

This is how chatty you want reporting to be while indexing ๐Ÿ“ข You can pick any number from 0 to 3. 0 is totally silent and 3 is the most verbose ๐Ÿ—ฃ๏ธ The default is 1.

The "-v" switch on the command line can override this (see SWISH-RUN) ๐Ÿ’…

๐Ÿงš ParserWarnLevel [0โŽช1โŽช2โŽช3]

This sets the error level when you're using the libxml2 parser for XML and HTML. libxml2 will point out structural errors in your documents ๐Ÿ” The levels are:

0 = no report
1 = fatal errors
2 = errors
3 = warnings

Currently (as of 2.4.4 - early 2005) libxml2 only reports errors at level 2. The default as of 2.4.4 is "2", which should report any errors that might mean a document had trouble parsing ๐Ÿšจ

The exception is UTF-8 to Latin-1 conversion errors, which are reported at level 3 (changed from 1 in 2.4.4). Even though these can mean there's a problem indexing text, they only show up at level 3 because they can be super common ๐Ÿ™„

It's recommended that you index at ParserWarnLevel 3 when you're first starting out, so you can see what errors and warnings get reported ๐Ÿ‘€ Then lower the level once you understand which documents are causing parsing problems and why ๐Ÿ’–

๐ŸŒธ IndexFile *path*

IndexFile specifies where the generated index file lives ๐Ÿ“ If you don't set it, Swish-e will create a file called index.swish-e in the current directory.

IndexFile /usr/local/swish/site.index

๐Ÿ“ obeyRobotsNoIndex [yesโŽชNO]

When this is enabled, Swish-e will skip indexing any HTML file that contains:

<meta name="robots" content="noindex">

The default is to ignore these meta tags and index the document anyway. This tag is described at http://www.robotstxt.org/wc/exclusion.html ๐Ÿค“

Note: This feature is only available with the libxml2 HTML parser ๐Ÿšซ

If you're using the libxml2 parser (HTML2 and XML2), you can also use these comments in your documents to prevent indexing:

<!-- SwishCommand noindex -->
<!-- SwishCommand index -->

and/or these may be used too:

<!-- noindex -->
<!-- index -->

These are super helpful for keeping common headers, footers, and menus out of the index ๐Ÿ™Œ

NOTE: The following items are currently not available. They require Swish-e to parse the configuration file while searching.

๐Ÿšง EnableAltSearchSyntax [yesโŽชNO]

NOTE: This item is currently not available.

This enables alternate search syntax, which allows a basic "Altavista(c)", "Lycos(c)", etc.-style search. That means a search query can use "+" and "-" as syntax parameters โœจ

Okay, so here's how the search operators look in action ๐Ÿ’…:

swish-e -w "+word1 +word2 -word3  word4 word5"
  • "+" โ€” the word right after it has to show up in every single doc that comes back ๐Ÿ‘‘
  • "-" โ€” the word right after it can't be in ANY of the found docs ๐Ÿ™…
  • " " โ€” the word right after it just gets searched for, no strings attached ๐Ÿฆ‹

SwishSearhOperators <and-word> <or-word> <not-word>

๐Ÿ’€ Heads up, bestie: this one is currently not available.

This config directive lets you swap out Swish-e's boolean search operators, which is so useful if you want them in your own language ๐ŸŒ. The default is AND OR NOT.

Example (german) ๐Ÿ‡ฉ๐Ÿ‡ช:

SwishSearchOperators   UND  ODER  NICHT

SwishSearchDefaultRule [<AND-WORD>โŽช<or-word>]

๐Ÿ’€ Heads up, bestie: this one is currently not available.

SwishSearchDefaultRule picks the default Boolean operator to use when you don't specify one between words or phrases. The default is "AND" โœจ.

The word you pick has to match one of the available SwishSearchOperators.

Example:

SwishSearchOperators   UND  ODER  NICHT
# Make it act like a web search engine
SwishSearchDefaultRule ODER

ResultExtFormatName name -x format string

๐Ÿ’€ Heads up, bestie: this one is currently not available.

Swish-e's output can be shaped with a format string, passed in using the -x command line argument. With ResultExtFormatName you can give a predefined format string a name ๐Ÿท๏ธ.

Examples:

ResultExtFormatName  moreinfo   "%cโŽช%rโŽช%tโŽช%pโŽช<author>โŽช<publishyear>\n"

Then when you're searching, you can call that format string by its name:

swish-e   ...  -x moreinfo  ...

See the -x switch in SWISH-RUN for more info about output formats ๐ŸŒธ.


๐ŸŽ€ Administrative Headers Directives

Swish-e stores config info in the header of the index file ๐Ÿ“‡. You can grab it back while searching, or with the functions in the Swish-e C library. There are a bunch of fields free for your own use. None of these fields are required, so no pressure ๐Ÿ’–:

  • IndexName text
  • IndexDescription text
  • IndexPointer text
  • IndexAdmin text

These are the vibes-and-info fields that help users and admins out ๐Ÿซถ. IndexName should be the name of your index, like a book title. IndexDescription is a short description of the index, or a URL pointing to a fuller one. IndexPointer should point to the original information, most likely a URL. IndexAdmin should be the name of the index maintainer and can include name and email info. Keep these values to about 70 characters or so, and wrap them in quotes โœจ.

Also, FYI, the automatically generated date in index files is in D/M/Y and 24-hour format ๐Ÿ•ฐ๏ธ.

Examples:

IndexName "Linux Documentation"
IndexDescription "This is an index of /usr/doc on our Linux machine."
IndexPointer http://localhost/swish/linux/index.html
IndexAdmin webmaster

๐ŸŽ€ Document Source Directives

These directives control what documents get indexed and how they're accessed ๐Ÿ“‚. See also Directives for the File Access method only and Directives for the HTTP Access Method Only for the ones specific to those access methods ๐Ÿฆ‹.

IndexDir [directories or filesโŽชURLโŽชexternal program]

IndexDir defines where Swish-e gets its documents from. Swish-e currently supports three file access methods: File system, HTTP (also called spidering), and prog, for reading files from an external program ๐Ÿงš.

The -S command line argument selects the file access method:

swish-e -c swish.config -S fs    - file system
swish-e -c swish.config -S http  - internal http spider
swish-e -c swish.config -S prog  - external program of any type

For the fs method, IndexDir is a space-separated list of files and directories to index. On MS Windows, use a forward slash as the path separator ๐ŸชŸ.

For the http method, IndexDir is a list of space-separated URLs.

For the prog method, IndexDir is a list of space-separated programs to run (which generate documents for swish to index).

You can have more than one IndexDir directive ๐Ÿ™Œ.

Any sub-directories of any listed directory get indexed too ๐Ÿ“.

๐Ÿ™ˆ Note: While processing directories, Swish-e ignores any files or directories that begin with a dot ("."). If you want to index those, specify their name with IndexDir or -i.

Examples:

# Index this directory an any subdirectories
IndexDir /usr/local/home/http

# Index the docs directory in current directory
IndexDir ./docs

# Index these files in the current directory
IndexDir ./index.html ./page1.html ./page2.html
# and index this directory, too
IndexDir ../public_html

For the HTTP method of access, specify the URLs where you want the spidering to begin ๐Ÿ•ธ๏ธ.

Example:

IndexDir http://www.my-site.com/index.html
IndexDir http://localhost/index.html

Obviously, using the HTTP method to index is way slower than indexing local files ๐Ÿข. Be well aware that some sites don't appreciate spidering and may block your IP address ๐Ÿ’€. You might want to contact the remote site before spidering their web site. More info on spidering is in Directives for the HTTP Access Method Only below.

For the prog method of access, IndexDir specifies the path to the program(s) to execute. The external program has to correctly format the documents it passes back to Swish-e. Examples of external programs are provided in the prog-bin directory ๐Ÿ—‚๏ธ.

IndexDir ./myprogram.pl

See prog for details.

โš ๏ธ Note: Not all directives work with all methods.

NoContents *list of file suffixes*

Files with these suffixes won't have their contents indexed, but their path name (file name) will be indexed instead ๐Ÿ™…โ€โ™€๏ธ๐Ÿ“„.

If the file's type is HTML or HTML2 (as set by "IndexContents" or "DefaultContents"), then the file gets parsed for an HTML title, and that title is indexed. Note that you must set the file's type with "IndexContents" or "DefaultContents": ".html" and ".htm" are NOT type HTML by default ๐Ÿšจ. For example:

IndexContents HTML* .htm .html

If a title is found, it still gets checked for "FileRules title", and the file gets skipped if a match is found. See "FileRules".

If the file's type is not HTML, or it is HTML and no title is found, then the file's path gets indexed.

For example, this will let you search by image file name ๐Ÿ–ผ๏ธ:

NoContents .gif .xbm .au .mov .mpg .pdf .ps
๐Ÿšจ Note: Using this directive will NOT cause files with those suffixes to be indexed. So if you use "IndexOnly" to limit the types of files that get indexed, you must specify the same suffixes in "IndexOnly" that are listed in "NoContents".

This does not work:

# Wrong!
IndexOnly .htm .html
NoContents .gif .xbm .au .mov .mpg .pdf .ps

A "-S prog" program can set the "No-Contents:" header to turn this feature on for a specific document (although it would be smarter for the "-S prog" program to simply only send the pathname or title to be indexed ๐Ÿง .

ReplaceRules [replaceโŽชremoveโŽชprependโŽชappendโŽชregex]

ReplaceRules lets you make changes to file pathnames before they're indexed ๐Ÿ”. Those changed file names or URLs are what show up in search results.

For example, you might index your files locally (with the File system indexing method) but still return a URL in search results. This directive can be used to map the file names to their respective URLs on your web server ๐ŸŒ.

There are five operations you can specify: replace, append, remove, prepend, and regex. They parse the pathname in the order you've typed them ๐Ÿ”ข.

This directive uses C library regex.h regular expressions ๐Ÿค“.

replace "the string you want replaced" "what to change it to"
remove "a string to remove"
prepend "a string to add before the result"
append "a string to add after the result"
regex  "/search string/replace string/options"

Remember, quotes are needed if an expression contains white space, and backslashes have special meaning ๐Ÿฅน.

Regex is an Extended Regular Expression. The first character found is the delimiter (but it's not smart enough to use matched chars such as [], (), and {}) ๐Ÿ™ƒ.

The replace string may use substitution variables:

$0      the entire matched (sub)string
$1-$9   returns patterns captured in "(" ")" pairs
$`      the string before the matched pattern
$'      the string after the matched pattern

The options change the behavior of the expression:

  • i โ€” ignore the case when matching ๐Ÿ”ค
  • g โ€” repeat the substitution for the entire pattern ๐Ÿ”

Examples:

ReplaceRules replace testdir/ anotherdir/
ReplaceRules replace [a-z_0-9]*_m.*\.html index.html

ReplaceRules remove testdir/

ReplaceRules prepend http://localhost/
ReplaceRules append .html

ReplaceRules regex  !^/web/(.+)/!http://$1.domain.com/!
replaces a file path:
    /web/search/foo/index.html
with
    http://search.domain.com/foo/index.html

ReplaceRules regex  #^#http://localhost/www#
ReplaceRules prepend http://localhost/www  (same thing)

# Remove all extensions from C source files
ReplaceRules remove .c     # ERROR! That "." is *any char*
ReplaceRules remove \.c    # much better...

ReplaceRules remove "\\.c" # if in quotes you need double-backslash!
ReplaceRules remove "\.c"  # ERROR! "\." -> "." and is *any char*

IndexContents [TXTโŽชHTMLโŽชXMLโŽชTXT2โŽชHTML2โŽชXML2โŽชTXT*โŽชHTML*โŽชXML*] file extensions

The IndexContents directive assigns one of Swish-e's document parsers to a document, based on its extension ๐Ÿงฉ. Swish-e currently knows how to parse TXT, HTML, and XML documents.

The XML2, HTML2, and TXT2 parsers are currently only available when Swish-e is configured to use libxml2 ๐Ÿ’œ.

You can use XML*, HTML*, and TXT* to select the parser automatically. If libxml2 is installed, then it gets used to parse the content. Otherwise, Swish-e's internal parsers get used ๐ŸŒˆ.

If a document doesn't get a parser from IndexContents, bestie, it's using the HTML2 parser by default ๐Ÿ’… as long as libxml2 is installed. Otherwise it falls back to Swish-e's internal HTML parser ๐ŸŒธ. The DefaultContents directive lets you pick a parser for docs that don't match any extension you set with IndexContents โœจ.

IndexContents HTML* .htm .html .shtml
IndexContents TXT*  .txt .log .text
IndexContents XML*  .xml

HTML* is the default type for every file unless you say otherwise (and DefaultContents can change that default) ๐ŸŽ€. Swish-e pulls titles out of HTML files when they're available ๐Ÿ“ and tracks where text sits in the document so context searching works ๐Ÿฆ‹. Check out -t in SWISH-RUN for that part.

If you use filters (through the FileFilter directive) to convert documents, you also need to add those extensions, bestie ๐Ÿ’–. Say you're converting .pdf to .html. You have to tell Swish-e that .pdf should go through the internal HTML parser:

FileFilter  .pdf   pdf2html
IndexContent  HTML  .pdf

See also Document Filter Directives ๐ŸŒˆ.

Note: some of this might switch to content-types instead of file extensions in the future ๐Ÿ‘€. Look at SWISH-3.0 for that.

DefaultContents [TXTโŽชHTMLโŽชXMLโŽชTXT2โŽชHTML2โŽชXML2โŽชTXT*โŽชHTML*โŽชXML*]

This sets the default parser for any document not listed in IndexContents ๐Ÿ“. If you don't set it, the default is HTML.

The XML2, HTML2, and TXT2 parsers are only around when Swish-e is built to use libxml2 ๐Ÿงš.

You can use XML*, HTML*, and TXT* to let the parser get picked automatically ๐Ÿค–. If libxml2 is installed, that one parses the content. If not, Swish-e's internal parsers take over.

Example:

DefaultContents HTML

Use DefaultContents when you're spidering, okay? HTML files can come back with no file extension at all, like when you request a directory and get the default index.html back ๐Ÿ .

FileInfoCompression [yesโŽชNO]

๐Ÿ’€ This directive is currently not supported. ๐Ÿ’€

Setting FileInfoCompression to "yes" squishes the index file to save disk space ๐Ÿ—œ๏ธ. That might make indexing take longer. The default is "no".

Also check out the -e switch in SWISH-RUN if you want to save RAM during indexing ๐Ÿง .


โœจ Document Contents Directives โœจ

These directives decide what info gets pulled out of your source documents, and how that info shows up when you search ๐Ÿ‘‘.

ConvertHTMLEntities [YESโŽชno]

Swish-e can automatically convert ASCII entities while indexing HTML documents (this doesn't apply to HTML2) ๐Ÿ’…. For speed, you can set this to "no" if your docs don't have any HTML entities. The default is "yes".

If ConvertHTMLEntities is "no", the entities get indexed exactly as they are, no conversion ๐Ÿ™ˆ.

NOTE: Entities inside XML files and files parsed with libxml2 (HTML2) get converted no matter what this setting says ๐Ÿ’….

MetaNames *list of names*

META names let you define "fields" in your XML and HTML documents ๐ŸŽ€. Then you can use them in queries to only search the words inside that META name. Like, say you've got a META tagged field called "subjects" ๐Ÿฆ‹. You can search for "foo" and only get back docs where "foo" shows up in the "subjects" META tag:

swish-e -w subjects=foo

(Also check out the -t switch in SWISH-RUN for context searching in HTML documents ๐ŸŒธ.)

The MetaNames directive takes a space separated list ๐Ÿ“. For example:

MetaNames meta1 meta2 keywords subjects

You can also use UndefinedMetaTags to automatically pull meta names out of your HTML and XML documents, and to skip indexing the content of meta tags ๐Ÿ™…โ€โ™€๏ธ.

META tags can look two ways in your HTML source docs ๐Ÿ‘€:

<META NAME="meta1" CONTENT="some content">

and (if you're using the HTML2/libxml2 parser):

<meta1>
    some content
</meta1>

But that second version is invalid HTML ๐Ÿ˜ญ, so you'll get a warning if ParserWarningLevel is set (libxml2 only).

In XML documents, use this format:

<meta1>
    Some Content
</meta1>

Then you can limit your search to just META meta1 like this ๐Ÿ”ฅ:

swish-e -w 'meta1=(apples or oranges)'

You can nest the XML and the start/end tag versions, too ๐Ÿงš:

<keywords>
    <tag1>
        some content
    </tag1>
    <tag2>
        some other content
    </tag2>
<keywords>

Then you can search in both tag2 and tag2 with:

swish-e -w 'keywords=(query words)'

Swish-e indexes all text as some metaname ๐Ÿ’œ. The default is "swishdefault", so these two queries are the same:

swish-e -w foo
swish-e -w swishdefault=foo

When it indexes HTML, Swish-e indexes the HTML title as default text โœจ. So when you search, you'll find matches in both the HTML body and the HTML title. Swish also indexes the content of meta tags by default ๐ŸŒˆ. So:

swish-e -w foo

will find "foo" in the body, the title, or any meta tags ๐Ÿซถ.

Right now there's no way to stop Swish-e from indexing the title contents along with the body contents ๐Ÿ™ƒ. But check out "UndefinedMetaTags" if you want to control how meta tags get indexed.

If you only want to search the title text, use this ๐Ÿ‘‘:

MetaNames swishtitle

This indexes the title text separately under the built-in swish internal meta name "swishtitle" ๐ŸŽ€. Then you can search like this:

swish-e -w foo  -- search for "foo" in title, body (and undefined meta tags)
swish-e -w swishtitle=foo -- search for "foo" in title only

On top of swishtitle, you can limit searches to a document's path ๐Ÿ›ค๏ธ:

MetaNames swishdocpath

Then to search for "foo" and also limit results to documents that have "manual" or "tutorial" in their path ๐Ÿฆ‹:

swish-e -w foo swishdocpath=(manual or tutorial)

See also "ExtractPath" ๐ŸŒธ.

MetaNameAlias *meta name* *list of aliases*

MetaNameAlias gives a meta name some aliases ๐Ÿ’…. Say your docs have meta tags "description", "summary", and "overview" that all summarize the doc. You could do this:

MetaNames summary
MetaNameAlias summary description overview

Then all three tags get indexed as the meta tag "summary" ๐Ÿ“. You can search all of those fields like this:

-w summary=foo

Aliases work at search time too, so these also limit the search to the "summary" meta name ๐Ÿ”ฅ:

-w description=foo
-w overview=foo

MetaNamesRank integer *list of meta names*

You can give meta names a bias that changes how ranking gets calculated ๐Ÿ“ˆ. The range is -10 to +10, and zero means no bias โญ.

MetaNamesRank 4 subject
MetaNamesRank 3 swishdefault
MetaNamesRank 2 author publisher
MetaNamesRank -5 wrongwords
๐Ÿงช This feature is still considered experimental. If you use it, please send feedback to the discussion list ๐Ÿ’œ.

HTMLLinksMetaName *metaname*

This lets you index HTML links ๐Ÿ”—. By default, HTML links (href tags) are not indexed by Swish-e ๐Ÿ™…โ€โ™€๏ธ. This directive defines a metaname, and links get indexed under that meta name.

Example:

HTMLLinksMetaName links

Now, if you want to limit searches to files that link to "home.html", do this ๐Ÿก:

-w links='"home.html"'

The double quotes force a phrase search ๐Ÿ’….

If you want Swish-e to index links as normal text, use:

HTMLLinksMetaName swishdefault

This feature is only available with the libxml2 HTML parser ๐Ÿงš.

ImageLinksMetaName *metaname*

This lets you index image links under a metaname ๐Ÿ–ผ๏ธ. By default, image URLs are not indexed.

Example:

ImagesLinksMetaName images

Now, if you want to find pages with a nice image of a beach ๐Ÿ–๏ธ:

-w images='beach'

If you want Swish-e to index links as normal text, use:

ImageLinksMetaName swishdefault

This feature is only available with the libxml2 HTML parser ๐ŸŒŠ.

IndexAltTagMetaName *tagname*โŽชas-text

This lets you index the ALT text of <IMG> tags ๐Ÿ–ผ๏ธ. You can give it a tag name, which gets used as a metaname, or use the special text "as-text" to index the ALT text as if it were plain text at the current location ๐Ÿ’–.

For example, with a tag name:

IndexAltTagMetaName bar

makes this markup:

<foo>
    <img src="/someimage.png" alt="Alt text here">
</foo>

look like this:

<foo>
    <bar>Alt text here</bar>
</foo>

Then the normal rules ("MetaNames" and "PropertyNames") apply to how that text gets indexed โœจ.

If you use the special tag "as-text", then this:

<foo>
    <img src="/someimage.png" alt="Alt text here">
</foo>

simply becomes this:

<foo>
    Alt text here
</foo>

This feature is only available with the libxml2 parser (HTML2 and XML2) ๐Ÿงš.

If this is set to yes, Swish-e will try to turn relative URIs pulled from HTML documents into absolute URIs ๐ŸŒ. That's for use with "HTMLLinksMetaName" and "ImageLinksMetaName". Swish-e uses any <BASE> tag it finds in the document. If there isn't one, it uses the file's pathname. The pathname used is the one after "ReplaceRules" has been applied to the document's pathname ๐Ÿ—บ๏ธ.

Say you want to index image links under the metaname "images":

ImageLinksMetaName images

If an image lives in http://localhost/vacations/france/index.html and "AbsoluteLinks" is set to no, then an image in that document like this:

<img src="beach.jpeg">

will only index "beach.jpeg" ๐Ÿ˜ญ.

But if you want more detail when searching, enable "AbsoluteLinks". Then Swish-e will index "http://localhost/vacations/france/beach.jpeg" ๐Ÿฅน. Now you can look for pictures of beaches, but only in France ๐Ÿ‡ซ๐Ÿ‡ท:

-w images=(beach and france)

This also means you can search for any images within France, bestie ๐Ÿ—ผ

-w images=(france)
โš ๏ธ Heads up: this feature is only available with the libxml2 HTML parser. ๐Ÿ™ˆ

UndefinedMetaTags ๐ŸŽ€

UndefinedMetaTags [errorโŽชignoreโŽชINDEXโŽชauto]

Okay so UndefinedMetaTags decides what Swish-e does during indexing when it finds a meta name that isn't listed in MetaNames ๐Ÿ‘€ There are four choices, and each one has its own energy:

  • error โ€” if a meta name shows up that isn't in MetaNames, indexing gets halted and an error is reported ๐Ÿšซ
  • ignore โ€” the contents of that meta tag get ignored and not indexed, unless a metaname has been defined with the MetaNames directive
  • index โ€” the contents of the meta tag get indexed, but they land in the main index unless there's already an enclosing metatag in force. This one is the default ๐Ÿ’…
  • auto โ€” this one creates meta tags automatically for HTML meta names and XML elements. Using it is the same as listing every meta name explicitly in a MetaNames directive โœจ

UndefinedXMLAttributes ๐Ÿฆ‹

UndefinedXMLAttributes [DISABLEโŽชerrorโŽชignoreโŽชindexโŽชauto]

This is basically the cousin of UndefinedMetaTags, but it only applies to XML documents (the ones parsed with libxml2). It lets you index attribute content, and gives you a way to index that content under a metaname. Like, UndefinedXMLAttributes can turn this:

<person age="23">
      John Doe
</person>

into this, as far as swish is concerned:

<person>
    <person.age>
        23
    </person.age>
    John Doe
</person>

What happens to the 23 depends on how UndefinedXMLAttributes is set:

  • disable โ€” XML attributes aren't parsed and aren't indexed. This is the default ๐Ÿ™…โ€โ™€๏ธ
  • error โ€” if the concatenated meta name (e.g. person.age) isn't listed in MetaNames, indexing gets halted and an error is reported ๐Ÿšซ
  • ignore โ€” the contents of the meta tag are ignored and not indexed, unless a metaname has been defined with the MetaNames directive
  • index โ€” the contents of the meta tag are indexed, but they go in the main index unless there's an enclosing metatag already in force
  • auto โ€” this creates meta tags from the combined element and attributes (plus the XML class name). Use it with caution, because it can generate a LOT of metaname entries ๐Ÿ˜ญ

Also peep the example below under XMLClassAttribues ๐Ÿ‘€


XMLClassAttributes

XMLClassAttributes *list of XML attribute names*

Okay this one is so cute ๐Ÿงš It combines an XML class name with the element name to make up a metaname. For example:

XMLClassAttributes class

<person class="first">
    John
</person>
<person class="last">
    Doe
</person>

Swish-e sees that as:

<person>
    <person.first>
    John
    </person.first>
</person>
<person>
    <person.last>
    Doe
    </person.last>
</person>

How the data gets indexed depends on MetaNames and UndefinedMetaTags ๐Ÿ’œ

Here's an example using this config, which combines XMLClassAttributes and UndefinedXMLAttributes:

XMLClassAttributes class
UndefinedMetaTags auto
UndefinedXMLAttributes auto
IndexContents XML2 .xml

The source XML file looks like:

<xml> <person class="student" phone="555-1212" age="102"> John </person>
<person greeting="howdy">Bill</person> </xml>

Swish-e parses as:

./swish-e -c 2 -i 1.xml -T parsed_tags  parsed_text  -v 0
Indexing Data Source: "File-System"

<xml> (MetaName)

    <person> (MetaName)
        <person.student> (MetaName)
            <person.student.phone> (MetaName)
                555-1212
            </person.student.phone>
            <person.student.age> (MetaName)
                102
            </person.student.age>
            John
    </person>

    <person> (MetaName)
        <person.greeting> (MetaName)
            howdy
        </person.greeting>
        Bill
    </person>

</xml>
Indexing done!

One thing to note ๐Ÿซถ The first <person> block finds a class name "student", so all the metanames created from attributes use the combined name person.student. The second <person> block doesn't contain a "class", so the attribute name gets combined directly with the element name (e.g. person.greeting).


ExtractPath ๐Ÿ—‚๏ธ

ExtractPath *metaname* [replaceโŽชremoveโŽชprependโŽชappendโŽชregex]

This directive lets you index extracted parts of a document's path. A common use is to limit searches to specific areas of your file tree, which is so useful, honestly ๐Ÿ”ฅ

The extracted string gets indexed under the metaname you specify.

See ReplaceRules for the rundown on the various pattern replacement methods, but you'll be using the regex method.

For example, say your file system (or web tree) is organized into departments:

/web/sales/foo...
/web/parts/foo...
/web/accounting/foo...

And you want a way to limit searches to just the documents under "sales":

ExtractPath department regex !^/web/([^/]+)/.*$!$1!

Which says: extract the department name (as substring $1) and index it as the metaname "department". Then, to limit a search to the sales department:

swish-e -w foo AND department=sales

Note that the regex method uses a substitution pattern, so to index only a sub-string, match the entire document path in the regular expression, as shown above. Otherwise, any part that isn't matched will end up in the substitution pattern ๐Ÿ™ˆ

See the ExtractPathDefault option for a way to set a value if no patterns match.

Although unlikely, you may use more than one ExtractPath directive. More than one directive with the same metaname will operate successively (in the order listed in the configuration file) on the path. This lets you run regular expressions on the results of the previous pattern substitution, kind of like piping the output from one expression into the pattern of the next:

ExtractPath foo regex !^(...).+$!$1!
ExtractPath foo regex !^.+(.)$!$1!

So, the third letter is indexed as the metaname "foo" if both patterns match ๐Ÿง 

ExtractPath foo regex !^X(...).+$!$1!
ExtractPath foo regex !^.+(.)$!$1!

Now (no X, no match!), if the first pattern doesn't match, the last character of the path name is indexed instead. You must be clear on this behavior if you're using more than one ExtractPath directive with the same metaname ๐Ÿ’€

The document path operated on is the real path swish used to access the document. That means the ReplaceRules directive has no effect on the path used with ExtractPath.

The full path is used for each metaname if more than one ExtractPath directive is used. That means changes to the path used in ExtractPath foo don't affect the path used by ExtractPath bar โœจ


ExtractPathDefault ๐ŸŒธ

ExtractPathDefault *metaname* default_value

This can be used with ExtractPath to set a default string to index under the given metaname, for when none of the ExtractPath patterns match.

For example, say you want to index each document with a metaname "department" based on these path examples:

/web/sales/foo...
/web/parts/foo...
/web/accounting/foo...

But you're also indexing documents that don't follow that pattern, and you want to search those separately too:

ExtractPath department regex !^/web/([^/]+)/.*$!$1!
ExtractPathDefault department other

Now you can search like this:

-w foo department=(sales)      - limit searches to the sales documents
-w foo department=(parts)      - limit searches to the parts documents
-w foo department=(accounting) - limit searches to the accounting documents
-w foo department=(other)      - everything but sales, parts, and accounting.

This basically is a shortcut for:

-w foo not department=(sales or parts or accounting)

...but you don't need to keep track of what got extracted ๐Ÿ’–


PropertyNames ๐ŸŒˆ

PropertyNames *list of meta names*
PropertyNamesCompareCase *list of meta names*
PropertyNamesIgnoreCase *list of meta names*

Swish-e lets you specify certain META tags that can be used as document properties. The contents of any META tag that's been identified as a document property can be returned as part of the search results, along with the rank, file name, title, and document size (see the -p and -x switches in SWISH-RUN) ๐Ÿ“„

Properties are great for returning extra data from documents in search results. This saves the effort of reading and parsing the source files while you're reading Swish-e search results, and it's especially useful when the source documents are no longer available or slow to access (e.g. over http) ๐Ÿฅน

Another feature of properties is that Swish-e can use PropertyNames for sorting search results (see the -s switch).

PropertyNames author subjects

There are two variations: PropertyNamesCompareCase and PropertyNamesIgnoreCase. These tell Swish-e to either ignore or compare case when sorting results. The default for PropertyNames is to ignore case.

PropertyNamesIgnoreCase subject
PropertyNamesCompareCase keyword

The defaults for "internal" properties are:

swishtitle          --  ignore the case
swishdocpath        --  compare case
swishdescription    --  compare case

These can be overridden with PropertyNamesCompareCase and PropertyNamesIgnoreCase:

PropertyNamesCompareCase swishtitle

Heads up, though: using PropertyNames will increase the size of your index files, sometimes significantly ๐Ÿ“ˆ Properties will be compressed if Swish-e is compiled with zlib, as described in the INSTALL manual page.

If Swish-e finds more than one property of the same name in a document, the property's contents will be concatenated for strings, and a warning will be issued for numeric (or date) properties ๐Ÿ”ฅ

๐Ÿ’… PropertyNamesNoStripChars ๐Ÿ’–

okay bestie, PropertyNamesNoStripChars tells swish-e that the listed properties should not have their low ASCII characters swapped out for a space ๐Ÿซถ. They get stored exactly as they show up in the document, no edits ๐Ÿ’…

When you print properties with the swish-e binary, newlines get turned into a space โœจ If you want them left alone, use the swish-e library (or the SWISH::API perl module) to grab the properties without newlines replaced ๐Ÿฆ‹

PropertyNamesNumeric ๐Ÿ”ข

this one is basically PropertyNames but with a glow-up ๐Ÿ’… It flags the property as a string of digits (an integer value) and stores it as binary data instead of a string ๐Ÿคฏ That's what lets -s sort and -L limit the property correctly โœจ

swish-e uses strtoul(3) to turn the string into an unsigned long integer, so only positive integers can be stored ๐Ÿ™ˆ

future versions of swish-e might be able to store other property types, like negative integers and real numbers ๐Ÿ‘€ This directive may change in future releases of Swish-e, so keep an eye on it ๐ŸŒˆ

PropertyNamesDate ๐Ÿ“…

this is exactly like PropertyNamesNumeric, but it also marks the number as a machine timestamp (seconds since Epoch) ๐Ÿ•ฐ๏ธ and it prints a formatted date whenever it returns this property. see -x in SWISH-RUN for more ๐ŸŽ€

swish-e will not parse dates when indexing, so you have to hand it a timestamp ๐Ÿ’€

PropertyNameAlias property name list of aliases ๐Ÿงš

PropertyNameAlias lets a property name have aliases, which is so iconic ๐Ÿ‘‘ For example, say you're indexing HTML files plus XML files written in English, German, and Spanish. Those use the tags "title", "titel", and "tรญtulo", so you can do this:

PropertyNameAlias swishtitle title titel tรญtulo titulo

heads up: swishtitle is the built-in property that stores a document's title ๐Ÿ“ So you don't need to list it as a PropertyName before using it ๐Ÿ’–

PropertyNamesMaxLength integer list of meta names ๐Ÿ“

this one sets the max length of the text stored in a property โœจ You give it a number between 0 and the max integer size on your platform, plus a list of properties. The properties you name must not be aliases ๐Ÿ™…โ€โ™€๏ธ

if any of the property names don't exist yet, swish-e creates them for you ๐Ÿซถ (so you don't need to define them with PropertyNames first)

honestly this is mostly useful when parsing HTML or XML with the libxml2 parser ๐Ÿ’œ

for example:

PropertyNamesMaxLength 1000 swishdescription
PropertyNameAlias swishdescription body

is kinda like this:

StoreDescription HTML <body> 1000
StoreDescription XML <body> 1000
StoreDescription HTML2 <body> 1000
StoreDescription XML2 <body> 1000

but StoreDescription lets you set the tag for each parser type, so it's a bit more hands-on ๐ŸŽ€

and this one collects all the heading text into a single property called "headings", not going over 1000 characters ๐Ÿ“š

PropertyNamesMaxLength 1000 headings
PropertyNameAlias headings h1 h2 h3 h4

PropertyNamesSortKeyLength integer list of meta names โฑ๏ธ

this sets the length of the string used when sorting ๐ŸŒธ The default is 100 characters. the -T metanames debugging option will list the current values for an index, so you can check your work ๐Ÿ”

it's used when sorting during indexing, and maybe when sorting while searching too ๐Ÿฆ‹ It also affects the order when you limit to a range of values with the -L option โœจ

PreSortedIndex list of property names ๐Ÿ—‚๏ธ

by default, swish-e generates presorted tables while indexing for each property name ๐Ÿ’… That makes sorting faster when it's time to generate results ๐Ÿƒโ€โ™€๏ธ But on large document collections, presorting can add to the indexing time and to the total size of the index ๐Ÿ˜ญ This directive lets you decide exactly which properties get presorted ๐Ÿ‘‘

  • if PreSortedIndex isn't in the config file (the default), all the properties get presorted at indexing time ๐ŸŒˆ
  • if it's present without any parameter, no properties get presorted ๐Ÿ™ˆ
  • otherwise, only the property names you list get presorted ๐Ÿ’–

say you only want to sort results by a property called "title":

PropertyNames title age time
PreSortedIndex  title

StoreDescription ๐Ÿ“

StoreDescription [XML <tag> sizeโŽชHTML <meta> sizeโŽชTXT size]

this lets you store a document description in the index file ๐Ÿซถ That description can show up in your search results when you use -x to include the swishdescription for extended results, or when you use -p swishdescription โœจ

the document type (XML, HTML, or TXT) has to match the type currently being indexed, as set by IndexContents or DefaultContents ๐Ÿšจ See those directives for the possible values. A super common problem is using StoreDescription without setting the document type with IndexContents or DefaultContents ๐Ÿ’€ Another sneaky problem is mismatched types:

IndexContents HTML2 .html
StoreDescription HTML <body>

here, .html documents get assigned a type of HTML2 (and get parsed by the libxml2 parser) ๐Ÿงš But the description won't be stored, because it's type HTML instead of HTML2 ๐Ÿ˜ญ

for text documents, you specify the type TXT (or TXT2 or TXT*) and how many characters to capture ๐Ÿ“–

StoreDescription TXT 20

that stores only the first twenty characters from the text file in the swish-e index file ๐ŸŒท

for HTML and XML file types, you specify the tag to use for the description, and optionally the number of characters ๐ŸŽ€ If you don't specify a number, it captures the entire contents of the tag ๐Ÿ“

StoreDescription HTML <body> 20000
StoreDescription XML  <desc> 40

again, documents must be assigned a document type with IndexContents or DefaultContents to use this feature ๐Ÿ’…

swish-e will compress the descriptions (or any other large property) if it's compiled to use zlib (see INSTALL) โœจ This is recommended when you're using StoreDescription with a large number of documents ๐Ÿซง Compression of 30% to 50% isn't uncommon with HTML files ๐Ÿคฉ

PropCompressionLevel [0-9] ๐Ÿ—œ๏ธ

this sets the compression level used when storing properties to disk ๐Ÿ’œ A setting of zero means no compression, and a setting of nine means the most compression ๐Ÿ”ฅ

the default depends on the default setting compiled with zlib, but it's typically six ๐ŸŒˆ

this is super useful when you use StoreDescription to store a lot of text in properties, or when you use PropertyNames with large property sizes ๐Ÿ“š

properties have to be over a value defined in config.h (100 is the default) before compression will even be attempted ๐Ÿ™ˆ And swish-e will never store the result of compression if the compressed data is larger than the original data ๐Ÿซถ

this option is only available when swish-e is compiled with zlib support, so check your build first โš ๏ธ

TruncateDocSize number of characters โœ‚๏ธ

TruncateDocSize limits the size of a document while indexing documents and/or using filters ๐Ÿฆ‹ It truncates the number of bytes read from a document down to the size you specify. So if a document is bigger, swish-e only reads that many bytes ๐ŸŒธ

example:

TruncateDocSize    10000000

the default is zero, which means read all the data ๐Ÿ’–

Warning: if you use TruncateDocSize, use it with care! ๐Ÿ’€ It's a safety belt only, meant to limit things like filter output, when accessing databases, or to stop "runaway" filters ๐Ÿšจ Truncating doc input may destroy document structures for swish-e (e.g. swish may miss closing tags for XML or HTML documents) ๐Ÿ˜ญ

TruncateDocSize doesn't currently work with the "prog" input source method ๐Ÿ™…โ€โ™€๏ธ

FuzzyIndexingMode NONEโŽชStemmingโŽชSoundexโŽชMetaphoneโŽชDoubleMetaphone ๐Ÿง 

FuzzyIndexingMode NONEโŽชStemmingโŽชSoundexโŽชMetaphoneโŽชDoubleMetaphone

this one selects the type of index to create ๐Ÿ”ฎ Only one type of index can be created per index, so pick wisely ๐Ÿ’…

it's a really good idea to create both a normal index and a fuzzy index, then let your search interface choose which one to use ๐Ÿซถ Lots of people find fuzzy searches to be too fuzzy, lowkey ๐Ÿ’€

if you want to see the available fuzzy indexing options, run:

swish-e -T LIST_FUZZY_MODES

available options include:

  • None โ€” words are stored in the index without any conversion. this is the default ๐ŸŒธ
  • Stemming_* โ€” uses one of the installed Snowball stemmers (http://snowball.tartarus.org/) ๐Ÿฆ‹ To see which stemmers are installed, run swish-e -T LIST_FUZZY_MODES (same command as above) โœจ For example, to use the Spanish stemming module:
FuzzyIndexingMode Stemming_es
  • Stem or Stemming_en โ€” this option is no longer supported. ๐Ÿ’€ It selects the legacy swish-e English stemmer, and it's deprecated in favor of the Snowball English stemmer Stemming_en1 ๐Ÿฅ€
the legacy English stemmer converts words using the Porter stemming algorithm, from http://www.tartarus.org/~martin/PorterStemmer/ ๐Ÿ“œ The Porter stemmer is a process for removing the commoner morphological and inflexional endings from English words. Its main use is as part of a term normalisation process, usually done when setting up Information Retrieval systems ๐Ÿงš

so, for example, this helps a search for "running" also find "run" and "runs" ๐Ÿƒโ€โ™€๏ธ

but here's the tea โ˜• the stemmer doesn't turn words into their root. It just programmatically chops off endings to make similar words with different endings stem to the same string of characters ๐Ÿซง It's not a perfect system, so searches on stemmed indexes often return curious results ๐Ÿ™ˆ For example, two entirely different words might stem to the same word ๐Ÿ’€

stemming can also get confusing with wildcards (truncation) ๐Ÿ˜ญ You might expect to find "running" by searching for runn*. But that fails on a stemmed index, because "running" stems to "run", while searching for runn* looks for words that start with "runn" ๐Ÿ’”

โœจ Soundex โœจ

Soundex was cooked up in the 1880s so records for people with similar sounding names could be found more easily ๐Ÿ’…. It's a coded surname based on how a surname sounds instead of how it's spelled ๐Ÿฆ‹. Names that sound alike, like Smith and Smyth, get filed together under the same Soundex code ๐Ÿ‘‘. This is mostly useful for US English ๐ŸŒธ.

Soundex should not be used to search for sound-alike words, bestie ๐Ÿ™ˆ. Metaphone is way more appropriate for generic sound matching of words. Soundex should only be used when you need to search multiple documents for proper names that sound similar. It's primarily used for indexing genealogical records ๐Ÿ“œ, and it may be useful for indexing other collections of data that are mostly names ๐ŸŽ€. Lots of common name variations get matched by Soundex. The only notable exception is the first letter of the name, which is not matched for sound ๐Ÿ’€.

๐Ÿงš Metaphone and DoubleMetaphone ๐Ÿงš

Words get transformed into a short series of letters representing the sound of the word (in English) โœจ. Metaphone algorithms are often used for looking up mis-spelled words in dictionary programs, so they're super helpful for that ๐Ÿ’–.

Source: "From: http://aspell.sourceforge.net/metaphone/"

Lawrence Philips' Metaphone Algorithm is basically an algorithm that returns the rough approximation of how an English word sounds ๐ŸŒˆ.

The "DoubleMetaphone" mode will sometimes generate two different metaphones for the same word ๐Ÿ‘ฏ. It's supposed to be useful when a word may be pronounced more than one way ๐Ÿซถ.

A metaphone index should give results somewhere in between Soundex and Stemming ๐Ÿ’œ.


UseStemming [yesโŽชNO]

Set it to yes to turn on the word stemming algorithm while indexing, or no to skip it ๐ŸŒฟ.

UseStemming no
UseStemming yes

When UseStemming is set to "yes", every word gets stemmed before it goes into the index โœจ.

โš ๏ธ This option is deprecated ๐Ÿ˜ญ. It has been superseded by FuzzyIndexingMode.

UseSoundex [yesโŽชNO]

When UseSoundex is set to "yes", every word gets converted to a Soundex code before it goes into the index ๐Ÿ”ฎ.

โš ๏ธ This option is deprecated ๐Ÿ’€. It has been superseded by FuzzyIndexingMode.

IgnoreTotalWordCountWhenRanking [YESโŽชno]

Put yes to ignore the total number of words in the file when ranking gets calculated ๐Ÿ“. It's often better with merges and small files ๐Ÿง. Default is yes.

IgnoreTotalWordCountWhenRanking no

The default was changed from no to yes in version 2.2 ๐ŸŽ€.

NOTE: must be set to no if you intend to use the -R 1 option when searching ๐Ÿšจ.

MinWordLimit integer

Sets the minimum length of a word. Shorter words won't be indexed ๐Ÿฆ‹. The default is 1 (as defined in src/config.h).

MinWordLimit 5

MaxWordLimit integer

Sets the maximum length of an indexable word. Every longer word won't be indexed ๐Ÿšซ. The default is 40 (as defined in src/config.h).


Word-shaping crew ๐Ÿ’…

  • WordCharacters string of characters
  • IgnoreFirstChar string of characters
  • IgnoreLastChar string of characters
  • BeginCharacters string of characters
  • EndCharacters string of characters

These settings define what a word consists of to the Swish-e indexing engine ๐Ÿง . Compiled-in defaults live in src/config.h.

When indexing, Swish-e uses WordCharacters to split the document into words โœ‚๏ธ. A word is any string of non-blank characters that only contains characters listed in WordCharacters. If a string includes a character that isn't in WordCharacters, the word gets split into two or more separate words ๐Ÿ’”.

For example:

WordCharacters abde

This would turn "abcde" into two words, "ab" and "de" ๐Ÿฅน.

Next, any characters defined in IgnoreFirstChar get stripped off the start of each word, and IgnoreLastChar characters get stripped off the end ๐Ÿงน. This lets you keep periods within a word (www.slashdot.com) but not at the end of one โœจ. Characters in IgnoreFirstChar and IgnoreLastChar must be in WordCharacters.

Finally, the resulting words MUST begin with one of the characters listed in BeginCharacters and end with one of the characters listed in EndCharacters ๐Ÿšฆ. BeginCharacters and EndCharacters must be a subset of the characters in WordCharacters. Often, WordCharacters, BeginCharacters and EndCharacters will all be the same ๐Ÿ‘ฏโ€โ™€๏ธ.

The same process applies to the query while searching, so it's all consistent ๐Ÿซถ.

Getting these settings right takes careful thought and practice ๐Ÿ˜ค. It's super helpful to create an index of a single test file and then look at the words that land in the index (see the "-v 4", "-D" and "-k" searching switches) ๐Ÿ”.

Currently there's only support for eight-bit characters ๐ŸŒˆ.

Example:

WordCharacters  .abcdefghijklmnopqrstuvwxyz
BeginCharacters abcdefghijklmnopqrstuvwxyz
EndCharacters   abcdefghijklmnopqrstuvwxyz
IgnoreFirstChar .
IgnoreLastChar  .

So the string:

Please visit http://www.example.com/path/to/file.html.

will be indexed as the following words:

please
visit
http
www.example.com
path
to
file.html

Which means you can search for "www.example.com" as a single word, but searching for just "example" will not find the document ๐Ÿ™ˆ.

Note: when indexing HTML documents, HTML entities get converted to their character equivalents before being processed with these directives ๐ŸŽ€. This is a change from previous versions of Swish-e, where you had to include the characters "0123456789&#;" to index entities. See also "ConvertHTMLEntities".

Buzzwords [list of buzzwordsโŽชFile: path]

The Buzzwords option lets you name words that will be indexed no matter what WordCharacters, BeginCharacters, EndCharacters, stemming, soundex and many of the other word checks say ๐Ÿš€. Main character energy!

Buzzwords are case insensitive ๐Ÿซ .

Buzzwords should be separated by spaces and can span multiple directives ๐Ÿงต. If the special format "File:filename" is used, the Buzzwords get read from an external file during indexing ๐Ÿ“‚.

Examples:

Buzzwords C++ TCP/IP

Buzzwords File: ./buzzwords.lst

If a Buzzword contains search operator characters, they must be backslashed when searching ๐Ÿ™ƒ. For example:

Buzzwords C++ TCP/IP web=http

./swish-e -w 'web\=http'

Buzzwords are found by splitting the text on whitespace, removing "IgnoreFirstChar" and "IgnoreLastChar" characters from the word, and then comparing with the list of "Buzzwords" ๐Ÿ”Ž. So if you're adding Buzzwords to an index, you'll probably want to define IgnoreFirstChar and IgnoreLastChar settings ๐Ÿ’….

Note: Buzzwords-specific settings for IgnoreFirstChar and IgnoreLastChar may be used in the future ๐Ÿ”ฎ.

CompressPositions [yesโŽชNO]

This option turns on zlib compression for individual word data in the index file ๐Ÿ—œ๏ธ. The default is NO, which means the index word data is not compressed by default.

Enabling this can reduce the size of the index file, but it comes at the expense of slower wildcard search times ๐Ÿข.

The default changed from YES to NO starting with version 2.4.3 ๐Ÿ“.

IgnoreWords [list of stop wordsโŽชFile: path]

The IgnoreWords option lets you specify words to ignore, called stopwords ๐Ÿšซ. The default is to not use any stopwords ๐ŸŒธ.

Words should be separated by spaces and can span multiple directives ๐Ÿงต. If the special format "File:filename" is used, the stop words get read from an external file during indexing ๐Ÿ“‚.

In previous versions of Swish-e you could use the directive:

IgnoreWords swishdefault - obsolete!

to include a default list of compiled-in stopwords ๐Ÿ•ฐ๏ธ. This keyword is no longer supported ๐Ÿ’€.

Examples:

IgnoreWords www http a an the of and or

IgnoreWords File: ./stopwords.de

UseWords [list of wordsโŽชFile: path]

UseWords defines the words that Swish-e will index ๐ŸŽฏ. Only the words listed will be indexed โœจ.

You can list words right after the directive (you can use more than one UseWords directive in a config file), and/or use the "File:" form to point at a file containing the words ๐Ÿ“ƒ:

UseWords perl python pascal fortran basic cobal php
UseWords File: /path/to/my/wordlist
Please drop the Swish-e list a note if you actually use this feature ๐Ÿ’Œ. It may be removed from future versions ๐Ÿ˜ญ.

IgnoreLimit integer integer

This automatically omits words that show up too often in the files (these words are called stopwords) ๐Ÿ™ˆ. Specify a whole percentage and a number, such as "80 256". This omits words that occur in over 80% of the files and appear in over 256 files ๐Ÿงฎ. Comment it out to turn off auto-stopwording ๐Ÿ’ค.

IgnoreLimit 50 1000

Swish-e has to do extra processing to adjust the entire index when this feature is used ๐Ÿ˜ฉ. It's recommended that, instead of using this feature, you decide which words are stopwords yourself and add them to IngoreWords in your configuration file ๐Ÿง . To do this, use IgnoreLimit one time and note the stop words that get found while indexing. Add that list to IgnoreWords, and then remove IgnoreLimit from the configuration file ๐Ÿซถ.

IgnoreMetaTags list of names

IgnoreMetaTags defines a list of metatags to ignore while indexing XML files (and HTML files if using libxml2 for parsing HTML) ๐Ÿ™…โ€โ™€๏ธ. All text within those tags gets ignored, both for indexing ("MetaNames") and for properties ("PropertyNames"). If you want to still parse properties but not index the text, see "UndefinedMetaTags" ๐ŸŽ€.

This option is useful for avoiding indexing specific data from a file ๐Ÿ”. For example:

<person>
    <first_name>
        William
    </first_name> <last_name>
        Shakespeare
    </last_name> <updated_date>
        April 25, 1999
    </updated_date>
</person>

In the above example, you might not want to index the updated date, and therefore prevent finding this record by searching:

-w 'person=(April)'

This is solved by:

IgnoreMetaTags updated_date

See also "UndefinedMetaTags" ๐Ÿ‘‘.

๐Ÿงช IgnoreNumberChars list of characters

๐Ÿงช Experimental Feature โ€” this one is still in its experimental era, so it may change in future versions. One possible change is to use regular expressions instead. ๐Ÿ™ˆ

okay so this one is giving number filter. โœจ You list a set of characters that describe a number, and if a word is made up of only those characters, Swish-e will skip indexing it. The characters you list have to already be part of your WordCharacters settings, because the "word" being checked is one Swish-e would otherwise index anyway. ๐Ÿ’…

For example:

IgnoreNumberChars 0123456789$.,

With that set, Swish-e would not index any of these:

123
123,456.78
$123.45
๐Ÿ™ˆ Bestie, careful with hex. You might be tempted to skip hex numbers with: IgnoreNumberChars 0123456789abcdef That won't index 0D31, but it also won't index the word "bad". ๐Ÿ’€

๐Ÿ’ฌ IndexComments [NOโŽชyes]

this option lets the user decide whether the contents of HTML comments get indexed. ๐Ÿซถ The default is no, so set it to yes if you actually need comment indexing.

IndexComments yes

Note: this is a change from the default behaviour before version 2.2, so keep that in mind if you're upgrading old configs. ๐ŸŒธ


๐Ÿ” TranslateCharacters [*string1 string2*โŽช:ascii7:]

the TranslateCharacters directive maps the characters in string1 to the characters in string2. It's like a makeover for your characters. ๐Ÿ’…

# This will index a_b as a-b and รกmo as amo
TranslateCharacters _รก -a

TranslateCharacters :ascii7: is a predefined set that turns eight bit characters into ascii7 characters. So with the :ascii7: rule, "ร„รครง" becomes "aac", which means searching "ร‡elik", "รงelik" or "celik" will all match the same word. โœจ Iconic. ๐Ÿฆ‹

Here's the timing tea โ˜•: translation happens early in the indexing process, after HTML entities are converted but before the input gets split into words based on WordCharacters. So the characters you're translating from don't need to be listed in word characters. ๐Ÿงš The same character translations also happen when searching. ๐Ÿ”ฅ


๐Ÿซง BumpPositionCounterCharacters string

when Swish-e indexes, it gives each word a position number, and that's what makes phrase searching work. ๐ŸŒˆ Sometimes you don't want phrases matching, though. The BumpPositionCounterCharacters directive lets you name a set of characters that, when they show up in the text, bump the word position up. That basically stops phrase matches from crossing that character. ๐Ÿ™…โ€โ™€๏ธ

For example, if you have a tag like this:

<subjects>
    computer programming โŽช apple computers
</subjects>

You might want to stop "programming apple" from matching in that meta name, so you'd write:

BumpPositionCounterCharacters โŽช

There is no default, and you can list a whole string of characters. ๐Ÿ’œ


๐Ÿช„ DontBumpPositionOnEndTags list of names & DontBumpPositionOnStartTags list of names

okay this one's a little plot twist. ๐ŸŽ€ Metatags are usually separate data fields, so the word position counter gets bumped automatically between metatags. It happens when a start tag is found and when an end tag is found too. This stops a phrase from matching across more than one metaname. ๐Ÿ™ˆ

DontBumpPositionOnEndTags and DontBumpPositionOnStartTags turn that feature off for the metanames you list. ๐Ÿซถ

For example, say you have this document:

<person>
    <first_name>
        William
    </first_name>
    <last_name>
        Shakespeare
    </last_name>
    <updated_date>
        April 25, 1999
    </updated_date>
</person>

In the configuration file, you'd write:

DontBumpPositionOnEndTags first_name
DontBumpPositionOnStartTags last_name

With that config, this phrase search works:

-w 'person=("william shakespeare")'

but this one will fail:

-w 'person=("shakespeare april")'

๐Ÿ“ Directives for the File Access method only

some directives do different jobs depending on where your documents come from. โœจ These ones are only valid when you're using the File system method of indexing. ๐Ÿ—‚๏ธ


๐Ÿ“„ IndexOnly list of file suffixes

this directive sets which file suffixes (extensions) are allowed while indexing. ๐ŸŒท The default is to index all files found under IndexDir.

# Only index .html .htm and .q files
IndexOnly .html .htm .q

Quick heads-up: IndexOnly checks that a file name ends in the characters listed. It does not check "extensions". ๐Ÿง It's tested right before FileRules gets processed.


put yes to follow symbolic links while indexing, or no if you don't. ๐Ÿ’– The default is no.

FollowSymLinks no
FollowSymLinks yes

Here's the tea: when this is set to no, extra stat(2) system calls have to be made for each file. โ˜• If you've got a large number of files, setting it to yes might give you a small cut in indexing time. โญ

See also the -l switch in SWISH-RUN. ๐Ÿฆ‹


๐Ÿšฆ FileRules [type] [containsโŽชisโŽชregex] regular expression & FileMatch [type] [containsโŽชisโŽชregex] regular expression

FileRules and FileMatch are how you exclude and include files and directories when indexing, respectively. ๐Ÿซง By default Swish-e indexes all files and recurses into all directories (but see also FollowSymLinks), so you'll usually only reach for FileRules to exclude stuff. FileMatch comes in clutch in a few cases, like overriding what IndexOnly did. Some examples are below. ๐Ÿ‘‘

Heads up: apart from FileRules title ..., this feature is only available for the file access method (-S fs), which is the default indexing mode. ๐ŸŒˆ Also, any pathname changes made with ReplaceRules happen after the FileRules check. (It's unlikely you'd exclude files with FileRules based on text you added with ReplaceRules!) ๐Ÿ™ƒ

The regular expression is a C regex.h extended regular expression. ๐Ÿงš You can supply more than one regular expression per line, or use separate directives. Putting the word not in front of the regular expression negates the match. ๐Ÿ”ฅ

The regular expression gets compared against the type described below.

For historical reasons, you can specify contains or is. is just forces the regular expression to match at the start and end of the string, which it does by internally prepending ^ and appending $ to the regular expression. ๐Ÿ’…

The regex option needs delimiter characters:

FileRules title regex /^private/i

The only real perk of regex is if you want case insensitive matches, or you just like your regular expressions to look like Perl regular expressions. ๐Ÿ’œ You must use matching delimiters. (), {}, and [] aren't currently supported, and the only reason is laziness. ๐Ÿ’€

Use quotes (" or ') around a pattern if it contains any white space. Also, the backslash becomes the escape character inside quotes, so watch out. โš ๏ธ

These all generate the same regular expressions:

FileRules title is hello
FileRules title contains ^hello$
FileRules title regex /^hello$/

These all need quotes because of the space character:

FileRules title is "hello there"
FileRules title contains "^hello there$"
FileRules title regex "!^hello there$!"

These show how the backslash has to be doubled inside quotes. Swish-e turns a double-backslash into a single backslash, and then passes that single one on to the regular expression compiler. ๐Ÿค“

FileRules filename regex /\.pdf/
FileRules filename regex "/\\.pdf/"

FileRules filename regex !hello\\there!     # need double for real backslash
FileRules filename regex "!hello\\\\there!" # need double-double inside of quotes

Matching Types ๐ŸŽ€

The following types of match strings may be supplied:

FileRules pathname
FileRules dirname
FileRules filename
FileRules directory
FileRules title

FileMatch pathname
FileMatch filename
FileMatch dirname
FileMatch directory

pathname matches the regular expression against the current pathname. Whether it's absolute or not depends on what you gave to IndexDir. ๐Ÿ—บ๏ธ

Example:

# Don't index paths that contain private or hidden
FileRules pathname contains (privateโŽชhidden)

# Same thing
FileRules pathname regex /(privateโŽชhidden)/

# Don't index exe files
FileRules pathname contains \.exe$

dirname and filename split the path name at the last delimiter character into a directory name and a file name. Then those get compared against your patterns. Directory names don't have a trailing slash, and all path names use the forward slash as a delimiter within Swish-e. ๐Ÿฆ‹

Example:

# Same as last example - don't index *.exe files.
FileRules filename contains \.exe$

# Don't index any file called test.html files
FileRules filename contains ^test\.html$

# Same thing
FileRules filename is test\.html

# Don't index any directories that contain "old"  (/usr/local/myold/docs)
FileRules dirname contains old

# Don't index any directories that contain the path segment "old" (/usr/local/old/foo)
FileRules dirname contains /old/

# Index only .htm, .html, plus any all-digit file names
IndexOnly .htm .html
FileMatch filename contains ^\d+$

# Same as previous, but maybe a little slower
FileRules filename regex not !\.(htmโŽชhtml)$!
FileMatch filename contains ^\d+$

Swish-e checks these settings in the order of pathname, dirname, and filename. In general, FileMatch patterns get checked before FileRules. โœจ This means you can exclude most files with FileRules and still let in a few special cases with FileMatch. ๐Ÿซถ For example:

# Exclude all files of .exe, .bin, and .bat
FileRules filename contains \.(exeโŽชbinโŽชbat)$
# But, let these two in
FileMatch filename is baseball\.bat incoming_mail\.bin

# Same, but as a single pattern
FileMatch filename is (baseball\.batโŽชincoming_mail\.bin)

The "directory" type is kinda unique ๐Ÿฆ‹ When Swish-e recurses into a directory, it checks every file in that directory against the pattern, then decides if the entire directory gets indexed (or recursed) or not. ngl that's giving "one bad apple spoils the bunch" energy ๐ŸŽ Remember you're matching against file names in a directory, and some of those names might be directory names too ๐Ÿ“‚

A "FileRules directory" match makes Swish-e ignore all files and sub-directories in the current directory. Total main character energy for exclusion ๐Ÿ’…

โš ๏ธ Warning! A match with "FileMatch directory" says to index everything in the current directory and ignore any FileRules for this directory. Handle with care, bestie ๐Ÿ˜ญ

Example:

# Don't index any directories (and sub directories) that contain
# a file (or sub-directory) called "index.skip"
FileRules directory contains ^index\.skip$

# Don't index directories that contain a .htaccess file.
FileRules directory contains ^\.htaccess

Note: While processing directories, Swish-e will skip any files or directories that begin with a dot (.) ๐Ÿ™ˆ If you do want dot-files or dot-directories indexed, name them with IndexDir or -i and they'll get in โœจ

"title" checks for a pattern match in an HTML title ๐ŸŽ€

Example:

FileRules title contains construction example pointers

# This example says to ignore case
FileRules title regex "/^Internal document/i"

Note: FileRules title works for any input method (fs, prog, or http) that gets parsed as HTML, and only where a title was actually found in the document ๐Ÿ“„

Okay so if all this feels a bit confusing, don't worry, it's a lot ๐Ÿ˜ญ Here's the order Swish-e processes a directory in, step by step ๐Ÿ’–

First, the directory name gets checked:

FileRules dirname - reject entire directory if matches

Next, the directory gets scanned and each file name (which might be a sub-directory name) gets checked:

FileRules directory - reject entire dir if *any* files match
FileMatch directory - accept entire dir if *any* files match

Then, unless "FileMatch directory" matched, each file gets tested with FileMatch. A match says to index the file without further testing, which means it overrides FileRules and IndexOnly ๐Ÿ”ฅ

FileMatch pathname  \
FileMatch dirname   - file is accepted if any match
FileMatch filename  /

Otherwise:

IndexOnly - file is checked for the correct file extension

FileRules pathname  \
FileRules dirname   - file is rejected if any match
FileRules filename  /

Finally, the file gets indexed ๐ŸŽ‰

Files (not directories) listed with IndexDir or -i get processed in a similar way ๐Ÿงš First up, FileMatch:

FileMatch pathname  \
FileMatch dirname   - file is accepted if any match
FileMatch filename  /

Otherwise, the file gets rejected if it doesn't have the correct extension or if a FileRules matches:

IndexOnly - file is checked for the correct file extension

FileRules pathname  \
FileRules dirname   - file is rejected if any match
FileRules filename  /

Note: If things aren't indexing the way you expect, make a directory with some test files and use the -T regex trace option to see how file names are checked ๐Ÿ” Start with very simple tests, no cap!


โœจ Directives for the HTTP Access Method Only โœจ

The HTTP Access method is turned on with the -S http switch when indexing ๐ŸŒ It works by running a Perl program called SwishSpider, which fetches documents from a web server.

Only text files (content-type of "text/*") get indexed with the HTTP Access Method. Other document types (e.g. PDF or MSWord) may be indexed as well ๐Ÿ“‘ SwishSpider will try to use the SWISH::Filter module (included with the Swish-e distribution) to convert documents into a format Swish-e can index ๐Ÿ”ง

Note: The -S prog method of spidering (using spider.pl) can be a replacement for the -S http method. It offers more configuration options and better spidering speed ๐Ÿš€

These directives below are available when using the HTTP Access Method of indexing ๐Ÿ’œ

๐ŸŒธ MaxDepth integer

MaxDepth defines how many links the spider should follow before stopping. A value of 0 tells the spider to traverse all links. The default is MaxDepth 0.

MaxDepth 5

Note: The default was changed from 5 to 0 in release 2.4.0 ๐Ÿฆ‹

๐Ÿซถ Delay seconds

This is the number of seconds to wait between issuing requests to a server. It's a super friendly way to spider remote sites ๐Ÿฅฐ The default is 5 seconds.

Delay 1

Note: The default was changed from 60 to 5 seconds in release 2.4.0 โญ

๐Ÿ“ TmpDir path

This is the location of a writable temp directory on your system. The HTTP access method tells the Perl helper to put its files here, and the -e switch makes Swish-e use this directory while indexing. There is no default ๐Ÿ™…โ€โ™€๏ธ

TmpDir /tmp/swish
โš ๏ธ If this directory doesn't exist or isn't writable, Swish-e will fail with an error during indexing ๐Ÿ’€

Note, the environment variables TMPDIR, TMP, and TEMP (in that order) will override this setting ๐ŸŒˆ

๐Ÿ’… SpiderDirectory path

This is the location of the Perl helper script called swishspider. If you use a relative directory, it's relative to your directory when you run Swish-e, not to the directory that Swish-e is in ๐Ÿ—บ๏ธ The default is the location swishspider was installed. Normally you don't need to set this ๐Ÿ™Œ

SpiderDirectory /usr/local/swish

๐Ÿ‘‘ EquivalentServer server alias

Okay so the same site can be referred to by different names all the time ๐Ÿ™ƒ A common example is that http://www.some-server.com and http://some-server.com are literally the same place. Each line should have a list of all the method/names that should be considered equivalent. You can use multiple EquivalentServer directives, and each one defines its own set of equivalent servers ๐Ÿ’–

EquivalentServer http://library.berkeley.edu http://www.lib.berkeley.edu
EquivalentServer http://sunsite.berkeley.edu:2000 http://sunsite.berkeley.edu

๐Ÿงš Directives for the prog Access Method Only ๐Ÿงš

This section covers the directives that only work with the "prog" document source feature of Swish-e ๐Ÿ’ซ The prog access method runs an external program that "feeds" documents to Swish-e, which means you can index and filter documents from literally any source ๐ŸŒ

See prog - general purpose access method in the SWISH-RUN man page for more information ๐Ÿ“–

A bunch of example programs for the prog access method live in the prog-bin directory. Check those out if you have questions about writing a prog input program ๐ŸŽ€

โœจ SwishProgParameters list of parameters

This is a list of parameters that gets sent to the external program when you run with the "prog" document source method. It's the easiest way to pass settings from the Swish-e configuration file to the external program ๐Ÿซถ

SwishProgParameters /path/to/config hello there
IndexDir /path/to/program.pl

Then running:

swish-e -c config -S prog

Swish-e will execute /path/to/program.pl and pass /path/to/config hello there to the program as three command line arguments ๐Ÿ”ฅ

For example, the spider.pl program (included in the prog-bin directory) uses SwishProgParameters to specify which file to read for configuration information ๐Ÿง 

SwishProgParameters spider.config
IndexDir ./spider.pl

The spider.pl program also has a default action, so you can skip the configuration file entirely ๐Ÿฅณ

SwishProgParameters default http://www.swishe.org/ http://some.other.site/
IndexDir ./spider.pl

And the spider program will use default settings for spidering those sites ๐Ÿ•ท๏ธ

Swish-e can also read documents from standard input, so another way to run an external program with parameters looks like this ๐ŸŒท

./spider.pl spider.conf โŽช ./swish-e -S prog -i stdin

๐ŸŽ€ Notes when using MS Windows ๐ŸŽ€

You should use unix style path separators to specify your external program ๐ŸชŸ Swish will convert forward slashes to backslashes before calling the external program. This only applies to the program name specified with IndexDir or the -i command line option.

Also, Swish-e will make sure the program you specify actually exists, which means you need to use the full name of the program ๐Ÿซ 

For example, to run the perl spider program spider.pl, you'd need a Swish-e configuration file like this:

IndexDir e:/perl/bin/perl.exe
SwishProgParameters prog-bin/spider.pl default http://swish-e.org

Then run indexing with the command:

swish-e -c swish.cfg -S prog -v 9

The IndexDir command tells Swish-e the name of the program to run ๐Ÿƒโ€โ™€๏ธ Under unix you can just specify the name of the script, since unix will figure out the program from the first line of the script ๐Ÿง

The SwishProgParameters are the parameters passed to the program specified by IndexDir (perl.exe in this case). The first parameter is the perl script to run (prog-bin/spider.pl), and perl passes the rest of the parameters directly to the perl script. The second parameter, default, tells the spider.pl program to use default settings for spidering (or you could specify a spider config file. See perldoc spider.pl for details). Lastly, the URL gets passed into the spider program ๐Ÿ’œ


๐Ÿฆ‹ Document Filter Directives ๐Ÿฆ‹

Internally, Swish-e only knows how to parse text, HTML, and XML documents ๐Ÿ“š With filters you can index other types of documents too. For example, if all your web pages are in gzip format, a filter can uncompress them on the fly while indexing ๐Ÿ—œ๏ธ

You may wish to read the Swish-e FAQ question on filtering before continuing here. How Do I filter documents? ๐Ÿค”

There are two suggested methods for filtering ๐Ÿ’…

๐ŸŒˆ Filtering with SWISH::Filter ๐ŸŒˆ

The Swish-e distribution includes a Perl module called SWISH::Filter and individual filters located in the filters directory ๐Ÿง This system uses plug-in filters to extend the types of documents Swish-e can index. The plug-in filters don't actually do the filtering themselves. They just provide a standard interface for accessing programs that can filter or convert documents ๐Ÿ”Œ The programs that do the filtering are not part of the Swish-e distribution, so they must be downloaded and installed separately ๐Ÿ“ฆ

The advantage of this method? New filtering methods can be installed easily ๐Ÿ™Œ

This system is designed to work with the -S http and -prog methods, but it can also vibe with the "FileFilter" feature and the -S fs indexing method ๐Ÿฆ‹. Peep this script for an example ๐ŸŒธ:

$prefix/share/doc/swish-e/examples/filter-bin/swish_filter.pl

Also, the filters/README file has more info, so go read it when you get a sec ๐Ÿ“–โœจ


๐ŸŽ€ Filtering with the FileFilter feature ๐ŸŽ€

A filter is an external program that Swish-e runs while it's processing a document of a certain type ๐Ÿ’…. Swish-e runs the filter program for every file that matches the file suffix (extension) set in the FileFilter or FileFilterMatch directives. FileFilterMatch matches using regular expressions, and we'll get to that below ๐ŸŒˆ.

Filters can be used with any type of input method (aka -S fs, -S http, or -S prog). But becauseโ€ฆ

Swish-e calls the external program and passes these as default arguments, so bestie, take note ๐Ÿ“:

  • $0 โ€” the name of the filter program
  • $1 โ€” the physical path name of the file to read. This might be a temporary file location if you're indexing by the http method ๐Ÿ—‚๏ธ
  • $2 โ€” when you're indexing under the file system, this is the same as $1 (the path to the source file). But when you're indexing under the http method, this is the URL of the source document ๐Ÿ”—

Swish-e can also pass other parameters to the filter program. You define these using the FileFilter or FileFilterMatch directives. See Filter Options below ๐Ÿ’–.

The filter program has to open the file, process its contents, and hand it back to Swish-e by printing to STDOUT ๐Ÿ–จ๏ธ.

โš ๏ธ Heads up, bestie: if your external program is a perl or shell script, this can add a lot of time to the indexing process ๐Ÿ˜ญ. If you have tons of files to filter, you should think about writing your filter in C instead of a shell or perl script, or using the "prog" Access Method along with SWISH::Filter ๐Ÿ’€.

FilterDir

FilterDir  *path-to-directory*

Deprecated. Yeah, this one is on its way out ๐Ÿฅ€.

This is the path to a directory where your filter programs live. Swish-e looks in this directory to find the filter named in the FileFilter directive ๐Ÿ“‚.

You don't need this if the filter program can be found in your system's path โœจ. Even if your filter isn't in your system's path, you can still give the full path to the filter in the FileFilter or FileFilterMatch directives ๐Ÿงš.

Example:

FilterDir /usr/local/swish/filters

FileFilter

FileFilter   *suffix*   "filter-prog"   ["filter-options"]

This maps a file suffix (extension) to a filter program ๐Ÿฆ‹. If filter-prog starts with a directory delimiter (aka an absolute path), Swish-e skips the FilterDir settings and uses the given filter-prog path directly ๐ŸŽฏ.

On systems with a working fork(2) system call, the filter program gets run by forking swish and then executing the filter. This means the shell isn't used to run the filter, and no arguments go through the shell ๐Ÿ™Œ.

On other systems (like Windows), the arguments are double-quoted and popen(3) is used to run the program. This does pass arguments through the shell, which may be a security concern depending on what the shell is able to do ๐Ÿšจ.

Filter options:

Filter options are a string passed as arguments to the filter-prog ๐ŸŽ€. Filter options can contain variables, which Swish-e replaces for you โœจ. If you leave out filter-options, Swish-e will use the default parameters for the options listed above ๐Ÿ’….

Default:

%p %P

Which means you're passing "workfile path" and "documentfile path" to the filter ๐ŸŒธ.

Variables in filter options:

  • %% โ€” a literal percent sign (%) ๐Ÿ’…
  • %P โ€” full document pathname (e.g. URL, or path on filesystem) ๐Ÿ”—
  • %p โ€” full pathname to work file (maybe a tmpfile or the real document path on filesystem) ๐Ÿ—ƒ๏ธ
  • %F โ€” filename stripped from full document pathname ๐Ÿ“„
  • %f โ€” filename stripped from "work" pathname ๐Ÿ“
  • %D โ€” directoryname stripped from full document pathname ๐Ÿ“
  • %d โ€” directoryname stripped from full "work" pathname ๐ŸŒท

Examples of strings passed:

%P =  document pathname:  http://myserver/path1/mydoc.txt
%p =  work pathname:      /tmp/tmp.1234.mydoc.txt
%F =     mydoc.txt
%f =     tmp.1234.mydoc.txt
%D =     http://myserver/path1
%d =     /tmp

Notes when using MS Windows

Windows uses double quotes to escape shell metacharacters ๐ŸชŸ. So if you need quotes, wrap the entire option string in single quotes ๐Ÿ’ซ.

FileFiler .mydoc mydocfilter.exe '--title "text with spaces"'

You can specify the filter program with forward slashes (unix style), and Swish will convert the slashes to backslashes before running your program ๐Ÿ”.

FileFilter .mydoc     c:/some/path/mydocfilter.exe  '-d "%d" -example -url "%P" "%f"'

Examples of filters:

FileFilter .doc       /usr/local/bin/catdoc "-s8859-1 -d8859-1 %p"
FileFilter .pdf       pdftotext   "%p -"
FileFilter .html.gz   gzip  "-c %p"
FileFilter .mydoc     "/some/path/mydocfilter"  "-d %d -example -url %P %f"

The examples above are running a binary filter program ๐Ÿ‹๏ธ. For more complicated filtering needs, you can use a scripting language like Perl or a shell script ๐Ÿ“œ. Here are some examples of calling a shell script and a perl script ๐Ÿš:

FileFilter .pdf       pdf2html.sh
FileFilter .ps        ghostscript-filter.pl
๐Ÿข Using a scripting language (or any language with a large startup cost) can greatly increase the indexing time. For small indexing jobs this might not be a big deal, but for large collections of files that need processing by a scripting language, you may be better off using the "-S prog" access method, where the script only gets compiled once instead of once per document ๐Ÿ’€.

Filters are probably easier to write than a "-S prog" program ๐Ÿฅฐ. Which one you pick depends on your requirements ๐Ÿ’…. Examples of filter scripts can be found in the filter-bin directory, and examples of "-S prog" programs can be found in the prog-bin directory ๐Ÿงšโ€โ™€๏ธ.

FileFilterMatch

FileFilterMatch   *filter-prog*   *filter-options*  *regex* [*regex* ...]

This is similar to "FileMatch", except it uses regular expressions to match against the file name ๐Ÿ”. filter-prog is the path to the program. Unlike "FileFilter", this does not use the "FilterDir" option ๐Ÿ™…. Also unlike "FileFilter", you must specify the filter-options ๐Ÿซถ.

Examples:

FileFilterMatch ./pdftotext "%p -" /\.pdf$/

Heads up, this will also match a file literally named ".pdf" ๐Ÿ™ˆ. So you might want something that requires a filename with more than just an extension. For example:

FileFilterMatch ./pdftotext "%p -" /.\.pdf$/

To specify more than one extension:

FileFilterMatch ./check_title.pl "%p" /\.html$/  /\.htm$/

Or a few ways to do the same thing:

FileFilterMatch ./check_title.pl %p /\.(htmlโŽชhtml)$/
FileFilterMatch ./check_title.pl %p /\.html?$/

And to ignore case:

FileFilterMatch ./check_title.pl %p /\.html?$/i

You can also put "not" in front of an expression to negate the regular expressions that follow it ๐Ÿ™ƒ. For example, to match files that do not have an extension:

FileFilterMatch ./convert "%p %P" not /\..+$/

๐Ÿ“œ Document Info ๐Ÿ“œ

$Id: SWISH-CONFIG.pod 1846 2006-10-20 20:18:30Z whmoseley $

That's the whole page, bestie ๐Ÿซถ๐Ÿ’– Version 2.4.7, dated 2009-04-04, SWISH-CONFIG(1) ๐ŸŒˆโœจ