Indexing and Query

Using CMISQL from Java

Updated: October 16, 2020

CMISQL is the CMIS Query Language. It's possible to make CMISQL queries from Java code inside a Nuxeo bundle, much in the same way that you may used to make NXQL queries.

You can find out more about the CMIS support in Nuxeo Platform on the CMIS Page. You can find more information on the CMISQL syntax in the CMIS specification.

Note that in Nuxeo CMISQL, JOINs are not enabled by default. They are only available if you set the nuxeo.conf property org.nuxeo.cmis.joins=true, and you are using the VCS storage backend. CMISQL JOINs are not supported with the DBS storage (MongoDB), because the underlying storage cannot do relational queries.

The following is a simple example of code making a query:

Constructing the CallContext

When constructing the CallContext, you should pass the ServletContextHttpServletRequest and HttpServletResponse if available from your context. These are important for rendition URLs for instance.

Making a CMISQL Query

import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.chemistry.opencmis.commons.enums.CmisVersion;
import org.apache.chemistry.opencmis.commons.server.CallContext;
import org.apache.chemistry.opencmis.server.impl.CallContextImpl;
import org.apache.chemistry.opencmis.server.shared.ThresholdOutputStreamFactory;
import org.nuxeo.ecm.core.api.CoreSession;
import org.nuxeo.ecm.core.api.IterableQueryResult;
import org.nuxeo.ecm.core.opencmis.bindings.NuxeoCmisServiceFactory;
import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoCmisService;

public class CMISQuery {

    /** Threshold over which temporary files are not kept in memory. */
    public static final int THRESHOLD = 1024 * 1024;

    public CallContext getCallContext(CoreSession session) {
        ServletContext servletContext = null; // pass this if available
        HttpServletRequest request = null; // pass this if available
        HttpServletResponse response = null; // pass this if available
        ThresholdOutputStreamFactory streamFactory = ThresholdOutputStreamFactory.newInstance(
                null, THRESHOLD, -1, false);
        CallContextImpl callContext = new CallContextImpl(
                CallContext.BINDING_LOCAL, CmisVersion.CMIS_1_1,
                session.getRepositoryName(), servletContext, request, response,
                new NuxeoCmisServiceFactory(), streamFactory);
        callContext.put(CallContext.USERNAME, session.getPrincipal().getName());
        return callContext;

    public void query(CoreSession session) {
        NuxeoCmisService cmisService = new NuxeoCmisService(session);
        cmisService.setCallContext(getCallContext(session)); // pass also servlet info if available
        try {
            // example CMISQL query
            String query = "SELECT cmis:objectId, dc:title FROM cmis:document WHERE dc:title LIKE 'foo%'";
            boolean searchAllVersions = true;
            IterableQueryResult result = cmisService.queryAndFetch(query, searchAllVersions);
            try {
                for (Map<String, Serializable> row : result) {
                    // do something with the result
            } finally { // you MUST always close result in a finally block
        } finally { // you MUST always close cmisService in a finally block




We'd love to hear your thoughts!

All fields required