Please refer to the errata for this document, which may include some normative corrections.
See also translations.
This document is also available in these non-normative formats: XML and Changes since Candidate Recommendation.
Copyright © 2011 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C liability, trademark and document use rules apply.
This document defines the syntax and formal semantics of XQuery and XPath Full Text 1.0, which is a language that extends XQuery 1.0 [XQuery 1.0: An XML Query Language (Second Edition)] and XPath 2.0 [XML Path Language (XPath) 2.0 (Second Edition)] with full-text search capabilities.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
This is a Recommendation of the W3C. It was jointly developed by the W3C XML Query Working Group and the W3C XSL Working Group, each of which is part of the XML Activity.
This document incorporates minor changes made against the Proposed Recommendation of 25 January 2011. Changes to this document since the Proposed Recommendation are detailed in J Change Log. A Java applet that parses XQuery and XPath Full Text 1.0 expressions is available at http://www.w3.org/2010/02/qt-applets/xquery10-fulltext/.
A Test Suite has been created for this document. Implementors are encouraged to run this test suite and report their results. The Test Suite can be found at http://dev.w3.org/cvsweb/2007/xpath-full-text-10-test-suite/. An implementation report is available at http://dev.w3.org/2007/xpath-full-text-10-test-suite/PublicPagesStagingArea/ReportedResults/XQFTTSReport.html.
No substantive changes have been made to this specification since its publication as a Proposed Recommendation.
Please report errors in this document using W3C's public Bugzilla system (instructions can be found at http://www.w3.org/XML/2005/04/qt-bugzilla). If access to that system is not feasible, you may send your comments to the W3C XSLT/XPath/XQuery public comments mailing list<EMAIL_ADDRESS>It will be very helpful if you include the string “[FT]” in the subject line of your report, whether made in Bugzilla or in email. Please use multiple Bugzilla entries (or, if necessary, multiple email messages) if you have more than one comment to make. Archives of the comments and responses are available at http://lists.w3.org/Archives/Public/public-qt-comments/.
This document has been reviewed by W3C Members, by software developers, and by other W3C groups and interested parties, and is endorsed by the Director as a W3C Recommendation. It is a stable document and may be used as reference material or cited from another document. W3C's role in making the Recommendation is to draw attention to the specification and to promote its widespread deployment. This enhances the functionality and interoperability of the Web.
This document was produced by groups operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the XML Query Working Group and also maintains a public list of any patent disclosures made in connection with the deliverables of the XSL Working Group; those pages also include instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
1 Introduction
1.1 Full-Text
Search and XML
1.2 Organization of this document
1.3 A word
about namespaces
2 Full-Text Extensions to XQuery and
XPath
2.1 Processing
Model
2.2 Full-Text Contains Expression
2.2.1 Description
2.2.2 Examples
2.3 Score Variables
2.3.1 Using Weights Within a Scored
FTContainsExpr
2.4 Extensions to the Static
Context
3 Full-Text Selections
3.1 Primary Full-Text
Selections
3.1.1 Weights
3.2 Search Tokens and
Phrases
3.3 Cardinality
Selection
3.4 Match
Options
3.4.1 Language Option
3.4.2 Wildcard Option
3.4.3 Thesaurus Option
3.4.4 Stemming Option
3.4.5 Case Option
3.4.6 Diacritics Option
3.4.7 Stop Word Option
3.4.8 Extension Option
3.5 Logical
Full-Text Operators
3.5.1 Or-Selection
3.5.2 And-Selection
3.5.3 Mild-Not Selection
3.5.4 Not-Selection
3.6 Positional
Filters
3.6.1 Ordered Selection
3.6.2 Window Selection
3.6.3 Distance Selection
3.6.4 Scope Selection
3.6.5 Anchoring Selection
3.7 Ignore
Option
3.8 Extension Selections
4 Semantics
4.1 Tokenization
4.1.1 Examples
4.1.2 Representations of Tokenized Text
and Matching
4.2 Evaluation of FTSelections
4.2.1 AllMatches
<IP_ADDRESS>
Formal Model
<IP_ADDRESS>
Examples
<IP_ADDRESS>
XML representation
4.2.2 XML Representation
4.2.3 The evaluate function
4.2.4 FTWords
4.2.5 Match Options Semantics
<IP_ADDRESS>
Types
<IP_ADDRESS>
High-Level Semantics
<IP_ADDRESS>
Formal Semantics
Functions
<IP_ADDRESS>
FTCaseOption
<IP_ADDRESS>
FTDiacriticsOption
<IP_ADDRESS>
FTStemOption
<IP_ADDRESS>
FTThesaurusOption
<IP_ADDRESS>
FTStopWordOption
<IP_ADDRESS>
FTLanguageOption
<IP_ADDRESS>
FTWildCardOption
4.2.6 Full-Text Operators Semantics
<IP_ADDRESS>
FTOr
<IP_ADDRESS>
FTAnd
<IP_ADDRESS>
FTUnaryNot
<IP_ADDRESS>
FTMildNot
<IP_ADDRESS>
FTOrder
<IP_ADDRESS>
FTScope
<IP_ADDRESS>
FTContent
<IP_ADDRESS>
FTWindow
<IP_ADDRESS>
FTDistance
<IP_ADDRESS>
FTTimes
4.3 FTContainsExpr
4.4 Scoring
4.5 Example
5 Conformance
5.1 Minimal Conformance
5.2 Optional Features
5.2.1 FTMildNot Operator
5.2.2 FTUnaryNot Operator
5.2.3 FTUnit and FTBigUnit
5.2.4 FTOrder Operator
5.2.5 FTScope Operator
5.2.6 FTWindow Operator
5.2.7 FTDistance Operator
5.2.8 FTTimes Operator
5.2.9 FTContent Operator
5.2.10 FTCaseOption
5.2.11 FTStopWordOption
5.2.12 FTLanguageOption
5.2.13 FTIgnoreOption
5.2.14 Scoring
5.2.15 Weights
6 XQueryX
Conformance
A EBNF for XQuery 1.0 Grammar
with Full Text extensions
A.1 Terminal
Symbols
B EBNF for XPath 2.0 Grammar with
Full-Text extensions
B.1 Terminal Symbols
C Static Context
Components
D Error Conditions
E XML Syntax (XQueryX) for XQuery and
XPath Full Text 1.0
E.1 XQueryX representation of XQuery and
XPath Full Text 1.0
E.2 XQueryX stylesheet for XQuery and
XPath Full Text 1.0
E.3 XQueryX for XQuery and XPath Full
Text 1.0 example
E.3.1 Example
E.3.1.1
XQuery solution in XQuery and
XPath Full Text 1.0 Use Cases:
E.3.1.2
A Solution in Full Text
XQueryX:
E.3.1.3
Transformation of Full
Text XQueryX Solution into XQuery Full Text
F References
F.1 Normative References
F.2 Non-normative References
G Acknowledgements
(Non-Normative)
H Glossary (Non-Normative)
I Checklist of Implementation-Defined
Features (Non-Normative)
J Change Log
(Non-Normative)
This document defines the language and the formal semantics of XQuery and XPath Full Text 1.0. This language is designed to meet the requirements identified in W3C XQuery and XPath Full Text Requirements [XQuery and XPath Full Text 1.0 Requirements] and to support the queries in the W3C XQuery and XPath Full Text Use Cases [XQuery and XPath Full Text 1.0 Use Cases].
In this document, examples and material labeled as "Note" are provided for explanatory purposes and are not normative.
XQuery and XPath Full Text 1.0 extends the syntax and semantics of XQuery 1.0 and XPath 2.0.
Additionally, this document defines an XML syntax for XQuery and XPath Full Text 1.0. The most recent versions of the two XQueryX XML Schemas and the XQueryX XSLT stylesheet for XQuery and XPath Full Text 1.0 are available at http://www.w3.org/2007/xpath-full-text/xpath-full-text-10-xqueryx.xsd, http://www.w3.org/2007/xpath-full-text/xpath-full-text-10-xqueryx-ftmatchoption-extensions.xsd, and http://www.w3.org/2007/xpath-full-text/xpath-full-text-10-xqueryx.xsl, respectively.
As XML becomes mainstream, users expect to be able to search their XML documents. This requires a standard way to do full-text search, as well as structured searches, against XML documents. A similar requirement for full-text search led ISO to define the SQL/MM-FT [SQL/MM] standard. SQL/MM-FT defines extensions to SQL to express full-text searches providing functionality similar to that defined in this full-text language extension to XQuery 1.0 and XPath 2.0.
XML documents may contain highly structured data (fixed schemas, known types such as numbers, dates), semi-structured data (flexible schemas and types), markup data (text with embedded tags), and unstructured data (untagged free-flowing text). Where a document contains unstructured or semi-structured data, it is important to be able to search using Information Retrieval techniques such as scoring and weighting.
Full-text search is different from substring search in many ways:
A full-text search searches for tokens and phrases rather than substrings. A substring search for news items that contain the string "lease" will return a news item that contains "Foobar Corporation releases version 20.9 ...". A full-text search for the token "lease" will not.
There is an expectation that a full-text search will support language-based searches which substring search cannot. An example of a language-based search is "find me all the news items that contain a token with the same linguistic stem as 'mouse'" (finds "mouse" and "mice"). Another example based on token proximity is "find me all the news items that contain the tokens 'XML' and 'Query' allowing up to 3 intervening tokens".
Full-text search must address the vagaries and nuances of language. Search results are often of varying usefulness. When you search a web site for cameras that cost less than $100, this is an exact search. There is a set of cameras that matches this search, and a set that does not. Similarly, when you do a string search across news items for "mouse", there is only 1 expected result set. When you do a full-text search for all the news items that contain the token "mouse", you probably expect to find news items containing the token "mice", and possibly "rodents", or possibly "computers". Not all results are equal. Some results are more "mousey" than others. Because full-text search may be inexact, we have the notion of score or relevance. We generally expect to see the most relevant results at the top of the results list.
Note:
As XQuery and XPath evolve, they may apply the notion of score to querying structured data. For example, when making travel plans or shopping for cameras, it is sometimes useful to get an ordered list of near matches in addition to exact matches. If XQuery and XPath define a generalized inexact match, we expect XQuery and XPath to utilize the scoring framework provided by XQuery and XPath Full Text 1.0.
[Definition: Full-text queries are performed on tokens and phrases. Tokens and phrases are produced via tokenization.] Informally, tokenization breaks a character string into a sequence of tokens, units of punctuation, and spaces.
Tokenization, in general terms, is the process of converting a text string into smaller units that are used in query processing. Those units, called tokens, are the most basic text units that a full-text search can refer to. Full-text operators typically work on sequences of tokens found in the target text of a search. These tokens are characterized by integers that capture the relative position(s) of the token inside the string, the relative position(s) of the sentence containing the token, and the relative position(s) of the paragraph containing the token. The positions typically comprise a start and an end position.
Tokenization, including the definition of the term "tokens", SHOULD be implementation-defined. Implementations SHOULD expose the rules and sample results of tokenization as much as possible to enable users to predict and interpret the results of tokenization. Tokenization operates on the string value of an item; for element nodes this does not include the content of attribute nodes, but for attribute nodes it does. Tokenization is defined more formally in 4.1 Tokenization.
[Definition: A token is a non-empty sequence of characters returned by a tokenizer as a basic unit to be searched. Beyond that, tokens are implementation-defined.] [Definition: A phrase is an ordered sequence of any number of tokens. Beyond that, phrases are implementation-defined.]
Note:
Consecutive tokens need not be separated by either punctuation or space, and tokens may overlap.
Note:
In some natural languages, tokens and words can be used interchangeably.
[Definition: A sentence is an ordered sequence of any number of tokens. Beyond that, sentences are implementation-defined. A tokenizer is not required to support sentences.]
[Definition: A paragraph is an ordered sequence of any number of tokens. Beyond that, paragraphs are implementation-defined. A tokenizer is not required to support paragraphs.]
Some XML elements represent semantic markup, e.g., <title>. Others represent formatting markup, e.g., <b> to indicate bold. Semantic markup serves well as token boundaries. Some formatting markup serves well as token boundaries; for example, paragraphs are most commonly delimited by formatting markup. Other formatting markup may not serve well as token boundaries. Implementations are free to provide implementation-defined ways to differentiate between the markup's effect on token boundaries during tokenization. In the absence of an implementation-defined way to differentiate, element markup (start tags, end tags, and empty-element tags) creates token boundaries.
A sample tokenization is used for the examples in this document. The results might be different for other tokenizations.
Tokenization enables functions and operators that operate on a part or the root of the token (e.g., wildcards, stemming).
Tokenization enables functions and operators which work with the relative positions of tokens (e.g., proximity operators).
This specification focuses on functionality that serves all languages. It also selectively includes functionalities useful within specific families of languages. For example, searching within sentences and paragraphs is useful to many western languages and to some non-western languages, so that functionality is incorporated into this specification.
Certain aspects of language processing are described in this specification as implementation-defined or implementation-dependent.
[Definition: Implementation-defined indicates an aspect that may differ between implementations, but must be specified by the implementor for each particular implementation.]
[Definition: Implementation-dependent indicates an aspect that may differ between implementations, is not specified by this or any W3C specification, and is not required to be specified by the implementor for any particular implementation.]
This document is organized as follows. We first present a high level syntax for the XQuery and XPath Full Text 1.0 language along with some examples. Then, we present the syntax and examples of the basic primitives in the XQuery and XPath Full Text 1.0 language. This is followed by the semantics of the XQuery and XPath Full Text 1.0 language. The appendix contains a section that provides an EBNF for the XPath 2.0 Grammar with Full-Text Extensions, an EBNF for XQuery 1.0 Grammar with Full-Text Extensions, acknowledgements and a glossary.
Certain namespace prefixes are predeclared by XQuery 1.0 and, by implication, by this specification, and bound to fixed namespace URIs. These namespace prefixes are as follows:
xml = http://www.w3.org/XML/1998/namespace
xs = http://www.w3.org/2001/XMLSchema
xsi = http://www.w3.org/2001/XMLSchema-instance
fn = http://www.w3.org/2005/xpath-functions
local =
http://www.w3.org/2005/xquery-local-functions
In addition to the prefixes in the above list, this document
uses the prefix err
to represent the namespace URI
http://www.w3.org/2005/xqt-errors
, This namespace
prefix is not predeclared and its use in this document is not
normative. Error codes that are not defined in this document are
defined in other XQuery 1.0 and XPath 2.0 specifications,
particularly [XML Path Language (XPath) 2.0
(Second Edition)] and [XQuery 1.0
and XPath 2.0 Functions and Operators (Second Edition)].
Finally, this document uses the prefix fts
to
represent a namespace containing a number of functions used in this
document to describe the semantics of XQuery and XPath Full Text
functions. There is no requirement that these functions be
implemented, therefore no URI is associated with that prefix.
XQuery and XPath Full Text 1.0 extends the languages of XQuery 1.0 and XPath 2.0 in three ways. It:
Adds a new expression called FTContainsExpr;
Enhances the syntax of FLWOR expressions in XQuery 1.0 and
for
expressions in XPath 2.0 with optional score
variables; and
Adds static context declarations for full-text match options to the query prolog.
Additionally, it extends the data model and processing models in various ways.
A full-text contains expression (2.2 Full-Text Contains Expression) is composed of several parts:
An XPath 2.0 or XQuery 1.0 expression (RangeExpr) that specifies the sequence of items to be searched. [Definition: Those items are called the search context.]
The full-text selection to be applied (3 Full-Text Selections). Full-text selections are, syntactically and semantically, fully composable and contain:
Required:
Tokens and phrases for which a search is performed (3.2 Search Tokens and Phrases).
Optional:
Match options, such as indicators for case sensitivity and stop words (3.4 Match Options);
Boolean full-text operators, that compose a full-text selection from simpler full-text selections (3.5 Logical Full-Text Operators);
Other full-text operators that are constraints on the positions of matches, such as indicators for distance between tokens and for the cardinality of matches (3.6 Positional Filters and 3.3 Cardinality Selection); and
The weighting information. Each individual search term in a full-text selection may be annotated with optional weight information. This information may be used during the evaluation of the full-text selections to calculate scoring, information that quantifies the relevance of the result to the given search criteria.
An optional XPath 2.0 or XQuery 1.0 expression (UnionExpr) that specifies the set of nodes, descendents of the RangeExp, whose contents must be ignored for the purpose of determining a match during the search (3.7 Ignore Option).
The results of the evaluation of the full-text selection operators are instances of the AllMatches model, which complements the XQuery Data Model (XDM) for processing full-text queries. An AllMatches instance describes all possible solutions to the full-text query for a given search context item. Each solution is described by a Match instance. A Match instance contains the tokens from the search context that must be included (described using StringInclude instances which model the positive terms) and the tokens from search context item that must be excluded (described using StringExclude instances which model the negative terms). Each negative or positive term is modeled as a tuple: the position of the query token or phrase in the full-text selection, and a TokenInfo structure that describes a set of tokens in the text string which match the query token or phrase.
Figure 1 provides a schematic overview of the XQuery and XPath Full Text 1.0 processing steps that are discussed in detail below. Some of these steps are completely outside the domain of XQuery; in Figure 1, these are depicted outside the black line that represents the boundaries of the language. The diagram only shows the central pieces of the XQuery Processing Model (see Section 2.2 Processing ModelXQ), however zooms in on the Execution Engine where the processing of the full-text extensions takes place. The full-text processing steps are labeled as FTn within the diagram and are referenced within the text.
Like all XQuery expressions, an FTContainsExpr returns an XDM Instance (see Fig. 1). With the exception of FTWords, which consumes TokenInfos, all full-text selections are closed under the AllMatches data model, i.e., their input and output are AllMatches instances. Tokenization transforms an XDM instance into TokenInfos, which ultimately get converted into AllMatches instances by the evaluation of full-text selections. Thus, the evaluation of nested full-text and XQuery expressions instances moves back and forth between these two models.
The resulting AllMatches instance obtained by the evaluation of an FTContainsExpr is converted into a Boolean value before being returned to the enclosing XPath or XQuery operation as follows. If at least one member of the disjunction contains only positive terms then value returned is true. If all members of the disjunction contain negative terms the result is false.
Weighting information, in an implementation-dependent fashion, may be used when calculating the scoring information computed and made available by FTContainsExpr to the optional score construct.
Given the components of a given full-text contains expression, the evaluation algorithm will proceed according to the following steps, also referenced in the processing model diagram as steps FTn (see Fig. 1):
Evaluate the search context expression (resulting in the sequence of search context items), the ignore option, if any (resulting in the set of ignored nodes), and any other XQuery/XPath exprssions nested within the full-text contains expression. (FT1)
Tokenize the query string(s). (FT2.1)
For each search context item:
Delete the ignored nodes from the search context item.
Tokenize the result of the previous step. This produces a sequence of tokens. (FT2.2) Note that implementations may (as an optimization) perform tokenization as part of the External Processing that is described in the XQuery Processing Model, when an XML document is parsed into an Infoset/PSVI and ultimately into a XQuery Data Model instance.
Evaluate the FTSelection against the tokens of the search context. (FT3, FT4)
Convert the topmost AllMatches instances into a Boolean value. (FT5)
The additional scoring information (also part of FT5) that is produced by the evaluation of the full-text contains expression is implementation-dependent and is not specified in this document. The scoring information is made available at the same time the Boolean value is returned.
(A more detailed version of the above procedure appears in Section 4.3 FTContainsExpr.)
Section 3 Full-Text Selections describes the syntax and the informal semantics of full-text operators. Their formal semantics as well as the formal definition of the AllMatches data model are given in Section 4 Semantics.
[Definition: A full-text contains expression is a expression that evaluates a sequence of items against a full-text selection. ]
As a syntactic construct, a full-text contains expression (grammar symbol: FTContainsExpr) behaves like a comparison expression (see Section 3.5.2 General ComparisonsXQ). This grammar rule introduces FTContainsExpr.
| [50] | ComparisonExpr |
::= | FTContainsExpr
( (ValueComp |
A full-text contains expression may be used anywhere a
ComparisonExpr may be used. The contains text
operator
has higher precedence than other comparison operators, so the
results of contains text
expressions may be compared
without enclosing them in parentheses.
| [51] | FTContainsExpr |
::= | RangeExpr (
"contains" "text" FTSelection FTIgnoreOption? )? |
A full-text contains expression returns a Boolean value. It returns true if there is some item returned by the RangeExpr that, after tokenization, matches the full-text selection FTSelection. Since tokenization includes tokens derived only from the string values of items, a full-text contains expression searches the text of element nodes and of their descendant elements. The string value of other kinds of nodes, such as attributes and comments, will not be included unless the attribute or comment node itself is the target (RangeExpr) of the full-text contains expression. See Section 3 Full-Text Selections for more details. For the purpose of determining a match, certain descendants of nodes (identified by FTIgnoreOption) in the RangeExpr may be ignored, as specified in Section 3.7 Ignore Option.
An XQuery and XPath Full Text 1.0 processor SHOULD try to use the information available in xml:lang for processing of collations, as well as the various match options defined in Section 3.4 Match Options.
The following example in XQuery 1.0 Full Text returns the author
of each book with a title containing a token with the same root as
dog
and the token cat
.
for $b in /books/book where $b/title contains text ("dog" using stemming) ftand "cat" return $b/author
The same example in XPath 2.0 Full Text is written as:
/books/book[title contains text ("dog" using stemming) ftand "cat"]/author
In the next example a ComparisonExpr is combined with an
FTContainsExpr using the logical XQuery operator and
.
The query selects books that have a price of less than 50 and a
title which contains a token with the same root as
train
:
/books/book[price < 50 and title contains text ("train" using stemming)]
The following example shows the combination of two
contains text
expressions the results of which are
compared using the not-equals operator. The query selects books
where either the title contains the token dog
and the
token cat
and the content does not contain a token
with the same root as train
, or where the title fails
to have one of the matching tokens but the content does:
/books/book[title contains text "dog" ftand "cat" ne content contains text ("train" using stemming)]
Besides specifying a match of a full-text query as a Boolean condition, full-text query applications typically also have the ability to associate scores with the results. [Definition: The score of a full-text query result expresses its relevance to the search conditions.]
XQuery and XPath Full Text 1.0 extends the languages of XQuery
1.0 and XPath 2.0 further by adding optional score
variables to the for
and let
clauses of
FLWOR expressions.
The production for the extended for
clause in
XQuery 1.0 follows.
| [35] | ForClause |
::= | "for" "$" VarName
TypeDeclaration?
PositionalVar? FTScoreVar? "in" ExprSingle ("," "$" VarName TypeDeclaration? PositionalVar? FTScoreVar? "in" ExprSingle)* |
| [37] | FTScoreVar |
::= | "score" "$" VarName |
In XPath 2.0, the SimpleForClause is extended similarly.
When a score
variable is present in a
for
clause the evaluation of the expression following
the in
keyword not only needs to determine the result
sequence of the expression, i.e., the sequence of items which are
iteratively bound to the for
variable. It must also
determine in each iteration the relevance "score" value of the
current item and bind the score
variable to that
value.
The scope of a score variable bound in a for or let clause comprises all subexpressions of the containing FLWOR expression that appear after the variable binding. The scope does not include the expression to which the variable is bound. The for and let clauses of a given FLWOR expression may bind the same score variable name more than once. In this case, each new binding occludes the previous one, which becomes inaccessible in the remainder of the FLWOR expression.
The expanded QName of a score variable bound in a for clause must be distinct from both the expanded QName of the variable with which it is associated and the expanded QName of any positional variable with which it is associated [err:XQST0089]XQ.
The semantics of scoring and how it relates to second-order functions is discussed in Section 4.4 Scoring.
In the following example book
elements are
determined that satisfy the condition [content contains text
"web site" ftand "usability" and .//chapter/title contains text
"testing"]
. The scores assigned to the book
elements are returned.
for $b score $s in /books/book[content contains text "web site" ftand "usability" and .//chapter/title contains text "testing"] return $s
The example above is also a valid example of the XPath 2.0 extension.
Scores are typically used to order results, as in the following, more complete example.
for $b score $s in /books/book[content contains text "web site" ftand "usability"] where $s > 0.5 order by $s descending return <result> <title> {$b//title} </title> <score> {$s} </score> </result>
Note that the score variable gets one score value for
each item in the value of the expression after the in
keyword, regardless of the number of FTContainsExprs in that
expression. In the following example, two separate full-text
contains expressions are used to select the matching paragraphs.
There is still just one score for each para
returned.
The highest scoring paragraphs will be returned first:
for $p score $s in //book[title contains text "software"]/para[. contains text "usability"] order by $s descending return $p
The following more elaborate example uses multiple score variables to return the matching paragraphs ordered so that those from the highest scoring books precede those from the lowest scoring books, where the highest scoring paragraphs of each book are returned before the lower scoring paragraphs of that book:
for $b score $score1 in //book[title contains text "software"] order by $score1 descending return for $p score $score2 in $b/para[. contains text "usability"] order by $score2 descending return $p
The score
variable is bound to a value which
reflects the relevance of the match criteria in the full-text
selections to the items returned by the respective RangeExprs. The
calculation of relevance is implementation-dependent,
but score evaluation must follow these rules:
Score values are of type xs:double
in the range [0,
1].
For score values greater than 0, a higher score must imply a higher degree of relevance
Similarly to their use in a for
clause, score
variables may be specified in a let
clause. A score
variable in a let
clause is also bound to the score of
the expression evaluation, but in the let
clause one
score is determined for the complete result.
The production for the extended let
clause
follows.
| [38] | LetClause |
::= | "let" (("$" VarName
TypeDeclaration?) |
FTScoreVar) ":=" ExprSingle ("," (("$" VarName TypeDeclaration?) | FTScoreVar) ":=" ExprSingle)* |
When using the score option in a for
clause the
expression following the in
keyword has the dual
purpose of filtering, i.e., driving the iteration, and determining
the scores. It is possible to separately specify expressions for
filtering and scoring by combining a simple for
clause
with a let
clause that uses scoring. The following is
an example of this.
for $b in /books/book[.//chapter/title contains text "testing"] let score $s := $b/content contains text "web site" ftand "usability" order by $s descending return <result score="{$s}">{$b}</result>
This example returns book
elements with chapter
titles that contain "testing". Along with the book
elements scores are returned. These scores, however, reflect
whether the book content contains "web site" and "usability".
Note that it is not a requirement of the score of an
FTContainsExpr to be 0, if the expression evaluates to false, nor
to be non-zero, if the expression evaluates to true. Hence, in the
example above it is not possible to infer the Boolean value of the
FTContainsExpr in the let
clause from the calculated
score of a returned result
element. For instance, an
implementation may want to assign a non-zero score to a book that
contained "web site", but not "usability", as this may be
considered more relevant than a book that does not contain "web
site" or "usability".
The expression ExprSingle associated with the score variable is passed to the scoring algorithm. The scoring algorithm calculates the score value based on the passed expression (not on the value returned by evaluating the expression). The set of expressions supported by the scoring algorithm is implementation-defined. If an expression not supported by the scoring algorithm is passed to the scoring algorithm, the result is implementation-defined.
The use of score
variables introduces a
second-order aspect to the evaluation of expressions which cannot
be emulated by (first-order) XQuery functions. Consider the
following replacement of the clause let score $s :=
FTContainsExpr
let $s := score(FTContainsExpr)
where a function score
is applied to some
FTContainsExpr. If the function score
were
first-order, it would only be applied to the result of the
evaluation of its argument, which is one of the Boolean constants
true
or false
. Hence, there would be at
most two possible values such a score
function would
be able to return and no further differentiation would be
possible.
[Definition: Scoring may be influenced by adding weight declarations to search tokens, phrases, and expressions.] Weight declarations are introduced syntactically in the FTPrimaryWithOptions production, described in Section 3.1.1 Weights.
The weights assigned are not related to any absolute standard, but typically have a relationship to other weights within the same FTContains expression.
The effect of weights on the resulting score is implementation-dependent. However, scoring algorithms MUST conform to the constraint that when no explicit weight is specified, the default weight is 1.0.
The following example illustrates how different weights can be used for different search terms.
for $b in /books/book let score $s := $b/content contains text ("web site" weight {0.5}) ftand ("usability" weight {2}) return <result score="{$s}">{$b}</result>
The XQuery Static Context is extended with a component for each full-text match option group. The settings of these components can be changed by using the following declaration syntax in the Prolog.
| [6] | Prolog |
::= | ((DefaultNamespaceDecl |
Setter | NamespaceDecl | Import | FTOptionDecl) Separator)* ((VarDecl | FunctionDecl | OptionDecl) Separator)* |
| [24] | FTOptionDecl |
::= | "declare" "ft-option" FTMatchOptions |
Match options modify the match semantics of full-text expressions. They are described in detail in Section 3.4 Match Options. When a match option is specified explicitly in a full-text expression, it overrides the setting of the respective component in the static context.
This section describes the full-text selections which contain the full-text operators in a full-text contains expression (FTContainsExpr), as well as the match options which modify the matching semantics of the full-text selections. In the following, the syntax for each type of full-text selection is given together with an informal statement of its meaning.
[Definition: A full-text selection specifies the conditions of a full-text search. ]
| [144] | FTSelection |
::= | FTOr FTPosFilter* |
As shown in the grammar, a full-text selection consists of search conditions possibly involving logical operators (FTOr), followed by an arbitrary number of positional filters (FTPosFilter).
The syntax and semantics of the individual full-text selection operators follow.
This XML document is the source document for examples in this section.
<books> <book number="1"> <title shortTitle="Improving Web Site Usability">Improving the Usability of a Web Site Through Expert Reviews and Usability Testing</title> <author>Millicent Marigold</author> <author>Montana Marigold</author> <editor>Véra Tudor-Medina</editor> <content> <p>The usability of a Web site is how well the site supports the users in achieving specified goals. A Web site should facilitate learning, and enable efficient and effective task completion, while propagating few errors. </p> <note>This book has been approved by the Web Site Users Association. </note> </content> </book> </books>
Tokenization is implementation-defined. A sample
tokenization is used for the examples in this section. This sample
tokenization uses white space, punctuation and XML tags as
word-breakers
,
periods followed by a space as sentence boundaries, and
<p>
for paragraph boundaries.
The
first sentence and paragraph start at the beginning of the
document, and the last sentence and paragraph end at the end of the
document. The results may be different for other
tokenizations.
The first five tokens in this example using the sample tokenization would be "Improving", "the", "usability", "of", and "a".
Unless stated otherwise, the results assume a case-insensitive match.
| [151] | FTPrimary |
::= | (FTWords FTTimes?) | ("(" FTSelection ")") | FTExtensionSelection |
[Definition: A primary full-text selection is the basic form of a full-text selection. It specifies tokens and phrases as search conditions (FTWords), optionally followed by a cardinality constraint (FTTimes). An FTSelection in parentheses and the FTExtensionSelection are also a primary full-text selections.]
| [150] | FTPrimaryWithOptions |
::= | FTPrimary FTMatchOptions? FTWeight? |
| [145] | FTWeight |
::= | "weight" "{" Expr
"}" |
As shown in the grammar, a full-text primary selection may be
optionally followed by match options (which are discussed in
3.4 Match Options) and by a
"weight" value that is specified using an expression enclosed in
braces. The Expr is evaluated as if it were an argument to a
function with an expected type xs:double
. The weight
MUST have an absolute value
between 0.0 and 1000.0 inclusive. If the absolute value of the
weight is greater than 1000.0, an error is raised: [err:FTDY0016].
Note:
As a consequence of the flexibility given to implementations under Section 2.3.4 Errors and OptimizationXQ, it is possible that evaluation of weight declarations in an FTContainsExpr for which no scores are evaluated may be skipped by the implementation and errors with them may go unreported.
| [152] | FTWords |
::= | FTWordsValue
FTAnyallOption? |
| [153] | FTWordsValue |
::= | StringLiteral
| ("{" Expr "}") |
| [155] | FTAnyallOption |
::= | ("any" "word"?) | ("all" "words"?) | "phrase" |
FTWords finds matches that contain the specified tokens and phrases.
FTWords consists of two parts: a mandatory FTWordsValue part and an optional FTAnyallOption part. FTWordsValue specifies the tokens and phrases that must be contained in the matches. FTAnyallOption specifies how containment is checked.
In general, the tokens and phrases in FTWordsValue are specified using a nested XQuery expression. To simplify notation, the enclosing braces may be omitted if FTWordsValue consists of a single string literal.
The following rules specify how an FTWordsValue matches tokens and
phrases. First, the FTWordsValue is converted to a
sequence of strings as though it were an argument to a function
with the expected type of xs:string*
. If the sequence
is empty, the FTWords yields no matches. Otherwise, each of those
strings is tokenized into a sequence of tokens as described in
Section 4.1 Tokenization. Then,
FTAnyallOption is
checked.
If FTAnyallOption is "any", the sequence of tokens for each string is considered as a phrase. If the sequence of tokens is empty, then the phrase contributes nothing to the set of matches for the FTWords. Otherwise, a match is found in the tokenized form of the text being searched, whenever that form contains a subsequence of tokens that corresponds to the sequence of query tokens in an implementation-defined way and that subsequence of tokens covers consecutive token positions in the tokenized text. If the value of the FTWordsValue contains more than one string, the different strings are considered to be alternatives, i.e., the search context must contain at least one of the generated phrases. Each resulting match will contain exactly one such phrase.
If FTAnyallOption is "all", the sequence of tokens for each string is considered as a phrase. If any such sequence of tokens is empty, the FTWords yields no matches. The resulting matches must contain all of the generated phrases.
If FTAnyallOption is "phrase", the tokens from all the strings are concatenated in a single sequence, which is considered as a phrase. If the sequence of tokens is empty, the FTWords yields no matches. The resulting matches must contain the generated phrase.
If FTAnyallOption is "any word", the tokens from all the strings are combined into a single set. If the set is empty, the FTWords yields no matches. The search context must contain at least one of the tokens in the set. Each resulting match will contain exactly one such token.
If FTAnyallOption is "all words", the tokens from all the strings are combined into a single set. If the set is empty, the FTWords yields no matches. The resulting matches must contain all of the tokens in the set.
If the FTWordsValue evaluates to a single string, the use of "any", "all", and "phrase" in FTAnyallOption produces the same results.
If FTAnyallOption is omitted, "any" is the default.
The following expression returns the sample book
element, because its title
element contains the token
"Expert":
//book[./title contains text "Expert"]
The following expression returns the sample book
element, because its title
element contains the phrase
"Expert Reviews":
//book[./title contains text "Expert Reviews"]
The following expression returns the sample book
element, because its title
element contains the two
tokens "Expert" and "Reviews":
//book[./title contains text {"Expert", "Reviews"} all]
The following expression returns false for our sample document,
because the p
element doesn't contain the phrase "Web
Site Usability" although it contains all of the tokens in the
phrase:
//book//p contains text "Web Site Usability"
The following expression returns book numbers of
book
elements by "Marigold" with a title about "Web
Site Usability", sorting them in descending score order:
for $book in /books/book[.//author contains text "Marigold"] let score $score := $book/title/@shortTitle contains text "Web Site Usability" where $score > 0.8 order by $score descending return $book/@number
| [156] | FTTimes |
::= | "occurs" FTRange
"times" |
[Definition: A cardinality selection consist of an FTWords followed by the FTTimes postfix operator.] A cardinality selection selects matches for which the operand FTWords is matched a specified number of times.
A cardinality selection limits the number of different matches of FTWords within the specified range. The semantics of FTRange are described in 3.6.3 Distance Selection.
In the document fragment "very very big":
The FTWords "very
big"
has 1 match consisting of the second "very" and
"big".
The FTWords {"very",
"big"} all
has 2 matches; one consisting of the first "very"
and "big", and the other containing the second "very" and
"big".
The FTWords {"very",
"big"} any
has 3 matches.
The following expression returns the example book
element's number, because the book
element contains 2
or more occurrences of "usability":
//book[. contains text "usability" occurs at least 2 times]/@number
The following expression returns the empty sequence, because
there are 3 occurrences of {"usability", "testing"}
any
in the designated title
:
//book[@number="1" and title contains text {"usability", "testing"} any occurs at most 2 times]
Full-text match options modify the matching behaviour of the primary full-text selection to which they are applied.
| [150] | FTPrimaryWithOptions |
::= | FTPrimary FTMatchOptions? FTWeight? |
| [166] | FTMatchOptions |
::= | ("using" FTMatchOption)+ |
| [167] | FTMatchOption |
::= | FTLanguageOption |
[Definition: Match options modify the set of tokens in the query, or how they are matched against tokens in the text.]
[Definition: Each of the alternatives of production FTMatchOption other than FTExtensionOption corresponds to one match option group. ] The match options from any given group are mutually exclusive, i.e., only one of these settings can be in effect, whereas match options of different groups can be combined freely.
It is a static error [err:FTST0019] if, within a single FTMatchOptions, there is more than one match option of any given match option group. For example, if the FTCaseOption "lowercase" is specified, then "uppercase" cannot also be specified as part of the same FTMatchOptions.
Although match options only take effect in the application of
FTWords, the syntax also allows
to specify match options that modify the non-primitive full-text
selection "(" FTSelection ")"
. Such a higher-level
match option provides a default for the respective match option
group for any embedded FTPrimary, just as match option declarations in the
Prolog provide default match
options for the whole query.
Match options are propagated through the query via the static
context. For each of the seven match option groups, the static
context has a component that contains one option from that group.
The seven settings are initialized by the implementation in
accordance with the table in Appendix C Static Context
Components, and are modified by any FTOptionDecls in the Prolog. The resulting settings are then
propagated unchanged to every FTContainsExpr in the module
(including those in VarDecl
s and
FunctionDecl
s, and including any that happen to be
nested within another FTContainsExpr
). At any given
FTContainsExpr
, the settings from the static context
are copied to the FTContainsExpr
's inner settings,
which are then propagated down the syntax tree. At each FTPrimaryWithOptions, the
locally specified match options (if any) overwrite the
corresponding inner setting(s). At each FTWords, the inner settings are used as
the effective match options for tokenizing the query strings and
matching them against the tokens in the text. (These inner settings
could be seen as a parallel set of components in the static
context, but Section 4 Semantics
models them as structures that get passed as parameters to various
semantic functions.)
Thus, when a match option appears in an FTSelection, it applies to the
associated FTPrimary, but not
to any FTContainsExpr
s that happen to be embedded
within that FTPrimary
. Instead, for a nested
FTContainsExpr
, the default match options are those
declared in the Prolog
or, if not declared in the
Prolog
, then supplied by the implementation's initial
values.
An FTMatchOption applies to the FTPrimary that immediately precedes it. That FTPrimary is either an FTWords (possibly qualified by an FTTimes), an FTExtensionSelection, or a parenthesized FTSelection.
[Definition: The order in which effective match options for an FTWords are applied is called the match option application order.] This order is significant because match options are not always commutative. For example, synonym(stem(word)) is not always the same as stem(synonym(word)).
The match option application order is subject to some constraints:
The Language Option must be applied first
The Stemming Option must be applied before the Case Option and the Diacritics Option
Aside from these constraints, the full order of the application of match options is implementation-defined.
More information on their semantics is given in 4.2.5 Match Options Semantics.
If no match options declarations are present in the prolog and the implementation does not define any overwriting of the static context components for the match options, the query:
/books/book/title contains text "usability"
is, assuming "de" is the implementation-defined default language, equivalent to the query:
/books/book/title contains text "usability" using language "de" using no wildcards using no thesaurus using no stemming using case insensitive using diacritics insensitive using no stop words
We describe each match option group in more detail in the following sections.
| [177] | FTLanguageOption |
::= | "language" StringLiteral |
[Definition: A language option modifies token matching by specifying the language of search tokens and phrases.]
The StringLiteral following the keyword language
designates one language. It must be castable to
xs:language
; otherwise, an error is raised: [err:XPTY0004]XP.
The "language" option influences tokenization, stemming, and stop words in an implementation-defined way. The "language" option MAY influence the behavior of other match options in an implementation-defined way.
The set of standardized language identifiers is defined in [BCP 47]. The set of valid language identifiers among the standardized set is implementation-defined. An implementation MAY choose to use private extensions introduced by a singleton 'x' for additional language identifiers, or other singletons for registered extensions as described in sec. 2.2.6 of [BCP 47]. It is implementation-defined what additional language identifiers, if any, are valid. If an invalid language identifier is specified, then the behavior is implementation-defined. If the implementation chooses to raise an error in that case, it must raise [err:FTST0009].
The default language is specified in the static context.
When an XQuery and XPath Full Text processor evaluates text in a document that is governed by an xml:lang attribute and the portion of the full-text query doing that evaluation contains an FTLanguageOption that specifies a different language from the language specified by the governing xml:lang attribute, the language-related behavior of that full-text query is implementation-defined.
This is an example where the language option is used to select the appropriate stop word list:
//book[@number="1"]/content//p contains text "salon de thé" using stop words default using language "fr"
| [178] | FTWildCardOption |
::= | "wildcards" | ("no" "wildcards") |
[Definition: A wildcard option modifies token and phrase matching by specifying whether or not wildcards are recognized in query strings.]
When the "wildcards" option is used, wildcard syntax may be included within query strings. A wildcard consists of an indicator (a period or full stop, "."), optionally followed by a qualifier. Each wildcard in a query token will match zero or more characters within a token in the text being searched, as described below. The number of characters that can be matched depends on the qualifier. The forms of wildcard syntax specified by this document are:
A single period, without any qualifiers: Matches a single arbitrary character.
A period immediately followed by a single question mark, "?": Matches either no characters or one character.
A period immediately followed by a single asterisk, "*": Matches zero or more characters.
A period immediately followed by a single plus sign, "+": Matches one or more characters.
A period immediately followed by a sequence of characters that
matches the regular expression {[0-9]+,[0-9]+}
:
Matches a number of characters, where the number is no less than
the number represented by the series of digits before the comma,
and no greater than the number represented by the series of digits
following the comma.
If a period in the query string is immediately followed by a left curly brace, but the subsequent characters do not conform to the given regular expression, then an error is raised: [err:FTDY0020].
A question mark, asterisk, plus sign, or left curly brace that is not immediately preceded by a period is not treated as a qualifier. For example, using the sample tokenization and "wildcards", the query string "wil+" does not match the search text "will" or "willlllll", but only matches the search text "wil". (The sample tokenization treats the plus sign as punctuation.)
When "wildcards" is used, any character in a query string can be "escaped" by immediately preceding it with a backslash, "\". That is, a backslash immediately followed by any character represents that character literally, preventing any special interpretation that the "wildcards" option might otherwise attach to it. In particular:
Escaping a period prevents its interpretation as a wildcard.
Escaping a question mark, asterisk, plus sign, or left curly brace ensures that it is not interpreted as a qualifier.
An escaped backslash ("\\") represents a literal backslash.
If a query string is terminated by an unescaped backslash, an error is raised: [err:FTDY0020].
Note:
A query string of the form "abc\"xyz"
does
not represent the three characters "abc" followed by a
literal double-quote followed by the three characters "xyz".
Instead, this is a malformed StringLiteral, and the processor will
report a syntax error [err:XPST0003]XP.
When the "no wildcards" option is used, no wildcards are recognized in query strings. Periods, question marks, asterisks, plus signs, left curly braces, and backslashes are always recognized as ordinary text characters.
The default is "no wildcards".
The following expression returns true, because the
p
element contains "well":
//book[@number="1"]/p contains text "w.ll" using wildcards
The following expression returns true, because the
title
element contains "site":
//book[@number="1"]/title contains text ".?site" using wildcards
The following expression returns true, because the
title
element contains "improving":
//book[@number="1"]/title contains text "improv.*" using wildcards
The following expression raises error [err:FTDY0020], because the query string uses incorrect syntax:
//book[@number="1"]/p contains text "wi.{5,7]" using wildcards
The following expression returns true, because the title contains "site":
//book[@number="1"]/title contains text "\s\i\t\e" using wildcards
The following expression returns true, because the title contains "Usability":
//book[@number="1"]/title contains text "Usab.+\\" using wildcards
(Note that "\\" represents a literal backslash, which the sample tokenization treats as punctuation.)
The following expression raises error [err:FTDY0020], because the query string ends with an unescaped backslash:
//book[@number="1"]/p contains text "will\" using wildcards
The following expression returns false, because the
p
element does not contain the phrase "w ll":
//book[@number="1"]/p contains text "w.ll" using no wildcards
(Note that, without wildcards, the sample tokenization will treat the period in "w.ll" as punctuation, thus producing "w" and "ll" as separate tokens.)
| [171] | FTThesaurusOption |
::= | ("thesaurus" (FTThesaurusID | "default")) |
| [172] | FTThesaurusID |
::= | "at" URILiteral
("relationship" StringLiteral)? (FTLiteralRange
"levels")? |
| [143] | URILiteral |
::= | StringLiteral |
| [173] | FTLiteralRange |
::= | ("exactly" IntegerLiteral) |
[Definition: A thesaurus option modifies token and phrase matching by specifying whether a thesaurus is used or not.] If thesauri are used, the thesaurus option specifies information to locate the thesauri either by default or through a URI reference. It also states the relationship to be applied and how many levels within the thesaurus to be traversed.
If the thesaurus option specifies a thesaurus with a relative URI, that relative URI is resolved to an absolute URI using the base URI in the static context and that absolute URI is used to identify the thesaurus.
If the URI specifies a thesaurus that is not found in the statically known thesauri, an error is raised [err:FTST0018].
Thesauri add related tokens and phrases to the query or change query tokens. Thus, the user may narrow, broaden, or otherwise modify the query using synonyms, hypernyms (more generic terms), etc. The search is performed as though the user has specified all related query tokens and phrases in a disjunction (FTOr).
Note:
A thesaurus may be standards-based or locally-defined. It may be a traditional thesaurus, or a taxonomy, soundex, ontology, or topic map. How the thesaurus is represented is implementation-dependent.
An FTThesaurusID may optionally contain a StringLiteral to specify the relationship sought between tokens and phrases written in the query and terms in the thesaurus. Relationships include, but are not limited to, the relationships and their abbreviations presented in [ISO 2788] and their equivalents in other languages. The set of relationships supported by an implementation is implementation-defined, but implementations SHOULD support the relationships defined in [ISO 2788]. The following list of terms have the meanings defined in [ISO 2788]. If a query specifies thesaurus relationships not supported by the thesaurus, or does not specify a relationship, the behavior is implementation-defined.
equivalence relationships (synonyms): PREFERRED TERM (USE), NONPREFERRED USED FOR TERM (UF);
hierarchical relationships: BROADER TERM (BT), NARROWER TERM (NT), BROADER TERM GENERIC (BTG), NARROWER TERM GENERIC (NTG), BROADER TERM PARTITIVE (BTP), NARROWER TERM PARTITIVE (NTP), TOP Terms (TT); and
associative relationships: RELATED TERM (RT).
An FTThesaurusID may also optionally include an FTLiteralRange to specify the number of levels to be queried in hierarchical relationships. An FTLiteralRange is a constrained form of FTRange, and specifies a (possibly empty) range of integer values according to the same rules.
Note:
For historical reasons, an implementation MAY allow an FTLiteralRange to have subexpressions more general than IntegerLiterals, and MAY even allow its subexpressions to be dynamically evaluated.
The effect of specifying a particular range of levels in an FTThesaurusID is implementation-defined. This includes cases involving empty ranges, negative levels, or levels not supported by the thesaurus.
If no levels are specified, the default is to query all levels in hierarchical relationships or to query an implementation-defined number of levels in hierarchical relationships.
The "thesaurus" option specifies that string matches include tokens that can be found in one of the specified thesauri. When "default" is used in place of a FTThesaurusID, the thesauri specified in the static context are used, which are either given by the prolog declaration for the thesaurus option, or, if no such declaration exists a system-defined default thesaurus with a system-defined relationship. The default thesaurus may be used in combination with other explicitly specified thesauri.
The "no thesaurus" option specifies that no thesaurus will be used.
The default is "no thesaurus".
The following expression returns true, because it finds a
content
element containing "task" which the thesaurus
identified as a synonym for "duty":
.//book/content contains text "duty" using thesaurus at "http://bstore1.example.com/UsabilityThesaurus.xml" relationship "UF"
The following expression returns a book
element,
because it finds a content
element containing "users",
which is a narrower term of "people":
doc("http://bstore1.example.com/full-text.xml") /books/book[./content contains text "people" using thesaurus at "http://bstore1.example.com/UsabilityThesaurus.xml" relationship "NT" at most 2 levels]
Assuming the thesaurus available at URL
"http://bstore1.example.com/UsabilitySoundex.xml" contains soundex
capabilities, the following query returns a book
element containing "Marigold" which sounds like "Merrygould":
doc("http://bstore1.example.com/full-text.xml") /books/book[. contains text "Merrygould" using thesaurus at "http://bstore1.example.com/UsabilitySoundex.xml" relationship "sounds like"]
| [170] | FTStemOption |
::= | "stemming" | ("no" "stemming") |
[Definition: A stemming option modifies token and phrase matching by specifying whether stemming is applied or not. ]
The "stemming" option specifies that matches may contain tokens that have the same stem as the tokens and phrases written in the query. It is implementation-defined what a stem of a token is.
The "no stemming" option specifies that the tokens and phrases are not stemmed.
It is implementation-defined whether the stemming is based on an algorithm, dictionary, or mixed approach.
The default is "no stemming".
The following expression returns true, because the
title
of the specified book
contains
"improving" which has the same stem as "improve":
/books/book[@number="1"]/title contains text "improve" using stemming
| [168] | FTCaseOption |
::= | ("case" "insensitive") |
[Definition: A case option modifies the matching of tokens and phrases by specifying how uppercase and lowercase characters are considered.]
There are four possible character case options:
Using the option "case insensitive", tokens and phrases are matched, regardless of the case of characters of the query tokens and phrases.
Using the option "case sensitive", tokens and phrases are matched, if and only if the case of their characters is the same as written in the query.
Using the option "lowercase", tokens and phrases are matched, if and only if they match the query without regard to character case, but contain only lowercase characters.
Using the option "uppercase", tokens and phrases are matched, if and only if they match the query without regard to character case, but contain only uppercase characters.
The default is "case insensitive".
The effect of the case options is also influenced by the query's default collation (see Section 2.1.1 Static ContextXQ and Section 4.4 Default Collation DeclarationXQ). The following table summarizes how these interact.
| Case option \ Default collation | UCC (Unicode Codepoint Collation) | CCS (some generic case-sensitive collation) | CCI (some generic case-insensitive collation) |
|---|---|---|---|
| case insensitive | compare as if both lower | case-insensitive variant of CCS if it exists, else error | CCI |
| case sensitive | UCC | CCS | case-sensitive variant of CCI if it exists, else error |
| lowercase | compare using UCC after applying fn:lower-case() to the query string | compare using CCS after applying fn:lower-case() to the query string | CCI |
| uppercase | compare using UCC after applying fn:upper-case() to the query string | compare using CCS after applying fn:upper-case() to the query string | CCI |
Note:
In this table, "else error" means "Otherwise, an error is raised: [err:FOCH0002]FO". The phrase "if it exists" is used, because the case-sensitive collation CCS does not always have a case-insensitive variant (and, even if one exists, it may not be possible to determine it algorithmically), and because the case-insensitive collation CCI does not always have a case-sensitive variant (and, even if one exists, it may not be possible to determine it algorithmically).
The following expression returns false, because the
title
element doesn't contain "usability" in
lower-case characters:
//book[@number="1"]/title contains text "Usability" using lowercase
The following expression returns true, because the character case is not considered:
//book[@number="1"]/title contains text "usability" using case insensitive
| [169] | FTDiacriticsOption |
::= | ("diacritics" "insensitive") |
[Definition: A diacritics option modifies token and phrase matching by specifying how diacritics are considered. ]
There are two possible diacritics options:
The option "diacritics" "insensitive" matches tokens and phrases with and without diacritics. Whether diacritics are written in the query or not is not considered.
The option "diacritics" "sensitive" matches tokens and phrases only if they contain the diacritics as they are written in the query.
The default is "diacritics insensitive".
The effect of the diacritics options is also influenced by the query's default collation (see Section 2.1.1 Static ContextXQ and Section 4.4 Default Collation DeclarationXQ). The following table summarizes how these interact.
| Diacritics option \ Default collation | UCC (Unicode Codepoint Collation) | CDS (some generic diacritics-sensitive collation) | CDI (some generic diacritics-insensitive collation) |
|---|---|---|---|
| diacritics insensitive | UCC comparison, but without considering diacritics | diacritics-insensitive variant of CDS if it exists, else error | CDI |
| diacritics sensitive | UCC | CDS | diacritics-sensitive variant of CDI if it exists, else error |
Note:
In this table, "else error" means "Otherwise, an error is raised: [err:FOCH0002]FO". The phrase "if it exists" is used, because the diacritics-sensitive collation CDS does not always have a diacritics-insensitive variant (and, even if one exists, it may not be possible to determine it algorithmically), and because the diacritics-insensitive collation CDI does not always have a diacritics-sensitive variant (and, even if one exists, it may not be possible to determine it algorithmically).
The following expression returns true, because the token "Véra"
in the editor
element is matched, as the acute accent
is not considered in the comparison:
//book[@number="1"]//editor contains text "Vera" using diacritics insensitive
This returns false, because the editor
element does
not contain the token "Vera" in this exact form, i.e. without any
diacritics:
//book[@number="1"]/editors contains text "Vera" using diacritics sensitive
| [174] | FTStopWordOption |
::= | ("stop" "words" FTStopWords FTStopWordsInclExcl*) |
| [175] | FTStopWords |
::= | ("at" URILiteral) |
| [176] | FTStopWordsInclExcl |
::= | ("union" | "except") FTStopWords |
[Definition: A stop word option controls matching of tokens by specifying whether stop words are used or not. Stop words are tokens in the query that match any token in the text being searched. ] More precisely, a stop word option defines a collection of stop words according to the rules below. Then, in every FTWords to which the stop word option applies, each query token is checked: if it appears (using an implementation-defined comparison) in the specified collection of stop words, it is considered a stop word.
Normally a stop word matches exactly one token, but there may be implementation-defined conditions, under which a stop word may match a different number of tokens.
Tokens matched by stop words retain their position numbers and are counted by FTDistance and FTWindow filters.
FTStopWords specifies
the list of stop words either explicitly as a comma-separated list
of string literals, or by the keyword at
followed by a
literal URI. If the URI specifies a list of stop words that is not
found in the statically known stop word lists, an error is raised
[err:FTST0008].
Whether the stop word list is resolved from the statically known
stop word lists or given explicitly, no tokenization is performed
on the stop words: they are used as they occur in the list.
If the stop words option specifies a stop word list with a relative URI, that relative URI is resolved to an absolute URI using the base URI in the static context and that absolute URI is used to identify the stop word list.
Multiple stop word lists may be combined using "union" or "except". The keywords "union" and "except" are applied from left to right. If "union" is specified, every string occurring in the lists specified by the left-hand side or the right-hand side is a stop word. If "except" is specified, only strings occurring in the list specified by the left-hand side but not in the list specified by the right-hand side are stop words.
The "stop words default" option specifies that an implementation-defined collection of stop words is used.
The "no stop words" option specifies that no stop words are used. This is equivalent to specifying an empty list of stop words.
The default is "no stop words".
Note:
Some implementations may apply stop word lists during indexing and be unable to comply with query-time requests to not apply those stop words. An implementation may still support stop-word options (and therefore not raise [err:FTST0006]) by applying any additional stop words specified in the query. Pre-application of irrevocable stop word lists falls under implementation-defined tokenization behavior in this case, and a query that specifies "no stop words" may still have some words ignored.
The following expression returns true, because the document contains the phrase "propagating few errors":
/books/book[@number="1"]//p contains text "propagating of errors" using stop words ("a", "the", "of")
Note the asymmetry in the stop word semantics: the property of being a stop word is only relevant to query terms, not to document terms. Hence, it is irrelevant for the above-mentioned match whether "few" is a stop word or not, and on the other hand we do not want the query above to match "propagating" followed by 2 stop words, or even a sequence of 3 stop words in the document.
The following expression returns false. In this case specifying "few" as a stop word has no effect, since "few" does not appear in the query. Although the words "propagating" and "errors" appear in the text being searched, the phrase "propagating errors" cannot be matched, since that phrase does not occur.
/books/book[@number="1"]//p contains text "propagating errors" using stop words ("few")
The following expression returns false, because "of" is not in
the p
element between "propagating" and "errors":
/books/book[@number="1"]//p contains text "propagating of errors" using no stop words
The following expression uses the stop words list specified at
the URL. Assuming that the specified stop word list contains the
word "then", this query is reduced to a query on the phrase
"planning X conducting", allowing any token as a substitute for X.
It returns a book
element, because its
content
element contains "planning then conducting".
It would also return the book
if the phrases "planning
and conducting" and "planning before conducting" had been in its
content
:
doc("http://bstore1.example.com/full-text.xml") /books/book[.//content contains text "planning then conducting" using stop words at "http://bstore1.example.com/StopWordList.xml"]
The following expression returns book
s containing
"planning then conducting", but not does not return
book
s containing "planning and conducting", since it
is exempting "then" from being a stop word:
doc("http://bstore1.example.com/full-text.xml") /books/book[.//content contains text "planning then conducting" using stop words at "http://bstore1.example.com/StopWordList.xml" except ("the", "then")]
[Definition: An extension option is a match option that acts in an implementation-defined way. ]
| [179] | FTExtensionOption |
::= | "option" QName
StringLiteral |
An extension option consists of an identifying QName and a StringLiteral. Typically, a particular option will be recognized by some implementations and not by others. The syntax is designed so that option declarations can be successfully parsed by all implementations.
The QName of an extension option must resolve to a namespace URI and local name, using the statically known namespaces.
Note:
There is no default namespace for options.
Each implementation recognizes an implementation-defined set of namespace URIs used to denote extension options.
If the namespace part of the QName is not a namespace recognized by the implementation as one used to denote extension option, then the extension option is ignored.
Otherwise, the effect of the extension option, including its error behavior, is implementation-defined. For example, if the local part of the QName is not recognized, or if the StringLiteral does not conform to the rules defined by the implementation for the particular extension option, the implementation may choose whether to report an error, ignore the extension option, or take some other action.
Implementations may impose rules on where particular extension options may appear relative to other match options, and the interpretation of an option declaration may depend on its position.
An extension option must not be used to change the syntax accepted by the processor, or to suppress the detection of static errors. However, it may be used without restriction to modify the set of tokens in the query or how they are matched against tokens in the text being searched. An extension option has the same scope as other match options.
The following examples illustrate several possible uses for extension options:
This extension option is set as part of the static context of all full-text expressions in the module and might be used to ensure that queries are insensitive to Arabic short-vowels.
declare namespace exq = "http://example.org/XQueryImplementation"; declare ft-option using option exq:diacritics "short-vowel insensitive";
This extension option applies only to the matching in the full-text selection in which it is found and might be used to specify how compound words should be matched.
declare namespace exq = "http://example.org/XQueryImplementation"; //para[. contains text ("Kinder" ftand "Platz" distance exactly 1 words) using stemming using option exq:compounds "distance=1" ]
Full-text selections can be combined with the logical
connectives ftor
(full-text or), ftand
(full-text and), not in
(mild not), and
ftnot
(unary full-text not).
| [146] | FTOr |
::= | FTAnd ( "ftor" FTAnd )* |
| [147] | FTAnd |
::= | FTMildNot ( "ftand"
FTMildNot )* |
| [148] | FTMildNot |
::= | FTUnaryNot ( "not"
"in" FTUnaryNot
)* |
| [149] | FTUnaryNot |
::= | ("ftnot")? FTPrimaryWithOptions |
[Definition: An or-selection combines two
full-text selections using the ftor
operator.]
An or-selection finds all matches that satisfy at least one of the operand full-text selections.
The following expression returns the book
element
written by "Millicent":
//book[.//author contains text "Millicent" ftor "Voltaire"]
[Definition: An and-selection combines
two full-text selections using the ftand
operator.]
An and-selection finds matches that satisfy all of the operand full-text selections simultaneously. A match of an and-selection is formed by combining matches for each of the operand full-text selections as described in <IP_ADDRESS> FTAnd.
For example, "usability" ftand "testing"
will find
two matches in //book[@number="1"]/title
: each of the
two matches for the FTWords selection "usability"
(the
two occurrences of "usability" in the string value of the title
element) is combined with the single match for the FTWords
"testing"
(only one occurrence of "testing" in the
title). Since the above and-selection has at least one match, the
following expression will return "true".
//book[@number="1"]/title contains text ("usability" ftand "testing")
The following expression returns false, because "Millicent" and
"Montana" are not contained by the same author
element
in any book
element:
//book/author contains text "Millicent" ftand "Montana"
No author
element in any book
element
contains both "Millicent" and "Montana". Therefore, for any such
author
element, there are either one match for the
FTWords "Millicent"
and zero matches for the FTWords
"Montana"
, or vice versa, or no matches for both of
them. In any of these cases, the and-selection will have zero
matches.
[Definition: A mild-not
selection combines two full-text selections using the not
in
operator.]
The not in
operator is a milder form of the
operator combination ftand ftnot
. The selection
A not in B
matches a token sequence that matches
A
, but not when it is a part of a match of
B
. In contrast, A ftand ftnot B
only
finds matches when the token sequence contains A
and
does not contain B
.
As an example, consider a search for "Mexico" not in "New
Mexico"
. This may return, among others, a document which is
all about "Mexico" but mentions at the end that "New Mexico was
named after Mexico". The occurrence of "Mexico" in "New Mexico" is
not considered, but other occurrences of "Mexico" are matched. Note
that this document would not be matched by the full-text selection
"Mexico" ftand ftnot "New Mexico"
.
A match to a mild-not selection must contain at least one token that satisfies the first condition and does not satisfy the second condition. If it contains a token that satisfies both the first and the second condition, the token is not considered as a match.
The following expression returns true, because "usability"
appears in the title
and the p
elements
and the token within the phrase "Usability Testing" in the
title
element is not considered:
/books/book contains text "usability" not in "usability testing"
If either operand of a mild-not selection yields an AllMatches that contains a Match that contains a StringExclude, then a dynamic error [err:FTDY0017] is raised.
Note:
This situation can arise if the operand contains a not-selection
or a cardinality constraint (FTTimes) involving
exactly
, at most
, or from ...
to
.
[Definition: A not-selection is a
full-text selection starting with the prefix operator
ftnot
.]
A not-selection selects matches that do not satisfy the operand full-text selection. Details about how such matches are constructed are given in <IP_ADDRESS> FTUnaryNot.
The following expression returns the empty sequence, because all
book
elements contain "usability":
//book[. contains text ftnot "usability"]
The following expression returns true, because book
elements contain "improving" and "usability" but not "improving
usability":
//book contains text "improving" ftand "usability" ftand ftnot "improving usability"
The following expression returns book
elements
containing "web site usability" but not "usability testing":
//book[title/@shortTitle contains text "web site usability" ftand ftnot "usability testing"]
| [158] | FTPosFilter |
::= | FTOrder | FTWindow | FTDistance | FTScope | FTContent |
[Definition: Positional filters are postfix operators that serve to filter matches based on various constraints on their positional information.]
Recall that the grammar rule for FTSelection allows an arbitrary number of positional filters to follow an FTOr. In a group of multiple adjacent positional filters, FTOrder filters are applied first, and then the other positional filters are applied from left to right, skipping the FTOrder filters. That is, the first filter is applied to the result of the FTOr, the second is applied to the result of that first application, and so on.
An FTOr consists of one or more
FTAnds (separated by
ftor
), each of which could be an FTPosFilter applied to an embedded
FTOr, enclosed in parentheses.
| [159] | FTOrder |
::= | "ordered" |
[Definition: An ordered selection consists of a full-text selection followed by the postfix operator "ordered".] An ordered selection constrains the order of tokens and phrases to be the same as the order in which they are written in the operand selection.
The default is unordered. Unordered is in effect when ordered is not specified in the query. Unordered cannot be written explicitly in the query.
An ordered selection selects matches which satisfy the operand full-text selection and which also satisfy the following constraint: the order that the matching tokens or phrases have in the text being searched is the same order that the corresponding query tokens or phrases have in the operand selection. In both cases, the ordering is determined from the minimum start positions of the constituent tokens.
The following expression returns true, because titles of
book
elements contain "web site" and "usability" in
the order in which they are written in the query, i.e., "web site"
must precede "usability":
//book/title contains text ("web site" ftand "usability") ordered
The following expression returns false, because although
"Montana" and "Millicent" both appear in the book
element, they do not appear in the order they are written in the
query:
//book[@number="1"] contains text ("Montana" ftand "Millicent") ordered
| [160] | FTWindow |
::= | "window" AdditiveExpr FTUnit |
| [162] | FTUnit |
::= | "words" | "sentences" | "paragraphs" |
[Definition: A window selection
consists of a full-text selection followed by one of the (complex)
postfix operators derived from FTWindow.] A window selection selects
matches which satisfy the operand full-text selection and for which
the matched tokens and phrases, more precisely the individual
StringIncludes of that match, are found within a number of FTUnits (words, sentences, and
paragraphs). The number of FTUnits is specified by an AdditiveExpr
that is converted as though it were an argument to a function with
the expected type of xs:integer
.
A window selection may cross element boundaries. The size of the window is not affected by the presence or absence of element boundaries. Stop words are included in the computation of the window size whether they are ignored by the query or not.
A window selection examines the matches generated by the preceding portion of the FTSelection, and selects those for which the matched tokens and phrases (more precisely, the individual StringIncludes of that match) are all found within a window whose size is a specified number of FTUnits (words, sentences, or paragraphs); for each such window, the window selection then generates a match containing the merge of those StringIncludes, plus any StringExcludes that fall within the window.
The following expression returns true, because "web", "site",
and "usability" are within a window of 5 tokens in the
title
element:
/books/book/title contains text "web" ftand "site" ftand "usability" window 5 words
The following expression returns true, because "web" and "site" in the order they are written in the query and either "usability" or "testing" are within a window of at most 10 tokens:
/books/book contains text ("web" ftand "site" ordered) ftand ("usability" ftor "testing") window 10 words
The following expression returns false, because the instances of
"web site" and "usability" in the title
element are
not within a window of 3. The phrase "Web Site Usability" in the
attribute does not apply because the attribute is not part of the
string value of the node. A similar query with a window of 5 would
return true.
/books/book//title contains text "web site" ftand "usability" window 3 words
The following expression returns the sample book
element, because its number
attribute is 1 and it
contains a window of 2 words which contains an occurrence of
"efficient" but not an occurrence of "and". There is just one such
matching window in the sample text and it contains "enable
efficient".
/books/book[@number="1" and . contains text "efficient" ftand ftnot "and" window 2 words]
The following expression returns the empty sequence, because in
the selected book
element, there is no occurrence of
"efficient" within a window of 3 tokens which would not also
contain an occurrence of "and":
/books/book[@number="1" and . contains text "efficient" ftand ftnot "and" window 3 words]
In order to allow meaningful results for nested positional filters, e.g., a window selection embedded inside a distance selection, the resulting matches for window selections are formed from the input matches that satisfy the window constraint as follows. All StringIncludes of such a match are coerced into a single StringInclude that spans all token positions from the smallest to the largest position of any input StringIncludes. This is explained in more detail in Section 3.6.3 Distance Selection.
| [161] | FTDistance |
::= | "distance" FTRange
FTUnit |
| [157] | FTRange |
::= | ("exactly" AdditiveExpr) |
[Definition: A distance selection consists of a full-text selection followed by one of the (complex) postfix operators derived from FTDistance.]
A distance selection selects matches which satisfy the operand full-text selection and for which the matched tokens and phrases satisfy the specified distance conditions.
Distances in the search context are measured in units of tokens, sentences, or paragraphs. Roughly speaking, the distance between two matches is the number of intervening units, so a distance of zero tokens (sentences, paragraphs) means no intervening tokens (sentences, paragraphs). More precisely, given two matches, we first determine their order by sorting on starting position and if necessary on ending position. Let M1 be the "earlier" and M2 be the "later". (If there are overlapping tokens involved, the designations "earlier" and "later" may not be intuitively obvious.) Then the distance between the two is M2's starting position minus M1's ending position, minus 1.
When computing distances in the search context, a distance selection may cross element boundaries; they affect the distance computed only to the extent that they affect the tokenization of the search context. Stop words are counted in those computations whether they are ignored or not.
When a distance selection applies a distance condition to more than two matches, the distance condition is required to hold on each successive pair of matches.
An FTDistance expresses a
distance condition in terms of an FTUnit and an FTRange. An FTUnit can be words
,
sentences
, or paragraphs
, where
words
refers to a distance measured in tokens.
An FTRange specifies a range
of integer values by providing a minimum and/or maximum value for
some integer quantity. (Here, where the FTRange appears in an
FTDistance, that quantity is a distance. When it appears in an
FTTimes, the quantity is a number of occurrences.) Each one of the
AdditiveExpr specified in an FTRange is converted as though it were
an argument to a function with the expected parameter type of
xs:integer
.
Let the value of the first (or only) operand be M. If "from" is specified, let the value of the second operand be N.
If "exactly" is specified, then the range is the closed interval [M, M]. If "at least" is specified, then the range is the half-closed interval [M, unbounded). If "at most" is specified, then the range is the half-closed interval (unbounded, M]. If "from-to" is specified, then the range is the closed interval [M, N]. Note: If M is greater than N, the range is empty.
Here are some examples of FTRanges:
'exactly 0' specifies the range [0, 0].
'at least 1' specifies the range [1,unbounded).
'at most 1' specifies the range (unbounded, 1].
'from 5 to 10' specifies the range [5, 10].
The following expression returns false, because "completion" and "errors" are less than 11 tokens apart:
/books/book contains text ("completion" ftand "errors" distance at least 11 words)
The following expression returns true:
/books/book contains text "web" ftand "site" ftand "usability" distance at most 2 words
The search context contains two occurrences of the phrase "the
usability of a web site" (once in the <title> and once in the
<content>). In this phrase, the tokens "usability" and "web"
have a distance of 2 words, and the tokens "web" and "site" have a
distance of 0 words, both of which satisfy the constraint
distance at most 2 words
. (The tokens "usability" and
"site" have a distance of 3 words, but this does not cause the
distance filter to fail, because these are not successive matches.)
Thus, the full-text selection yields two matches, and the whole
expression yields true. (The phrase "Improving Web Site Usability"
would also satisfy the given full-text selection, but in the sample
document it occurs in an attribute value, and so does not
contribute to the string value or the tokenization of the book
element.)
The following expression returns the empty sequence, because between any token "usability" and the token in any occurrence of the phrase "web site" that is the nearest to the token "usability" there is always more than one intervening token:
/books/book[.//p contains text "web site" ftand "usability" distance at most 1 words]
The following expression returns the book
title,
because for the occurrences of the tokens "web" and "users" in the
note
element only one intervening token appears:
/books/book[. contains text "web" ftand "users" distance at most 1 words]/title
In order to allow meaningful results for nested positional filters, e.g., a distance selection embedded inside another distance selection, the resulting matches for distance selections are formed from the input matches that satisfy the distance constraint as follows. All StringIncludes of such a match are coerced into a single StringInclude that spans all token positions from the smallest to the largest position of any input StringIncludes. Thus, a distance selection that embeds a window or a distance selection takes the result of the embedded selection as a single unit.
The following gives an example of nested distance selections:
/books/book contains text ((("richard" ftand "nixon") distance at most 2 words) ftand (("george" ftand "bush") distance at most 2 words) distance at least 20 words)
This expression allows to find book
elements that
contain, for instance, "Richard M. Nixon" and "George W. Bush" at
least 20 words apart. The matches for the inner distance selections
are treated as single units (represented by StringIncludes) by the
outer distance selection. Suppose such phrases are present in the
search context, then the outer distance selection enforces a
constraint on the number of intervening tokens ("at least 20")
between the last token of "Richard M. Nixon" and the first token of
"George W. Bush".
| [163] | FTScope |
::= | ("same" | "different") FTBigUnit |
| [164] | FTBigUnit |
::= | "sentence" | "paragraph" |
[Definition: A scope selection consists of a full-text selection followed by one of the (complex) postfix operators derived from FTScope.]
A scope selection selects matches which satisfy the operand full-text selection and for which the matched tokens and phrases are contained in the same scope or in different scopes.
Possible scopes are sentences and paragraphs.
By default, there are no restrictions on the scope of the matches.
The following expression returns false, because the tokens "usability" and "Marigold" are not contained within the same sentence:
//book contains text "usability" ftand "Marigold" same sentence
The following expression returns true, because the tokens "usability" and "Marigold" are contained within different sentences:
//book contains text "usability" ftand "Marigold" different sentence
The following expression returns a book
element,
because it contains "usability" and "testing" in the same
paragraph:
//book[. contains text "usability" ftand "testing" same paragraph]
The following expression returns a book
element,
because "site" and "errors" appear in the same sentence:
//book[. contains text "site" ftand "errors" same sentence]
It is possible that both "same sentence" and "different sentence" conditions are simultaneously safisfied for several tokens and/or phrases within the same document fragment. This can be observed if there are occurrences of the tokens and/or phrases both within the same sentence and within difference sentences. For example, consider the following document fragment.
<introduction> ... The usability of a Web site is how well the site supports the user in achieving specified goals. ... Expert reviews and usability testing are methods of identifying problems in layout, terminology, and navigation. ... </introduction>
This sample will satisfy both conditions ("usability"
ftand "reviews") different sentence
and ("usability"
ftand "reviews") same sentence
. The tokens "usability" and
"reviews" occur both in different sentences (the first and second
shown sentences) and in the same sentence (the second shown
sentences.)
The above observation also holds for the "same paragraph" and "different paragraph" conditions.
| [165] | FTContent |
::= | ("at" "start") | ("at" "end") | ("entire"
"content") |
[Definition: An anchoring selection consists of a full-text selection followed by one of the postfix operators "at start", "at end", or "entire content".]
An anchoring selection selects matches which satisfy the operand full-text selection and for which the matched tokens and phrases are the first, last, or all tokens in the tokenized form of the items being searched.
Using the "at start" operator, tokens or phrases are matched, if they cover the first token position in the tokenized string value of the item being searched.
Using the "at end" operator, tokens or phrases are matched, if they cover the last token position in the tokenized string value of the item being searched.
Using the "entire content" operator, tokens or phrases are matched, if they cover all token positions of the tokenized string value of the item being searched.
The following expression returns each title
element
starting with the phrase "improving the usability of a web
site":
/books//title[. contains text "improving the usability of a web site" at start]
The following expression returns the p
element of
the sample, because it ends with the phrase "propagating few
errors":
/books//p[. contains text "propagat.*" using wildcards ftand "few errors" distance at most 2 words at end]
Since the distance operator doesn't imply an ordering, the last
example would also yield a match if the p
element
ended with, say, "few errors are propagated".
The following expression returns each note
element
whose entire content is "this book has been approved by the web
site users association":
/books//note[. contains text "this book has been approved by the web site users association" entire content]
The following example returns true because both the
content
and the note
elements match:
/books//* contains text "Association" at end
| [180] | FTIgnoreOption |
::= | "without" "content" UnionExpr |
The ignore option specifies a set of nodes whose contents are ignored. It is applicable only to a top-level FTSelection (see FTContainsExpr). [Definition: Ignored nodes are the set of nodes whose content are ignored.] Ignored nodes are identified by the XQuery expression UnionExpr. The value of the UnionExpr must be a sequence of zero or more nodes; otherwise a type error is raised [err:XPTY0004]XP.
Let I1, I2, ..., In
be the sequence of items of the
search context and let N1, N2, ..., Nk
be the sequence
of nodes that UnionExpr evaluates to. For each Ij
(j=1..n)
a copy is made that omits each node Ni
(i=1..k)
. Those copies form the new search context. If
UnionExpr evaluates to an empty sequence no nodes are omitted.
In the following fragment, if $x//annotation
is
ignored, "Web Usability" will be found 2 times: once in the
title
element and once in the editor
element. The 2 occurrences in the 2 annotation
elements are ignored. On the other hand, "expert" will not be
found, as it appears only in an annotation
element.
let $x := <book> <title>Web Usability and Practice</title> <author>Montana <annotation> this author is an expert in Web Usability</annotation> Marigold </author> <editor>Véra Tudor-Medina on Web <annotation> best editor on Web Usability</annotation> Usability </editor> </book>
By default, no element content is ignored.
Note:
Nodes MAY be ignored during indexing and during query processing. The ignore option applies only to query processing. Whether and how indexing ignores nodes is out of scope for this specification.
[Definition: An extension selection is a full-text selection whose semantics are implementation-defined.] Typically, a particular extension will be recognized by some implementations and not by others. The syntax is designed so that extension selections can be successfully parsed by all implementations, and so that fallback behavior can be defined for implementations that do not recognize a particular extension.
| [154] | FTExtensionSelection |
::= | Pragma+ "{" FTSelection? "}" |
| [69] | Pragma |
::= | "(#" S? QName (S
PragmaContents)?
"#)" |
| [70] | PragmaContents |
::= | (Char* - (Char* '#)'
Char*)) |
An extension selection consists of one or more pragmas followed
by a full-text selection enclosed in curly braces. See Section
3.14 Extension ExpressionsXQ for
information on pragmas in general. A pragma is denoted by the
delimiters (#
and #)
, and consists of an
identifying QName followed by implementation-defined
content. The content of a pragma may consist of any string of
characters that does not contain the ending delimiter
#)
. The QName of a pragma must resolve to a namespace
URI and local name, using the statically known namespaces.
Note:
Since there is no default namespace for pragmas, a pragma QName must include a namespace prefix.
Each implementation recognizes an implementation-defined set of namespace URIs used to denote pragmas.
If the namespace part of a pragma QName is not recognized by the implementation as a pragma namespace, then the pragma is ignored. If all the pragmas in an FTExtensionSelection are ignored, then full-text extension selection is just the full-text selection enclosed in curly braces; if this full-text selection is absent, then a static error is raised [err:XQST0079]XQ.
If an implementation recognizes the namespace of one or more pragmas in an FTExtensionSelection, then the value of the FTExtensionSelection, including its error behavior, is implementation-defined. For example, an implementation that recognizes the namespace of a pragma QName, but does not recognize the local part of the QName, might choose either to raise an error or to ignore the pragma.
It is a static error [err:XQST0013]XQ if an implementation recognizes a pragma but determines that its content is invalid.
If an implementation recognizes a pragma, it must report any static errors in the following full-text selection even if it will not apply that selection.
The following examples illustrate three ways in which extension selections might be used.
A pragma can be used to furnish a hint for how to evaluate the following full-text selection, without actually changing the result. For example:
declare namespace exq = "http://example.org/XQueryImplementation"; /books/book/author[name contains text (# exq:use-index #) {'Berners-Lee'}]
An implementation that recognizes the exq:use-index
pragma might use an index to evaluate the full-text selection that
follows. An implementation that does not recognize this pragma
would evaluate the full-text selection in its normal way.
A pragma might be used to modify the semantics of the following full-text selection in ways that would not (in the absence of the pragma) be conformant with this specification. For example, a pragma might be used to change distance counting so that adjacent words are at a distance of 1 (otherwise they would be at a distance of 0):
declare namespace exq = "http://example.org/XQueryImplementation"; /books/book[.//p contains text (# exq:distance #) { "web site" ftand "usability" distance at most 1 words }]
Such changes to the language semantics must be scoped to the expression contained within the curly braces following the pragma.
A pragma might contain syntactic constructs that are evaluated in place of the following full-text selection. In this case, the following selection itself (if it is present) provides a fallback for use by implementations that do not recognize the pragma. For example:
declare namespace exq = "http://example.org/XQueryImplementation"; //city[. contains text (# exq:classifier with class 'Animals' #) {"animal" using thesaurus at "http://example.org/thesaurus.xml" relationship "RT"}]
Here an implementation that recognizes the pragma will return
the result of evaluating the proprietary syntax with class
'animals'
, while an implementation that does not recognize
the pragma will instead return the result of the thesaurus option.
If no fallback expression is required, or if none is feasible, then
the expression between the curly braces may be omitted, in which
case implementations that do not recognize the pragma will raise a
static error.
This section describes the formal semantics of XQuery and XPath Full Text 1.0. The figure below shows how XQuery and XPath Full Text 1.0 integrates with XQuery 1.0 and XPath 2.0.
The following diagram represents the interaction of XQuery and XPath Full Text 1.0 with the rest of XQuery 1.0 and XPath 2.0. It illustrates how full-text expressions can be nested within XQuery 1.0 and XPath 2.0 expressions and vice versa.
Step 1 represents the composability of XQuery 1.0 and XPath 2.0 expressions and the fact that such expressions evaluate to a sequence of XDM items. This process is outside the scope of this document and will not be discussed further.
Step 2 shows how XQuery 1.0 and XPath 2.0 expressions can be nested within full-text expressions. If an XQuery 1.0 and XPath 2.0 expression is nested on the left-hand side of an FTContains expression or within FTWords, the sequence of XDM items that result from evaluation of that XQuery 1.0 or XPath 2.0 expression are converted to their tokenized form, as described in Tokenization. If the XQuery 1.0 and XPath 2.0 expression is nested within another type of FTSelection, the items in its result sequence are converted to atomic values, as discussed in FTSelections.
Step 3 represents the composability of FTSelections. Each FTSelection operates on zero or more AllMatches and returns an AllMatches. The process is described in the Evaluation of FTSelections section.
Step 4 shows how XQuery and XPath Full Text 1.0 and scoring expressions can be nested into XQuery 1.0 and XPath 2.0 expressions. The sections 4.3 FTContainsExpr and 4.4 Scoring describe how this is achieved.
Note:
In the list above and throughout the rest of this section, bold typeface has been used to distinguish the concepts that are part of the AllMatches model.
The functions and schemas defined in this section are considered to be within the fts: namespace (as discussed in section 1.3 A word about namespaces). These functions and schemas are used only for describing the semantics. There is no requirement that an implementation of this specification must use the functions, schemas, or algorithms described in this section of this specification. The only requirement is that implementations must achieve the same results that an implementation that does use these functions, schemas, and algorithms would achieve.
Note that by using XQuery 1.0 and XPath 2.0 to specify the formal semantics, we avoid the need to introduce new formalism. We simply reuse the formal semantics of XQuery 1.0 and XPath 2.0.
[Definition: Formally, tokenization is the process of converting an XDM item to a collections of tokens, taking any structural information of the item into account to identify token, sentence, and paragraph boundaries. Each token is assigned a starting and ending position.]
Tokenization, including the definition of the term "token", SHOULD be implementation-defined. Implementations SHOULD expose the rules and sample results of tokenization as much as possible to enable users to predict and interprete the results of tokenization. Tokenization MUST conform to these constraints:
Each token MUST consist of one or more characters.
Tokenization of an item MUST include only tokens derived from the string value of that item. The string value is defined in [XQuery 1.0 and XPath 2.0 Data Model (XDM) (Second Edition)] in Section 2.6.5 String ValuesDM; for element nodes it does not include the contents of attributes, but for attribute nodes it does.
The tokenizer SHOULD, when tokenizing two equal items, identify the same tokens in each. The cases where it does not are implementation-defined.
The starting and ending position of a token MUST be integers, and the starting position MUST be less than or equal to the ending position.
In the tokenization of an item, consider the range of token
positions from the smallest starting position to the largest ending
position; every token position in that range must be covered by
some token in the tokenization. That is, for every token position
P
, there must exist some token T
such
that T's starting position <= P <= T's ending
position
.
The tokenizer MUST preserve the containment hierarchy (paragraphs contain sentences contain tokens) by adhering to the following constraints:
Each token is contained in at most one sentence and at most one paragraph. (In particular, this means that no tokens of any sentence are contained in any other sentence, and no tokens of any paragraph are contained in any other paragraph.)
All tokens of a sentence are contained in at most one paragraph.
The range of token positions from the smallest starting position to the largest ending position in a sentence does not overlap with the token position range from any other sentence.
The range of token positions from the smallest starting position to the largest ending position in a paragraph does not overlap with the token position range from any other paragraph.
Useful information for tokenizer implementors may be found in [UAX29].
Note:
Usually, the starting and ending positions of a token are the same. For some languages, some tokenizers may identify overlapping tokens. For example, the German word "Donaudampfschifffahrtskapitaensmuetze" might be tokenized into the following tokens: "Donaudampfschifffahrtskapitaensmuetze", "Donau", "dampf", "schiff", "dampfschiff", "kapitaen", "muetze", "kapitaensmuetze", "schifffahrt", "dampfschifffahrt", and perhaps others. In the face of overlapping tokens, it is implementation-dependent what positions a tokenizer assigns to each such token. For example, a tokenizer might assign the same position value to each of the tokens "Donaudampfschifffahrtskapitaensmuetze", "Donau", "dampf", "schiff", "dampfshiff", etc. In that case, the distance between each (overlapping) token assigned the same position is -1. Tokenizers might retain additional information about those overlapping tokens that allows the full-text implementation to distinguish among them.
Consider the sentence "Ich sehe den Dampfschifffahrtskapitän auf dem Fluß." If an implementation tokenizes "Dampfschifffahrtskapitän" as overlapping tokens at the same position, then the implementation could still determine that the query "'Schifffahrt Dampf' window 0 words ordered" fails to match the sentence because phrase matching is implementation-defined and may make use of additional implementation-dependent token information.
Even more complex situations can arise. Consider, for example,
the German sentence "Er stellte sie vor." A sophisticated tokenizer
might construct the token "vorstellen" covering positions 2 through
4, which overlaps the token "sie" at position 3. For the purposes
of distance calculations, tokens are considered in the order of
their starting positions, so the distance between "vorstellen" and
"sie" would be 3-4-1=-2. (See fts:wordDistance
,
below.)
For example, the following example must return false, because the 'secret' only occurs within an attribute and a comment, neither of which contributes characters to the string value of the 'p' element node:
<p kind='secret'>Sensitive material <!-- secret --></p> contains text 'secret'
The following document may lead to overlapping tokens to account for the ambiguity caused by the hyphen:
<p>I will re- sign tommorow.</p>
The following document fragment is the source document for examples in this section. A sample tokenization is used for the examples in this section. The results might be different for other tokenizations.
Unless stated otherwise, the results assume a case-insensitive match.
<offers> <offer id="1000" price="10000"> Ford Mustang 2000, 65K, excellent condition, runs great, AC, CC, power all </offer> <offer id="1001" price="8000"> Honda Accord 1999, 78K, A/C, cruise control, runs and looks great, excellent condition </offer> <offer id="1005" price="5500"> Ford Mustang, 1995, 150K highway mileage, no rust, excellent condition </offer> </offers>
In this sample tokenization, tokens are delimited by punctuation and whitespace symbols.
The token "Ford" is at relative position 1.
The token "Mustang" is at relative position 2.
The token "2000" is at relative position 3.
Relative position numbers are assigned sequentially through the end of the document.
Hence in this example each token occupies exactly one position, and no overlapping of tokens occurs. The relative positions of tokens are shown below in parentheses.
<offers> <offer id="1000" price="10000"> Ford(1) Mustang(2) 2000(3), 65K(4), excellent(5) condition(6), runs(7) great(8), AC(9), CC(10), power(11) all(12) </offer> <offer id="1001" price="8000"> Honda(13) Accord(14) 1999(15), 78K(16), A(17)/C(18), cruise(19) control(20), runs(21) and(22) looks(23) great(24), excellent(25) condition(26) </offer> <offer id="1005" price="5500"> Ford(27) Mustang(28), 1995(29), 150K(30) highway(31) mileage(32), little(33) rust(34), excellent(35) condition(36) </offer> </offers>
The relative positions of paragraphs are determined similarly. In this sample tokenization, the paragraph delimiters are start tags and end tags.
The tokens in the first 'offer' element are assigned relative paragraph number 1.
The tokens from the next 'offer' element are assigned relative paragraph number 2.
Relative paragraph numbers are assigned sequentially through the end of the document.
The relative positions of sentences are determined similarly using sentence delimiters.
Implementations may provide for the means to ignore or side-step
certain structural elements when performing tokenization. In the
following example, the implementation has decided to ignore the
markup for <bold>
and prune out the entire
subtree headed by <deleted>
.
<para><deleted>This sentence was deleted.</deleted> This <bold>entire paragraph</bold> is one sentence as far as the tokenizer is concerned. </para>
Using the same notation as before, this sample tokenization is shown below. All the tokens marked with a token position also have the same sentence and paragraph relative positions. Note that there are no tokens marked for the ignored subtree.
<para><deleted>This sentence was deleted.</deleted> This(1) <bold>entire(2) paragraph(3)</bold> is(4) one(5) sentence(6) as(7) far(8) as(9) the(10) tokenizer(11) is(12) concerned(13). </para>
[Definition: A QueryItem is a sequence of QueryTokenInfos representing the collection of tokens derived from tokenizing one query string. ]
[Definition: A QueryTokenInfo is the identity of a token inside a query string. ] Each QueryTokenInfo is associated with a position that captures the relative position of the query string in the query.
[Definition: A TokenInfo represents a contiguous collection of tokens from an XML document. ] Each TokenInfo is associated with:
startPos
: the smallest starting position of a token
in the sequence
endPos
: the largest ending position of any token of
the sequence
startSent
: the relative position of the sentence
containing the token with the smallest starting position or zero if
the tokenizer does not report sentences
endSent
: the relative position of the sentence
containing the token with the largest ending position or zero if
the tokenizer does not report sentences
startPara
: the relative position of the paragraph
containing the token with the smallest starting position or zero if
the tokenizer does not report paragraphs
endPara
: the relative position of the paragraph
containing the token with the largest ending position or zero if
the tokenizer does not report paragraphs
The following matching function is the central implementation-defined primitive performing the full-text retrieval.
declare function fts:matchTokenInfos ( $searchContext as item(), $matchOptions as element(fts:matchOptions), $stopWords as xs:string*, $queryTokens as element(fts:queryToken)* ) as element(fts:tokenInfo)* external;
The above function returns the TokenInfos in items in
$searchContext
that match the query string represented
by the sequence $queryTokens
, when using the match
options in $matchOptions
and stop words in
$stopWords
. If $queryTokens
is a sequence
of more than one query token, each returned TokenInfo must
represent a phrase matching that sequence.
Note:
While this matching function assumes a tokenized representation
of the query strings, it does not assume a tokenized representation
of the input items in $searchContext
, i.e. the texts
being searched. Hence, the tokenization of the search context is
implicit in this function and coupled to the retrieval of matches.
Of course, this does not imply that tokenization of the search
context cannot be done a priori. The tokenization of each item in
$searchContext
does not necessarily take into account
the match options in $matchOptions
or the query tokens
in $queryTokens
. This allows implementations to
tokenize and index input data without the knowledge of particular
match options used in full-text queries.
The XQuery 1.0 and XPath 2.0 Data Model is inadequate to support fully composable FTSelections. Full-text operations, such as FTSelections, operate on linguistic units, such as positions of tokens, and which are not captured in the XQuery 1.0 and XPath 2.0 Data Model (XDM).
XQuery and XPath Full Text adds relative token, sentence, and paragraph position numbers via AllMatches. AllMatches make FTSelections fully composable.
[Definition: An AllMatches describes the possible results of an FTSelection.] The UML Static Class diagram of AllMatches is shown on the diagram given below.
The AllMatches object contains zero or more Matches.
[Definition: Each Match describes one result to the FTSelection.] The result is described in terms of zero or more StringIncludes and zero or more StringExcludes.
[Definition: A StringMatch is a possible match of a sequence of query tokens with a corresponding sequence of tokens in a document. A StringMatch may be a StringInclude or StringExclude.] The queryPos attribute specifies the position of the query token in the query. This attribute is needed for FTOrders. The matched document token sequence is described in the TokenInfo associated with the StringMatch.
[Definition: A StringInclude is a StringMatch that describes a TokenInfo that must be contained in the document.]
[Definition: A StringExclude is a StringMatch that describes a TokenInfo that must not be contained in the document.]
Intuitively, AllMatches specifies the TokenInfos that a search context item contains and does not contain to satisfy an FTSelection.
The AllMatches structure resembles the Disjunctive Normal Form (DNF) in propositional and first-order logic. The AllMatches is a disjunction of Matches. Each Match is a conjunction of StringIncludes, and StringExcludes.
Since in most of the examples below the tokens span only a
single position, we characterize the TokenInfo instance by
simply giving this position, written as "Pos:X". This should be
read as the value for both, the startPos
and the
endPos
attribute. Furthermore, for expository reasons,
we include in each StringMatch example an attribute "query
string", set to the original query string, in order to facilitate
the association from which query string that match came from.
The simplest example of an FTSelection is an
FTWords such as "Mustang"
. The
AllMatches corresponding to this FTWords is given
below.
As shown, the AllMatches consists of two Matches.
Each Match represents one possible result of the
FTWords "Mustang"
. The result represented by
the first Match, represented as a StringInclude,
contains the token "Mustang" at position 2. The result described by
the second Match contains the token "Mustang" at position
28.
A more complex example of an FTSelection is an
FTWords such as "Ford Mustang"
. The
AllMatches for this FTWords is given below.
There are two possible results for this FTWords, and these are represented by the two Matches. Each of the Matches requires two tokens to be matched. The first Match is obtained by matching "Ford" at position 1 and matching "Mustang" at position 2. Similarly, the second Match is obtained by matching "Ford" at position 27 and "Mustang" at position 28.
An even more complex example of an FTSelection is an
FTSelection such as "Mustang" ftand ftnot
"rust"
that searches for "Mustang" but not "rust". The
AllMatches for this FTSelection is given below.
This example introduces StringExclude. StringExclude corresponds to negation in DNF (Disjunctive Normal Form). It specifies that the result described by the corresponding Match must not match the token at the specified position. In this example, the first Match specifies that "Mustang" is matched at position 2, and that the token "rust" at position 34 is not matched.
AllMatches has a well-defined hierarchical structure. Therefore, the AllMatches can be easily modeled in XML. This XML representation and those which follow formally describe the semantics of FTSelections. For example, the XML representation of AllMatches formally specifies how an FTSelection operates on zero or more AllMatches to produce a resulting AllMatches.
The XML schema for representing AllMatches is given below.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fts="http://www.w3.org/2007/xpath-full-text" targetNamespace="http://www.w3.org/2007/xpath-full-text" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:complexType name="allMatches"> <xs:sequence> <xs:element ref="fts:match" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> <xs:attribute name="stokenNum" type="xs:integer" use="required" /> </xs:complexType> <xs:element name="allMatches" type="fts:allMatches"/> <xs:complexType name="match"> <xs:sequence> <xs:element ref="fts:stringInclude" minOccurs="0" maxOccurs="unbounded"/> <xs:element ref="fts:stringExclude" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:element name="stringInclude" type="fts:stringMatch" /> <xs:element name="stringExclude" type="fts:stringMatch" /> <xs:element name="match" type="fts:match"/> <xs:complexType name="stringMatch"> <xs:sequence> <xs:element ref="fts:tokenInfo"/> </xs:sequence> <xs:attribute name="queryPos" type="xs:integer" use="required"/> <xs:attribute name="isContiguous" type="xs:boolean" use="required"/> </xs:complexType> <xs:complexType name="tokenInfo"> <xs:attribute name="startPos" type="xs:integer" use="required"/> <xs:attribute name="endPos" type="xs:integer" use="required"/> <xs:attribute name="startSent" type="xs:integer" use="required"/> <xs:attribute name="endSent" type="xs:integer" use="required"/> <xs:attribute name="startPara" type="xs:integer" use="required"/> <xs:attribute name="endPara" type="xs:integer" use="required"/> </xs:complexType> <xs:element name="tokenInfo" type="fts:tokenInfo"/> <xs:complexType name="queryItem"> <xs:sequence> <xs:element ref="fts:queryToken" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:complexType name="queryTokenInfo"> <xs:attribute name="word" type="xs:string" use="required"/> <xs:attribute name="queryPos" type="xs:integer" use="required"/> </xs:complexType> <xs:element name="queryToken" type="fts:queryTokenInfo"/> </xs:schema>
The stokenNum
attribute in AllMatches is
related to the representation of the semantics as XQuery functions.
Therefore, it is not considered part of the AllMatches
model. The stokenNum
attribute stores the number of
query tokens used when evaluating the AllMatches. This value
is used to compute the correct value for the queryPos
attribute in new StringMatches.
FTSelections are fully composable and may be nested arbitrarily under other FTSelections. Each FTSelection may be associated with match options (such as stemming and stop words) and score weights. Since score weights are solely interpreted by the formal semantics scoring function, they do not influence the semantics of FTSelections. Therefore, score weights are not considered in the formal semantics.
The XML structures defined by the following schema represent
FTSelections within the semantic functions of section
4 Semantics. This representation
is used for definitional purposes only and should not be confused
with the XML representation for queries in Appendix E XML Syntax (XQueryX) for XQuery and XPath
Full Text 1.0. Every FTSelection is represented as
an XML element. Every nested FTSelection is represented as a
nested descendant element. For binary FTSelections, e.g.,
FTAnd, the nested FTSelections are represented in
<left>
and <right>
descendant
elements. For unary FTSelections, a
<selection>
descendant element is used.
 The function
takes three parameters: (1) an FTSelection, 2) a search
context item, and 3) the default set of match options that apply to
the evaluation of the FTSelection.
The fts:evaluate
function returns the
AllMatches that is the result of evaluating the
FTSelection. When fts:evaluate
is applied to
some FTSelection X, it calls the function
fts:ApplyX
to build the resulting AllMatches.
If X is applied on nested FTSelections, the
fts:evaluate
function is recursively called on these
nested FTSelections and the returned AllMatches are
used in the evaluation of fts:ApplyX
.
The semantics for the fts:evaluate
function is
given below.
declare function fts:evaluate ( $ftSelection as element(*, fts:ftSelection), $searchContext as item(), $matchOptions as element(fts:matchOptions), $queryTokenNum as xs:integer ) as element(fts:allMatches) { if (fn:count($ftSelection/fts:matchOptions) > 0) then (: First we deal with all match options that the :) (: FTSelection might bear: we add the match options :) (: to the current match options structure, and :) (: pass the new structure to the recursive call. :) let $newFTSelection := <fts:selection>{$ftSelection/* [fn:not(self::fts:matchOptions)]}</fts:selection> return fts:evaluate($newFTSelection, $searchContext, fts:replaceMatchOptions($matchOptions, $ftSelection/fts:matchOptions), $queryTokenNum) else if (fn:count($ftSelection/fts:weight) > 0) then (: Weight has no bearing on semantics -- just :) (: call "evaluate" on nested FTSelection :) let $newFTSelection := $ftSelection/*[fn:not(self::fts:weight)] return fts:evaluate($newFTSelection, $searchContext, $matchOptions, $queryTokenNum) else typeswitch ($ftSelection/*[1]) case $nftSelection as element(fts:ftWords) return (: Apply the FTWords in the search context :) fts:ApplyFTWords($searchContext, $matchOptions, $nftSelection/@type, $nftSelection/fts:queryItem, $queryTokenNum + 1) case $nftSelection as element(fts:ftAnd) return let $left := fts:evaluate($nftSelection/fts:left, $searchContext, $matchOptions, $queryTokenNum) let $newQueryTokenNum := $left/@stokenNum let $right := fts:evaluate($nftSelection/fts:right, $searchContext, $matchOptions, $newQueryTokenNum) return fts:ApplyFTAnd($left, $right) case $nftSelection as element(fts:ftOr) return let $left := fts:evaluate($nftSelection/fts:left, $searchContext, $matchOptions, $queryTokenNum) let $newQueryTokenNum := $left/@stokenNum let $right := fts:evaluate($nftSelection/fts:right, $searchContext, $matchOptions, $newQueryTokenNum) return fts:ApplyFTOr($left, $right) case $nftSelection as element(fts:ftUnaryNot) return let $nested := fts:evaluate($nftSelection/fts:selection, $searchContext, $matchOptions, $queryTokenNum) return fts:ApplyFTUnaryNot($nested) case $nftSelection as element(fts:ftMildNot) return let $left := fts:evaluate($nftSelection/fts:left, $searchContext, $matchOptions, $queryTokenNum) let $newQueryTokenNum := $left/@stokenNum let $right := fts:evaluate($nftSelection/fts:right, $searchContext, $matchOptions, $newQueryTokenNum) return fts:ApplyFTMildNot($left, $right) case $nftSelection as element(fts:ftOrder) return let $nested := fts:evaluate($nftSelection/fts:selection, $searchContext, $matchOptions, $queryTokenNum) return fts:ApplyFTOrder($nested) case $nftSelection as element(fts:ftScope) return let $nested := fts:evaluate($nftSelection/fts:selection, $searchContext, $matchOptions, $queryTokenNum) return fts:ApplyFTScope($nftSelection/@type, $nftSelection/@scope, $nested) case $nftSelection as element(fts:ftContent) return let $nested := fts:evaluate($nftSelection/fts:selection, $searchContext, $matchOptions, $queryTokenNum) return fts:ApplyFTContent($searchContext, $nftSelection/@type, $nested) case $nftSelection as element(fts:ftDistance) return let $nested := fts:evaluate($nftSelection/fts:selection, $searchContext, $matchOptions, $queryTokenNum) return fts:ApplyFTDistance($nftSelection/@type, $nftSelection/fts:range, $nested) case $nftSelection as element(fts:ftWindow) return let $nested := fts:evaluate($nftSelection/fts:selection, $searchContext, $matchOptions, $queryTokenNum) return fts:ApplyFTWindow($nftSelection/@type, $nftSelection/@size, $nested) case $nftSelection as element(fts:ftTimes) return let $nested := fts:evaluate($nftSelection/fts:selection, $searchContext, $matchOptions, $queryTokenNum) return fts:ApplyFTTimes($nftSelection/fts:range, $nested) default return <fts:allMatches stokenNum="0" /> };
For concreteness, assume that the FTSelection was invoked
inside an contains text
expression such as
searchContext contains text ftSelection
. In order to
determine the AllMatches result of ftSelection
,
the fts:evaluate
function is invoked as follows:
fts:evaluate($ftSelection, $searchContext, $matchOptions,
0)
, where $ftSelection
is the XML
representation of the ftSelection
and
$searchContext
is bound to the result of the
evaluation of the XQuery expression searchContext
.
Initially, the $queryTokensNum
is 0, i.e., no query
tokens have been processed.
The variable $matchOptions
is bound to the list of
match options as defined in the static context (see Appendix
C Static Context
Components). Match options embedded in
$ftSelection
modify the match options collection as
evaluation proceeds.
Given the invocation of: fts:evaluate($ftSelection,
$searchContext, $matchOptions)
, evaluation proceeds as
follows. First, $ftSelection
is checked to see whether
1) it contains a match option, 2) it contains a weight
specification, 3) it is an FTWords, or 4) none of the above
hold.
If $ftSelection
contains one or more match options,
these are combined with the inherited match options via a call to
fts:replaceMatchOptions
(see 4.2.5 Match Options Semantics). The
evaluate
function is then invoked on the nested
FTSelection with the new set of match options, and the
result of that call is returned.
If $ftSelection
contains a weight specification,
then the specification is ignored because it does not alter the
semantics. The evaluate
function is recursively called
on the nested FTSelection and the resulting
AllMatches is returned.
If $ftSelection
is an FTWords, then it does
not have any nested FTSelections. Consequently, this is the
base of the recursive call, and the AllMatches result of the
FTWords is computed and returned. The AllMatches is
computed by invoking the ApplyFTWords
function with
the current search context and other necessary information.
If $ftSelection
contains neither a match option nor
a weight specification and is not an FTWords, the
FTSelection performs a full-text operation, such as
ftand
, ftor
, window
. These
operations are fully-compositional and may be invoked on nested
FTSelections. Consequently, evaluation proceeds as
follows.
First, the evaluate
function is recursively invoked
on each nested FTSelection. The result of evaluating each
nested FTSelection is an AllMatches.
The AllMatches are transformed into the resulting
AllMatches by applying the full-text operation corresponding
to FTSelection1
which is generically named
applyX
for some type of FTSelection X in the
code.
For example, let FTSelection1
be FTSelection2
ftand FTSelection3
. Here FTSelection2
and
FTSelection3
may themselves be arbitrarily nested
FTSelections. Thus, evaluate
is invoked on
FTSelection2
and FTSelection3
, and the
resulting AllMatches are transformed to the final
AllMatches using the ApplyFTAnd
function
corresponding to ftand
.
The semantics of the ApplyX
function for each
FTSelection kind X is given below.
An FTWords that consists of a single query string
consisting of a sequence of token to be matched as a phrase is
evaluated by the applyQueryTokensAsPhrase
function.
Its parameters are 1) the search context, 2) the list of match
options, 3) the query string to be matched as a sequence of
fts:queryToken
items, and 4) the position where the
latter query string occurs in the query.