Applicable: | This tutorial applies to Confluence 7.17.0 or higher. |
Level of experience: | Advanced. You should complete at least one intermediate tutorial before working through this tutorial. |
The SearchIndexAccessor
is a V2-level Java API for accessing Confluence's indices and any custom search indices. You might be familiar with the similar SearchManager
,
however that interface is purely for searching, hence only provides a sub-set of functionality, and remains for legacy purposes.
A SearchIndexAccessor
can be obtained by creating a custom search index
or hooking into Confluence's existing search indices via Spring's dependency injection. Both the content index and change index are available to access.
However, being under the same interface, this will require explicitly qualifying the bean id using @Qualifier("changeIndexAccessor")
or @Qualifier("contentIndexAccessor")
.
Warning: If this is not done, your app may leak functionality or data which should not be visible for the current user.
Permissions checking should be done explicitly if required, as no permissions checking is promised by SearchIndexAccessor
.
Just like the SearchManager
, if permissions checks are required when searching, this must be explicitly done by adding a permissions checking query like SiteSearchPermissionsQuery
or by using the PredefinedSearchBuilder
to build an ISearch
which contains permissions checking.
Use constructor dependency injection to get access to the content index.
1 2public class AppService { private SearchIndexAccessor searchIndexAccessor; private SiteSearchPermissionsQueryFactory siteSearchPermissionsQueryFactory; public AppService(@ComponentImport @Qualifier("contentIndexAccessor") SearchIndexAccessor searchIndexAccessor, @ComponentImport SiteSearchPermissionsQueryFactory siteSearchPermissionsQueryFactory) { this.searchIndexAccessor = searchIndexAccessor; this.siteSearchPermissionsQueryFactory = siteSearchPermissionsQueryFactory; } ...
Construct SearchQuery
and perform a search against the content index.
1 2... public SearchResults search(String fieldName, String fieldValue) throws InvalidSearchException { SearchQuery query = BooleanQuery.builder() .addMust(new TermQuery(fieldName, fieldValue), siteSearchPermissionsQueryFactory.create()) .build(); ISearch search = new ContentSearch(query, null); return searchIndexAccessor.search(search, null); } ...
Execute a SearchIndexAction
against the content index. A SearchIndexAction
is a functional description of how to use a SearchIndexWriter
.
1 2... public void create(String fieldName, String fieldValue) { AtlassianDocument atlassianDocument = new AtlassianDocument(); atlassianDocument.addField(new StringFieldDescriptor(fieldName, fieldValue, FieldDescriptor.Store.YES)); searchIndexAccessor.execute(writer -> writer.add(atlassianDocument)); } ...
Scan the content index with a SearchQuery
, consuming the results by adding them to a List
.
1 2... public List<Map<String, String[]>> scan(String fieldName, String fieldValue) { SearchQuery query = BooleanQuery.builder() .addMust(new TermQuery(fieldName, fieldValue), siteSearchPermissionsQueryFactory.create()) .build(); List<Map<String, String[]>> results = new ArrayList<>(); searchIndexAccessor.scan(query, null, results::add); return results; } ...
Batch update the content index with the addition of two documents, one being a related companion document that must always exist alongside the parent.
1 2... public void create(String fieldName, String fieldValue) { String parentId = UUID.randomUUID().toString(); AtlassianDocument atlassianDocument = new AtlassianDocument(); atlassianDocument.addField(new StringFieldDescriptor(fieldName, fieldValue, FieldDescriptor.Store.YES)); atlassianDocument.addField(new StringFieldDescriptor("id", parentId, FieldDescriptor.Store.YES)); AtlassianDocument companionDocument = new AtlassianDocument(); atlassianDocument.addField(new StringFieldDescriptor("id", UUID.randomUUID().toString(), FieldDescriptor.Store.YES)); atlassianDocument.addField(new StringFieldDescriptor("parent", parentId, FieldDescriptor.Store.YES)); searchIndexAccessor.withBatchUpdate(() -> searchIndexAccessor.execute((writer) -> { writer.add(atlassianDocument); writer.add(companionDocument); }) ); } }
Learn more about extending Confluence's search capabilities with these tutorials:
Rate this page: