To begin writing queries, you must understand the query language concepts, syntax, and grammar. These sample queries cover item types, text searches, arithmetic operations in conditions, traversal of links and references, checked out items, and querying by timestamp.
For more information about attribute names and display names, see the SAttributeDefinitionCreationICM and SSearchICM API education samples.
The sample queries provided in this section are based on the sample data model, Figure 1, and the sample XML document.
The IN operator is used with literals (integer, float, string), and should be used to match an attribute with a set of possible values. Using IN instead of multiple equality or inequality predicates connected through OR operators result in shorter queries. The IN operator should be used if existing queries cause a DK_ICM_MSG_QL_TOO_LONG_OR_TOO_COMPLEX exception.
To search for a journal that has 4, 8, or 12 pages, the search string without the IN operator:
/Journal[(@NumPages = 4) OR (@NumPages = 8)
OR (@NumPages = 12)]
To search for a journal that has 4, 8, or 12 pages, the search string with IN operator is:
/Journal[@NumPages IN (4,8,12)]
To search for books written by authors with last names other than Smith or Jones, the search string without the IN operator:
/Book[Book_Author[(@LastName != “Smith”)
AND (@LastName != “Jones”)]]
To search for books written by authors with last names other than Smith or Jones, the search string with the IN operator:
/Book[Book_Author[@LastName NOT IN (“Smith”, “Jones”)]]
/Journal
The / starts at the
implicit root of the XML document, which in this case is the entire
library server. Each item type is an element under this root. If LS.xml is
the XML document that contains the entire model as described earlier,
then the explicit document root is document (LS.xml)./Journal[@NumPages=50]
The
predicate @NumPages = 50 evaluates to true for all
journals that have the attribute NumPages set to 50.(/Book | /Journal)
[(.//Journal_Author/@LastName = “Williams”
OR .//Book_Author/@LastName = “Williams”)
AND (.//Book_Section/@Title LIKE “XML%”
OR .//Journal_Section/@Title LIKE “XML%”)]
OR(/Book[.//Book_Author/@LastName = “Williams”
AND .//Book_Section/@Title LIKE “XML%”])
| (/Journal[.//Journal_Author/@LastName = “Williams”
AND .//Journal_Section/@Title LIKE “XML%”])
The previous
two queries produce the same result. .//Journal_Author means
that a component Journal_Author should be found either
directly under the current component in the path (which in the first
case is either a Book or a Journal)
or somewhere deeper in the hierarchy. Note that the LIKE operator
is used in conjunction with a wildcard character, in this case %./Journal[@NumPages BETWEEN 49-4 AND 2*100]
Note
that you can perform arithmetic operations to calculate the resulting
values to be used with the BETWEEN operator.If you are looking for all journals with the number of pages between 10 and 200, you can use the BETWEEN operator available in the query language.
“/Journal [@NumPages BETWEEN 10 AND 200]”
The values that are used with the BETWEEN operator are included in the range, meaning that the lower bound includes the value of 10 and the upper bound includes the value of 200.
The use of the BETWEEN operator should make your query more easy to read, especially if multiple query conditions are used in the same query string. The BETWEEN operator can be used not only with attributes of numeric types, but also with attributes of other types (for example, date, string).
/SIG[@Title = “SIGMOD”]/OUTBOUNDLINK
[@LINKTYPE = “contains”]/@TARGETITEMREF =>
Journal[Journal_Editor/@LastName = “Williams”]
/Journal_Article
This is an example of following links
in the forward direction. The virtual XML component OUTBOUNDLINK and
its attribute TARGETITEMREF are used to traverse
to all Journals and then finally the underlying Journal_Articles.
The last component in the path is what is returned as the result of
the query. The result can be constrained by traversing only specific
link types (contains in this example) to a specific
type of items (Journal in this example). Since the
conceptual XML representation of the library server looks at inbound
and outbound links as being parts of items, the dereferencing operator
can be used to relieve applications from writing explicit joins./Journal[@Cost < 5
AND .//Journal_Author/@LastName = “Nelson”]
/INBOUNDLINK[@LINKTYPE = “contains”]
/@SOURCEITEMREF => *
This is an example of following links
in the backward direction. The wildcard *, following
the dereference operator => ensures that items of ANY type
are returned as the result.In general, use basic text search in your applications whenever possible because the syntax works for all databases and search engines. Only use a specific search engine syntax if you need to make use of specific search engine features.
This query finds all journals that contain the text Java in the title, and sorts the results by title:
/Journal [contains-text-basic (@Title, “ ‘Java’ ”)=1] SORTBY (@Title)
This query finds all journal articles that contain the text Java and the text JDK 1.6 but not the text XML by using the simplified (basic) text search syntax and sort the results by the text search score:
//Journal_Article
[contains-text-basic(@Title, “ +Java -XML +‘JDK 1.6’”)=1]
SORTBY (score-basic(@Title, “ +Java -XML +‘JDK 1.6’ ”))
This is an example of performing text search by using the simplified text search syntax. Use a + to indicate the words or phrases that should be present in the attribute Title, and, similarly, use a - to exclude other words or phrases. The score-basic function works similarly to the score function in the previous example, but uses a simplified syntax.
The score-basic and the score functions support the SORTBY clause. However, the SORTBY clause can be used in many functions provided that they return a scalar result that can be used to sort the result. For example, the following query is valid for returning all versions of all journal items in the system sorted by length of the title attribute value:
/Journal SORTBY( LENGTH(@title) )
//Journal_Article[Journal_Author/@LastName = “Richardt”
AND contains-text-db2(@Text, “ ‘Java’ & ‘XML’ ”)=1]
SORTBY(score(@Text, “ ‘Java’ & ‘XML’ ”))
//Journal_Article[Journal_Author/@LastName = “Richardt”
AND contains-text-oracle(@Text, “ ‘Java’ & ‘XML’ ”, 1)>0]
SORTBY(score(1))
//Journal_Article[contains-text-db2ts(@Title, “ ‘Design’ OR ‘System’ ”)=1]
In DB2 Text Search, you can also append additional search argument options to the query:
Example of a query that uses these options (finds ten students at random who wrote online essays that contain the words "fossil fuel" in Spanish):
//STUDENT_ESSAYS[contains-text-db2ts(@TERM_PAPER, “combustible fosil”,
“QUERYLANGUAGE=es_ES RESULTLIMIT=10 SYNONYM=ON”)=1]
For
more information on IBM® DB2 Text Search, see DB2 Text Search./Journal
[Journal_Article[contains-text-db2(@Title, “ ‘Design’ |
‘Index’ ”)=1]]
SORTBY (@Title DESCENDING)
/Journal
[Journal_Article[contains-text-oracle(@Title, “ ‘Design’ |
‘Index’ ”)>0]]
SORTBY (@Title DESCENDING)
/Journal[Journal_Article[contains-text-db2ts(@Title, “ ‘Design’ OR
‘System’ ”)=1]] SORTBY (@Title)
/TextResource[contains-text-db2(@TIEREF, “ ‘Java’ & ‘XML’
”)=1]
/TextResource[contains-text-oracle(@TIEREF, “ ‘Java’ & ‘XML’
”)>0]
/TextResource[contains-text-db2ts(@TIEREF, “ ‘TConnectICM’ ”)=1]
/Conference/Conference_Note [@PublicationRef =>
Book[@Title LIKE “%CM%”]]
/Conference_FAQ
/Conference[@Title LIKE “%Internet%”]
/Conference_Note/@PublicationRef =>
*/Book_Chapter
/Book/REFERENCEDBY/@REFERENCER => *
/Book[@Title LIKE “XML”]/REFERENCEDBY/@REFERENCER =>
Conference_Note/Conference_FAQ
Note that since the reference
attributes originate inside of the Conference_Note component,
this is the component that must appear as the first component after
the dereference operator. This query produces an empty result set
if, for example, Conference follows the => operator./Book/REFERENCEDBY/@REFERENCER =>
*[@Remark LIKE “%XML%”]
/Journal[@VERSIONID = latest-version(.)]
/Conference/Conference_Note/@SYSREFERENCEATTRS =>
Book[@VERSIONID = latest-version(.)]
/Book/REFERENCEDBY/@REFERENCER => *
[@VERSIONID = latest-version(.)]
/*[@ITEMID =
“A1001001A01J09B00241C95000”]
/Doc[contains-text-db2(.//ICMPARTS/@TIEREF, “ ‘XML’ ”)=1]
/Doc[contains-text-oracle(.//ICMPARTS/@TIEREF, “ ‘XML’ ”)>0]
/Doc[contains-text-db2ts(.//ICMPARTS/@TIEREF, “ ‘XML’ ”)=1]
/Doc[@ArchiveID = 555]/ICMPARTS/
@SYSREFERENCEATTRS => *
//ICMPARTS/@SYSREFERENCEATTRS => *
Because
both the Doc and Paper item types have been defined as being Documents
in the system, the ICM Parts from both of them are returned in the
result. /*[@Title]
To
eliminate the restriction that only root components should be returned,
the query can be rewritten to start with a double-slash.//*[@Title]
/Journal[@Title = [Journal_Article/@Title,
.//Journal_Section/@Title,“IBM Systems Journal”]]
/Book[@Cost IN (10, 20, 30)]
Although
it is possible to perform the same query by using the list operator,
as in /Book[@Cost = [10, 20, 30]] (sub-optimal),
for a large number of literals this approach might lead to errors
because the generated SQL would be too long or too complex. If all
the elements in the list are literals, always use the IN operator
for the best performance and the shortest SQL. You can use the IN operator
for literals of any type, including non-numeric types. [/Journal, /Book[@Title = “Star Wars”]]
/Doc[Doc_Description/@PageSummary.NumPages >=
20]//Doc_Details
Note that if an attribute (for example, NumPages)
is contained in an attribute group (for example, PageSummary),
then you must refer to that attribute as GroupName.AttrName (for
example, PageSummary.NumPages). The attribute @NumPages would
not be found under Doc_Description./Journal [ICMCHECKEDOUT]
The ICMCHECKEDOUT XML
element is a sub-element of only the root components, but not of the
descendant components. Therefore, if the ICMCHECKEDOUT element
is written in a query as a condition of a child component (for example, //Journal_Author
[ICMCHECKEDOUT]), then no results return.Whenever an item is checked out, all versions of that item are checked out. Therefore, when an ICMCHECKEDOUT element is applied to a checked out item, all currently available versions will be returned. To retrieve a specific version, you can still use the @VERSIONID query syntax (for example, /Journal [ICMCHECKEDOUT AND @VERSIONID = 4]). For the latest version, you can use the latest-version() function.
/Journal [ICMCHECKEDOUT/@ICMCHKOUTUSER = “SMITH”]
The
value for ICMCHKOUTUSER must be entered in uppercase
in a query. Since the content servers store user IDs as uppercase,
all queries must query for user IDs by using uppercase. All attribute
data pertaining to user IDs must store them in uppercase as well./Journal [ICMCHECKEDOUT/@ICMCHKOUTTS > “2003-08-02-17.29.23.977001”]
This query searches XML documents with DB2 Text Search (DB2TS):
/Mimetype_XML[contains-text-db2ts(.//ICMPARTS/@TIEREF,
“ @xmlxp:‘‘//Extension’’ ”)=1]
This query sorts by three attributes, and does not require each attribute to exist on all of the item types. If the attribute does not exist, NULL is used for sorting.
(/Journal | /Book | /Conference ) SORTBY (@Title, @Organization, @PublishDate)
/*[@LASTCHANGEDUSERID] SORTBY (@Title)
You can also use the sorting attribute itself to define the scope. This query sorts only the item types that have the attribute Title:
/*[@Title] SORTBY (@Title)
When dealing with item holds, you must specify LINKTYPE=DKHold in the query string.
This query returns the on-hold items in a hold container:
/hold/OUTBOUNDLINK[@LINKTYPE =“DKHold”]/@TARGETITEMREF => * [@Title LIKE “Java%”]
This query gets all the holds for a held item:
/onhold/INBOUNDLINK[@LINKTYPE= “DKHold”]/@SOURCEITEMREF => *
If you need to query both Link and Hold related tables/items without specifying LINKTYPE, then set the query option DK_CM_PARM_USE_LINK_HOLD_UNION to true to force the query to access union view (which contains both hold and normal LINKTYPEs).
If a query string specifies more than one LINKTYPEs and one of them is DKHold, for example, @LINKTYPE IN (“DKHold”, “DkFolder”), then a union view table is used (which might have a performance impact).
