Main Page » XQuery » Functions » Full-Text Functions

Full-Text Functions

This module extends the Full-Text features of BaseX: The index can be directly accessed, full-text results can be marked with additional elements, or the relevant parts can be extracted.

The tokenization of Japanese input is described in Full-Text Japanese.

Conventions

All functions and errors are in the http://basex.org/modules/ft namespace, to which the ft prefix is statically bound.

ft:search and ft:tokens access the full-text index of a database. All other functions operate on arbitrary strings and nodes; what they have in common is that they are aware of the language of the input, and that they tokenize, normalize and stem it accordingly.

The String Module complements this module: it measures how similar two arbitrary strings are. Its similarity functions accept the same options as ft:tokenize, and apply them to their input. See the String Module for a comparison of the two.

Full-text options that are declared in the query prolog with declare ft-option are inherited by ft:search, ft:contains, ft:tokenize and ft:normalize. Options that are supplied in the $options argument of a function call take precedence.

Database Functions

Updated: REBUILD REQUIRED. See Full-Text Index for more details.

ft:search

Updated: New stop-words option; full-text options declared in the query prolog are inherited.

Signature
ft:search(  $database  as xs:string,  $terms     as item()*,  $options   as map(*)?  := {}) as text()*
SummaryReturns all text nodes from the full-text index of the database $database that contain the specified $terms. The options used for tokenizing the input and building the full-text index will also be applied to the search terms. As an example, if the index terms have been stemmed, the search string will be stemmed as well. As these options are dictated by the index, they cannot be overwritten: case, diacritics, stemming and language will be rejected.

The $options argument can be used to control full-text processing. The following options are available (the introduction on Full-Text processing presents equivalent expressions in the XQuery Full-Text notation):

optiondefaultdescription
modeany Determine how tokens are searched. Allowed values are any, any word, all, all words, and phrase.
wildcardsfalse() Turn wildcard querying on or off.
fuzzyfalse() Turn fuzzy querying on or off.
errors Control the maximum number of tolerated errors for fuzzy querying (see Fuzzy Querying for more details). By default, the value of the LSERROR option is used.
orderedfalse() Indicate if all tokens must occur in the order in which they are specified.
stop-words Supply a list of stop words. Search terms that occur in this list are ignored, i.e., they are treated as if they matched the input.
content Specify that the matched tokens need to occur at the beginning or end of a searched string, or need to cover the entire string. Allowed values are start, end, and entire.
scope Define the scope in which tokens must be located. The following sub options are available:
  • same: can be set to true or false. It specifies if tokens need to occur in the same or different units.
  • unit: can be sentence or paragraph. It specifies the unit for finding tokens.
window Set up a window in which all tokens must be located. The following sub options are available:
  • size: specify the size of the window in terms of units.
  • unit: can be words, sentences or paragraphs. The default is words.
distance Specify the distance in which tokens must occur. The following sub options are available:
  • min: specify the minimum distance in terms of units. The default is 0.
  • max: specify the maximum distance in terms of units. The default is .
  • unit: can be words, sentences or paragraphs. The default is words.
Errors
optionsBoth wildcards and fuzzy search have been specified as search options.
Examples
ft:search('DB', 'QUERY')
Return all text nodes of the database DB that contain the term QUERY.
ft:search('DB', ('2010', '2020'), { 'mode': 'all' })
Return all text nodes of the database DB that contain the numbers 2010 and 2020.
ft:search('db', ('A', 'B'), {
  'mode': 'all words',
  'distance': { 'max': 5, 'unit': 'words' }
})
Return text nodes that contain the terms A and B in a distance of at most 5 words.
let $terms := 'Hello Worlds'
let $fuzzy := true()
for $db in 1 to 3
let $dbname := 'DB' || $db
return ft:search($dbname, $terms, { 'fuzzy': $fuzzy })/..
Iterate over three databases and return all elements containing terms similar to Hello World in the text nodes.

ft:tokens

Updated: New fuzzy and errors options for looking up tokens with a bounded number of errors.

Signature
ft:tokens(  $database  as xs:string,  $prefix    as xs:string?  := (),  $options   as map(*)?  := {}) as element(entry)*
SummaryReturns all full-text tokens stored in the index of the database $database, along with their numbers of occurrences in the @count attribute. If $prefix is specified, the returned nodes will be refined to the strings starting with that prefix. The prefix will be tokenized according to the full-text used for creating the index. The following $options are available:
optiondefaultdescription
fuzzyfalse() Turn fuzzy lookup on or off. If enabled, $prefix is matched as a whole word, and all tokens within the maximum number of errors are returned (see Fuzzy Querying). As the index groups its tokens by length, only the entries that are long enough to yield a distance within the limit are inspected. The lookup is still considerably more expensive than a prefix lookup, which is resolved with a binary search.
errors The maximum number of errors that are tolerated for fuzzy lookup. By default, the value of the LSERROR option is used. If the value is negative, the number of errors is derived from the length of the prefix.

