magnifierAllows querying the XWiki Model using a variety of query languages
Developed by

XWiki Development Team

0 Votes
LicenseGNU Lesser General Public License 2.1
Bundled With

XWiki Enterprise, XWiki Enterprise Manager


All data making up the XWiki application can be queried using one of the supported Query languages. Right now we support 2 languages:

Historically XWiki was only supporting HQL but that lead to complex queries in some instances and thus we've introduced XWQL which is a JPQL superset and which makes it much easier to write queries for the XWiki model, as you can see in the examples below.

The Query Module is only designed for READ-only queries. If you need to write something in the database, you should use the XWiki API.

Query Language Examples

Before 7.2 all queries starting with select require programming rights to execute.
Query DescriptionXWQLHQL
Query listing all documents<empty query><empty query>
Query listing all documents created after a given date

where doc.creationDate > :date

Full example:

$services.query.xwql("where doc.creationDate > :date").bindValue('date', $datetool.toDate('yyyy-MM-dd', '2008-01-01')).execute()

where doc.creationDate > :date

Full example:

$services.query.hql("where doc.creationDate > :date").bindValue('date', $datetool.toDate('yyyy-MM-dd', '2008-01-01')).execute()

Query listing all documents last updated by a given userwhere = 'XWiki.LudovicDubost'where = 'XWiki.LudovicDubost'
Query listing all documents containing XWiki Objects (XObject) of a given XWiki Class (XClass)from doc.object(XWiki.XWikiUsers) as user, BaseObject as obj where doc.fullName = and obj.className = 'XWiki.XWikiUsers'
Query on XObjects and filtering on XObject property valuewhere = 'XWiki.LudovicDubost' and doc.object(XWiki.XWikiUsers).email like '', BaseObject as obj, StringProperty as prop where doc.fullName = and obj.className = 'XWiki.XWikiUsers' and and'email' and prop.value like '' and ='XWiki.LudovicDubost'
Query on 2 XObjectswhere doc.object(XWiki.XWikiUsers).email like ''  and  doc.object(XWiki.ArticleClass).content like '%ludovic%', BaseObject as obj, StringProperty as prop, BaseObject as obj2, LargeStringProperty as contentprop where doc.fullName = and obj.className = 'XWiki.XWikiUsers' and and'email' and prop.value like '' and and obj2.className='XWiki.ArticleClass' and and'content' and contentprop.value like '%ludovic%'
Search blogs per category (MyCategory)where doc.fullName <> 'XWiki.ArticleClassTemplate' and :category member of doc.object(Blog.BlogPostClass).category #set ($category = "blog.MyCategory")
, BaseObject as obj, DBStringListProperty as prop join prop.list list where and obj.className='Blog.BlogPostClass' and<>'Blog.BlogPostTemplate' and and'category'  and list='${category}' order by doc.creationDate desc
List all tagsselect distinct obj.tags from Document doc, doc.object(XWiki.TagClass) as objselect distinct tag from BaseObject as obj, DBStringListProperty as prop join prop.list as tag where obj.className='XWiki.TagClass' and and'tags'
List all blog posts, published and not hidden (filter by multiple properties of an object)from doc.object(Blog.BlogPostClass) as blog where blog.published = '1' and :category member of blog.category and blog.hidden = '0' and doc.web = 'Blog' order by blog.publishDate desc, BaseObject as obj, IntegerProperty publishedProp, IntegerProperty hiddenProp, DateProperty publishDateProp, DBStringListProperty as categoryProp join categoryProp.list list where and obj.className='Blog.BlogPostClass' and = 'Blog' and and'category' and list='$category' and = and = 'published' and publishedProp.value = '1' and = and'hidden' and hiddenProp.value = '0' and = and'publishDate' order by publishDateProp.value desc
List documents having at least tags tag1 and tag2from doc.object(XWiki.TagClass) as tag where  'tag1' member of tag.tags and  'tag2' member of tag.tags, BaseObject as obj, DBStringListProperty as prop join prop.list item where obj.className='XWiki.TagClass' and and and'tags' and (lower(item)=lower('tag1') and (lower(item)=lower('tag2'))
Make a join between two objects that are not on the same document and are bound by a propertyfrom doc.object('Space.Class') as obj, Document doc1, doc1.object('Space.Class1') obj1 where obj.prop1 = doc1.fullName and obj1.prop2 like '%text%' order by obj1.prop3TODO
List child spaces (7.2+)select from XWikiSpace as space where space.parent = 'Parent Space'same
List the nested documents that contain 'wiki' in their name (7.2+)from XWikiSpace as space where = space.reference and (( <> 'WebHome' and lower( like '%wiki%') or ( = 'WebHome' and lower( like '%wiki%')), XWikiSpace as space where = space.reference and (( <> 'WebHome' and lower( like '%wiki%') or ( = 'WebHome' and lower( like '%wiki%'))
List all nested documents in the space "Space"where like 'Space' or like 'Space.%'same
Note that when using XWQL, it's mandatory to use aliases when filtering for multiple properties of an object; it's not possible to use the abbreviated syntax doc.object(Blog.BlogPostClass).propertyName multiple times in the same query. 

Performing Queries

The principle is to get a reference to the Query Manager, then call a method on it to create a Query for a given Query language. Then on the Query object you can set some behaviors (limit the number of returned result, bind variables, set the offset, set the wiki on which to execute the query) and then execute it.

From Velocity


  • Return all the results matching the XWQL statement:
  • Return only 5 results at most:
  • Set the starting offset (starts at result number 5 and beyond):
  • Set the wiki on which to run the query (requires Programming Rights before XWiki 4.1):
  • You can add filters to apply to the query and multiple filters can be added to a query.
    • The hidden filter will exclude documents marked as hidden from the query results, except if the user has chosen to see hidden documents in his profile preferences:
    • The unique filter will make sure you don't get duplicate results with a short-form query:
    • The count filter allows to transform a short-form query into a count of the distinct results it would return. Unfortunately this doesn't work with XWQL on versions older than 4.4.1:
      ## You can also use the following shortcut
    • The language filter will transform the query to also return document languages (the result you'll get is List<Object[]> with Object[0] being the document name and Object[1] being the document language, e.g. en, fr, fr_FR, etc): New in 5.1
    • The currentlanguage filter will only return documents in the current language: New in 5.1
  • Bind a value:
    $services.query.xwql("xwqlstatement containing :var").bindValue("var", "value").execute()

    Specific example that will return all documents that have comments containing the test string:

    $services.query.xwql("select doc.fullName from Document doc, doc.object(XWiki.XWikiComments) com WHERE doc.translation = 0 and com.comment LIKE :value").bindValue("value", "%test%").execute()

    You can also bind a list or an array to a query parameter: New in 6.0

    #set ($query = $services.query.xwql('where in (:myList)'))
    $query.bindValue('myList', ['Activity', 'BlogPostClass', 'Welcome']).execute()
  • Behaviors can be chained:

For HQL:


The information above is valid starting with XWiki Platform 2.4M2. Before that you had to use the following which is now deprecated:

## For XWQL
## For HQL
$xwiki.queryManager.createQuery("hqlstatement", "hql").execute()

From other Scripting languages

For XWQL (example with Groovy):


For HQL:


From Java components

Get a QueryManager injected. For example :

private QueryManager queryManager;

Obtain and execute a query :

this.queryManager.createQuery(statement, Query.XWQL).execute();


Query query = this.queryManager.createQuery("select,, from XWikiDocument doc, BaseObject obj where and obj.className='XWiki.WikiMacroClass'");
List<Object[]> results = (List<Object[]>) (List) q.execute();
for (Object[] wikiMacroDocumentData : results) {
    String space = (String) wikiMacroDocumentData[0];
    String name = (String) wikiMacroDocumentData[1];
    String author = (String) wikiMacroDocumentData[2];

XWQL Implementation Details

The XWQL grammar is defined here.

Note that currently the XWQL implementation translates queries into HQL which are then executed using Hibernate against the RDBMS.

XWiki-specific extensions in XWQL over JPQL

  • Short form queries:
    • where <expr> means select doc.fullName where <expr>
    • from <fromlist> [where <expr>] means select doc.fullName from Document as doc, <fromlist> [where <expr>]
  • Special syntax for XWiki objects in from and where clauses:
    • from doc.object(Class) as obj
    • where doc.object(Class).prop = 'something'

    The class name must be quoted if it contains special characters (e.g. Unicode). Both single and double quotes can be used.

Note that any JPQL query is a correct XWQL query. This also means almost any HQL query (HQL is a JPQL superset) will work with XWQL (when executed on the XWiki Hibernate store).

Noteworthy differences between XWQL and HQL

 Like statement can't be transformed in XWQL  where upper( like 'WEBHOME'  where upper( like upper('webhome')  The string_expression must have a string value. The pattern_value is a string literal or a string-valued input parameter

Using the XWiki object (Deprecated)

This is now deprecated in XWiki Enterprise 2.4 in favor of the Query Manager but it's still supported and XWiki's code itself is still using this manner as we're gradually moving to using the Query Manager.

See the Velocity HQL Guide (till we incorporate it back in this guide).

Tags: development
Created by Vincent Massol on 2010/06/21 11:18

Get Connected