Embedding Oak Index Configurations into a Package

Embedding Oak Index Configurations into a Package

AEM 6 ships with a new repository, CRX3 which is based on Apache Oak, a subproject of the Apache Jackrabbit project.  This repository promises significant performance increases over CRX2, however it does require a bit more work to setup. 

Unlike CRX2, CRX3 requires you to explicitly declare which fields will be indexed.  If a field is not indexed, you will see an error like the one below in the error.log and significant performance degredation:

16.01.2015 13:56:45.206 *WARN* [0:0:0:0:0:0:0:1 [1421434528059] GET /content/client/en/products/product.3.json HTTP/1.1] org.apache.jackrabbit.oak.spi.query.Cursors$TraversingCursor Traversed 660000 nodes with filter Filter(query=SELECT * FROM [client:type] AS s WHERE ISCHILDNODE('/etc/catalog/products/PRODUCTID') UNION SELECT * FROM [client:type] AS s WHERE [client:id] = 'PRODUCTID', path=*, property=[client:id=PRODUCTID]); consider creating an index or changing the query

To to correct this issue and restore acceptable performance, you should configure your Oak Index to add the required properties.  Adobe has already produced good information on this, as well as a nifty tool for seeing the indexes. But how do you go ahead and package this up as part of your project?  It's pretty simple, just do the following:

  1. Create a folder _oak_index inside the content package for your project.  The reason for the name is that oak:index is not a valid folder name on Windows.
  2. Create a file .content.xml and add in something like this:
    <?xml="1.0"encoding="UTF-8"?>
    <jcr:rootxmlns:oak="http://jackrabbit.apache.org/oak/ns/1.0"xmlns:jcr="http://www.jcp.org/jcr/1.0"xmlns:nt="http://www.jcp.org/jcr/nt/1.0"xmlns:st="http://www.st.com/nt/st"
            jcr:primaryType="nt:unstructured">
            <myNodeType
                    jcr:primaryType="oak:QueryIndexDefinition"
                    declaringNodeTypes="{Name}[my:NodeType]"
                    propertyNames="{Name}[my:idProperty,my:titleProperty]"
                    type="property"/>
            <myNodeType2
                    jcr:primaryType="oak:QueryIndexDefinition"
                    declaringNodeTypes="{Name}[my:NodeType2]"
                    propertyNames="{Name}[my:idProperty2,my:titleProperty2]"
                    type="property"/>
    </jcr:root>
    One thing to note which caught me the first time, is that the declaringNodeTypes and propertyNames must be of type Name, not just String.
  3. Add in something like this into your package's filter.xml:
    <workspaceFilter version="1.0">
        [...]
        <filter root="/oak:index/myNodeType"/>
        <filter root="/oak:index/myNodeType2"/>
    </workspaceFilter>

Once you install your packages, your new oak indexes will appear and be ready for use. I'd recommend reindexing manually as you don't want this to occur with every package deployment.

Update - As per @davide and @AlexanderKlimetschek updated the log message to be the correct one showing the un-indexed node traversal.

Share this post

0 Comments

comments powered by Disqus