The returned vocabulary is a good input for the similarity functions of the String Module: it allows you to detect spelling and OCR variants across an entire corpus, and the @count attribute indicates which variant occurs most frequently.

Examples
let $term := ft:tokenize('Exercises')
return number(ft:tokens('db', $term)[. = $term]/@count)
Returns the number of occurrences for a single, specific index entry.
ft:tokens('db', 'rembrandt', { 'fuzzy': true(), 'errors': 2 })
Returns all index tokens that differ from rembrandt in at most 2 characters, such as rembrant or rembrand.
let $candidates := ft:tokens('db', 'rembrandt', { 'fuzzy': true(), 'errors': 2 })
return string:closest('rembrandt', $candidates, { 'limit': 3 })
Retrieves the spelling variants of a name from the index, and ranks them by their similarity with string:closest.

Highlighting

ft:mark

Updated: Constructed nodes are accepted; the name of the marker element must be an NCName.

Signature
ft:mark(  $nodes  as node()*,  $name   as xs:string?  := ()) as node()*
SummaryPuts a marker element around the resulting $nodes of a full-text request. The default name of the marker element is mark. An alternative name can be chosen via the optional $name argument, which must be an NCName. Please note that the full-text expression that computes the token positions must be specified as argument of the ft:mark() function, as all position information is lost in subsequent processing steps. You may need to specify more than one full-text expression if you want to use the function in a FLWOR expression, as shown in Example 2. Results can only be highlighted if the string value of the tested node is supplied by a single text node, see Mixed Content.
Examples
ft:mark(db:get('DB')//*[text() contains text 'hello'])
Returns <XML><mark>hello</mark> world</XML>, if one text node of the database DB has the value "hello world".
let $start := 1
let $end   := 10
let $term  := 'welcome'
let $test  := fn($node) { $node/text() contains text { $term } }
for $ft in (db:get('DB')//*[$test(.)])[position() = $start to $end]
return ft:mark($ft[$test(.)])
Iterates over the first ten full-text results and marks the results in a second expression.
ft:mark(<xml>hello world</xml>[text() contains text 'world'], 'b')
Result: <xml>hello <b>world</b></xml>

ft:extract

Updated: Constructed nodes are accepted; the name of the marker element must be an NCName.

Signature
ft:extract(  $nodes   as node()*,  $name    as xs:string?  := (),  $length  as xs:integer?  := ()) as node()*
SummaryExtracts and returns relevant parts of full-text results. It puts a marker element around the resulting $nodes of a full-text index request and chops irrelevant sections of the result. The default element name of the marker element is mark. An alternative element name can be chosen via the optional $name argument, which must be an NCName. The default length of the returned text is 150 characters. An alternative length can be specified via the optional $length argument. Note that the effective text length may differ from the specified length due to formatting and readability issues. For more details on this function, please have a look at ft:mark.
Examples
ft:extract(db:get('DB')//*[text() contains text 'hello'], 'b', 1)
Returns <XML>...<b>hello</b>...<XML> if a text node of the database DB contains the string hello world.

Tokenization

Updated: Letters that denote multiple characters are expanded (ßss, æae, …).

ft:tokenize

Signature
ft:tokenize(  $value    as xs:string?,  $options  as map(*)?  := {}) as xs:string*
SummaryTokenizes the given string $value, using the current default full-text options or the $options specified as second argument, and returns a sequence with the tokenized string. The following options are available:
optiondefaultdescription
caseinsensitive Determine how upper/lower case is processed. Allowed values are insensitive, sensitive, upper and lower.
diacriticsinsensitive Determine how diacritical characters are processed. Allowed values are insensitive and sensitive.
stemmingfalse() Determine how tokens are stemmed.
languageen Determine the input language. This option is relevant for stemming tokens. Arbitrary language codes are accepted.
Examples
ft:tokenize('No Doubt')
Returns the two strings no and doubt.
ft:tokenize('École', { 'diacritics': 'sensitive' })
Returns the string école.
declare ft-option using stemming; ft:tokenize('GIFTS')
Returns a single string gift.
ft:tokenize("Vincent van Gogh's Sunflowers (1888)")
Result: 'vincent', 'van', 'gogh', 's', 'sunflowers', '1888'. Punctuation, apostrophes and brackets are dropped. The token functions of the String Module split their input on whitespace, unless these options are supplied to them.

ft:normalize

Signature
ft:normalize(  $value    as xs:string?,  $options  as map(*)?  := {}) as xs:string
SummaryNormalizes the given string $value, using the current default full-text options or the $options specified as second argument. The function accepts the same arguments as ft:tokenize; special characters and separators will be preserved. Case and diacritics are folded, including letters that cannot be decomposed, such as ł, đ, ı and ø. Characters that denote more than a single letter are expanded: ß and become ss, the ligatures æ, œ, ij and become ae, oe, ij and fi, and þ becomes th. Characters that merely carry a modifier are reduced to their base letter instead (ø becomes o, ł becomes l). The rules follow those of Lucene’s ASCIIFoldingFilter, so that tokens are largely interchangeable with other full-text engines. Note that the folding is designed for matching, not for display: it is not a transliteration, and ø is not rewritten to oe.
Examples
ft:normalize('Häuser am Meer', { 'case': 'sensitive' })
Returns the string Hauser am Meer.
ft:normalize('Rübens Ærø Łódź straße Đurađ ıstanbul')
Result: 'rubens aero lodz strasse durad istanbul'

General Functions

ft:contains

Updated: New stop-words and occurs options; full-text options declared in the query prolog are inherited.

Signature
ft:contains(  $input    as item()*,  $terms    as item()*,  $options  as map(*)?  := {}) as xs:boolean
SummaryChecks if the specified $input items contain the specified $terms. The function does the same as the Full-Text expression contains text, but options can be specified more dynamically. The $options are the same as for ft:search, plus the following ones:
optiondefaultdescription
caseinsensitive Determine how upper/lower case is processed. Allowed values are insensitive, sensitive, upper and lower.
diacriticsinsensitive Determine how diacritical characters are processed. Allowed values are insensitive and sensitive.
stemmingfalse() Determine how tokens are stemmed.
languageen Determine the input language. This option is relevant for stemming tokens. Arbitrary language codes are accepted.
occurs Specify how often the terms must occur in the input. The following sub options are available:
  • min: specify the minimum number of occurrences. The default is 0.
  • max: specify the maximum number of occurrences. The default is .
Errors
optionsBoth wildcards and fuzzy search have been specified as search options.
Examples
ft:contains('John Doe', ('jack', 'john'), { 'mode': 'any' })
Checks if jack or john occurs in the input string John Doe.
for $s in (true(), false())
return ft:contains('Häuser', 'Haus', { 'stemming': $s, 'language':'de' })
Calls the function with stemming turned on and off.
ft:contains('to be or not to be', 'be', { 'occurs': { 'min': 2 } })
Checks if be occurs at least twice in the input.
ft:contains('sunflowers', 'the sunflowers',
  { 'mode': 'all words', 'stop-words': 'the' })
Result: true. The search term the is ignored, and only sunflowers needs to be found.

ft:count

Updated: Constructed nodes are accepted.

Signature
ft:count(  $nodes  as node()*) as xs:integer
SummaryReturns the number of occurrences of the search terms specified in a full-text expression.
Examples
ft:count(//*[text() contains text 'QUERY'])
Returns the xs:integer value 2 if a document contains two occurrences of the string QUERY.

ft:score

Signature
ft:score(  $input  as item()*) as xs:double*
SummaryReturns the score values (0.0 - 1.0) that have been attached to the specified items. 0 is returned if no score was attached.
Examples
ft:score('a' contains text 'a')
Returns the xs:double value 1.

ft:thesaurus

Signature
ft:thesaurus(  $node     as node(),  $term     as xs:string,  $options  as map(*)?  := {}) as xs:string*
SummaryLooks up a $term in a Thesaurus Structure supplied by $node. The following $options are available:
optiondefaultdescription
relationship The relationship between terms. By default, terms of all relationships are returned.
levels The maximum number of levels to traverse. By default, the number of levels is unlimited.
Examples
ft:thesaurus(
  <thesaurus>
    <entry>
      <term>happy</term>
      <synonym>
        <term>lucky</term>
        <relationship>RT</relationship>
      </synonym>
    </entry>
  </thesaurus>,
  'happy'
)
Result: 'lucky', 'happy'

Errors

CodeDescription
optionsBoth wildcards and fuzzy search have been specified as search options.

Changelog

Version 13.0Version 9.6Version 9.1Version 9.0
  • Updated: error codes updated; errors now use the module namespace
Version 8.0Version 7.8Version 7.7
  • Updated: the functions no longer accept database nodes as reference. Instead, the name of a database must now be specified.
Version 7.2
  • Updated: ft:search (second argument generalized, third parameter added)
Version 7.1

⚡Generated with XQuery