h1. CMIS search and index {anchor:id=CONTref.Configuration.CMIS_search_indexRoleNotInToc}

The CMIS standard defines a query language based on a subset of the SQL-92 grammar (ISO/IEC 9075: 1992 -- Database Language SQL), with a few extensions to enhance its filtering capability for the CMIS data model, such as existential quantification for multi-valued property, full-text search, and folder membership.

{warning}
  CMIS search is disabled by default in eXo CMIS. Uncomment the _indexDir_ parameter if you need the query support in CMIS.
  To discover the search capability, check the _capabilityQuery_ property (see the [table|#CONTref.Configuration.Query_capabilities] below).
{warning}

{docbook}
<para xml:id="CONTref.Configuration.CMIS_relational_view">
<citetitle>
<emphasis role="bold">CMIS Relational View</emphasis>
</citetitle>
</para>
{docbook}

The relational view of a CMIS repository consists of a collection of virtual tables that are defined on the top of the CMIS data model. A virtual table exists for every _queryable_ object type (content type if you prefer) in the repository. Each row in these virtual tables corresponds to an instance of the corresponding object type (or one of its subtypes). A column exists for every property that the object type has.

{docbook}
<para xml:id="CONTref.Configuration.Query_capabilities">
<citetitle>
<emphasis role="bold">Query Capabilities</emphasis>
</citetitle>
</para>
{docbook}

|| *Capability* || *Value* ||
| _capabilityQuery_ | {{bothcombined}} (if _indexDir_ is configured, otherwise {{none}}) |
| _capabilityJoin_ | {{none}} |
| _capabilityPWCSearchable_ | {{false}} |
| _capabilityAllVersionsSearchable_ | {{false}} |


{docbook}
<para xml:id="CONTref.Configuration.CMIS_search_index.configuration">
<citetitle>
<emphasis role="bold">Configuration</emphasis>
</citetitle>
</para>
{docbook}

To be able to provide full-text search capabilities, xCMIS uses its own index. The following is the configuration parameter:

|| *Parameter* || *Default* || *Description* ||
| _indexDir_ | none | The location of the index directory. This parameter is mandatory for the default implementation. |


This parameter is passed through the XML configuration.

For example, to set up the index directory:
{code:xml}<component>
   <type>org.exoplatform.ecms.xcmis.sp.DriveCmisRegistry</type>
   <init-params>
         <!-- Disabled by default. Uncomment if you need query support in CMIS. -->
         <!-- value-param>
            <name>indexDir</name>
            <value>${gatein.jcr.index.data.dir}/cmis-index${container.name.suffix}</value>
         </value-param-->
         ..............
   </init-params>
</component>{code}

{docbook}
<para xml:id="CONTref.Configuration.Index_atomicity_durability">
<citetitle>
<emphasis role="bold">Index atomicity and durability</emphasis>
</citetitle>
</para>
{docbook}

* *Write-ahead logging*

To be able to provide index consistency and recovery in case of unexpected crashes or damages, XCMIS uses [write-ahead logging|http://en.wikipedia.org/wiki/Write-ahead_logging] (WAL) technique. Write-ahead logging is a standard approach to transaction logging. Briefly, WAL's center concept is changes of data files (indexes) must be written only after those changes have been logged, that is, when the change log records have been flushed to permanent storage. If you follow this procedure, you do not need to flush data pages to disk on every transaction commit, because it is known in the event of a crash, and the index can be recovered by using the log: any changes that have not been applied to the data pages can be redone from the log records. (This is roll-forward recovery, also known as REDO.)

A major benefit of using WAL is a significantly reduced number of disk writes, because only the log file needs to be flushed to disk at the time of transaction commit, rather than every data file changed by the transaction.

* *Recover uncommitted transaction*

When you start Indexer, it will check uncommitted transaction logs. If at least one log exists, recovering process will be started. Indexer will read all logs and extract added, updated and removed UUIDs into a set. Then, indexer walks through this set and checks objects against UUID. If the object exists, the indexer will put it into the added document list. In other cases, UUID will be added to the removed documents list. After that, depending on the list of added and removed documents, changes will be applied to the index.

* *Initial index population*

When you run the indexer to check the number of documents in the index. If there are no documents in the index or the previous re-indexation was not successful, then re-indexation of all content will be started. The first step is cleaning old index data. Uncommitted transaction logs and old persistent data are removed. These data are useless, because re-indexation of all content will be started. Then indexer walks throw all objects and makes lucene document for each one. Then batches with less than 100 elements will be saved to the index. After re-indexation, all logs (WAL) will be removed, all data mentioned on these change logs are already indexed.

{note}
  If the administrator gets an exception with the message "Can't remove reindex flag.", it means that the index restoring was finished but file-flag was not removed (see index directory, file named as "reindexProcessing"). You can manually remove this file-flag, and avoid a new reindex of repository on the JCR start.
{note}
