Indexing Queue

As soon as you include the Search add-on in your application, it starts tracking changes in your entities. In this section, we describe how to set up the automatic update of the Elasticsearch indexes with the new data.

The change tracking mechanism stores a queue of actions that should be done for changed entity instances in the the SEARCH_INDEXING_QUEUE database table. The IndexingQueueManager bean contains methods to process the queue and send changed data to Elasticsearch.

You should set up periodic processing of the indexing queue, otherwise the search will return stale data.

You can use Quartz Job Scheduler for periodic queue processing as described below.

Default Quartz Configuration

The Search add-on provides the default configuration of Quartz Job Scheduler. To process the indexing queue on a regular basis, do the following:

  1. Include Quartz in your project as described in the Quartz Job Scheduler Setup section.

  2. Change scheduling as CRON expression if necessary. The default value is 0/5 * * * * (every 5 seconds).

    jmix.search.indexingQueueProcessingCron = 0/10 * * * * ?

The default configuration creates and schedules a job with the IndexingQueueProcessing identity.

Custom Quartz Configuration

If you want to use a custom Quartz configuration, do the following:

  1. Include Quartz in your project as described in the Quartz Job Scheduler Setup section.

  2. Add the following property to the application.properties file to disable the default configuration:

    jmix.search.useDefaultIndexingQueueProcessingQuartzConfiguration = false
  3. Create custom job class that invokes IndexingQueueManager.processNextBatch():

    public class MyCustomQueueProcessingJob implements Job {
    
        @Autowired
        private IndexingQueueManager indexingQueueManager;
    
        @Override
        public void execute(JobExecutionContext context) throws JobExecutionException {
            indexingQueueManager.processNextBatch();
        }
    }
  4. Register the following beans in the application:

    @Bean
    JobDetail myCustomIndexingQueueProcessingJob() {
    	return JobBuilder.newJob()
    			.ofType(IndexingQueueProcessingJob.class)
    			.storeDurably()
    			.withIdentity("MyCustomIndexingQueueProcessing")
    			.build();
    }
    
    @Bean
    Trigger myCustomIndexingQueueProcessingTrigger() {
    	return TriggerBuilder.newTrigger()
    			.forJob(myCustomIndexingQueueProcessingJob())
    			.startNow()
    			.withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))
    			.build();
    }