Getting Custom fields from Confluence V2 Searches

If you use an extractor module in your Confluence plugin to add additional information to the Lucene search index there is currently no way to access these fields using the V2 Search API. You can use these fields in custom search queries or sorts, but actually reading these fields from the returned data is not possible with the current API.

Limitations of the Current API

When you do a search using the V2 Search API the SearchManager.search(..) method Confluence will give you back a SearchResults object. You can then retrieve each of the individual SearchResult objects that matched your search.

The SearchResult interface contains a getExtraFields() method which is supposed to return additional fields that cannot be directly accessed by this interface. Unfortunately the LuceneSearchResult implementation has hardcoded the fields that are returned. This means that if you have an extractor module that has added custom fields to the index they can not be retrieved using the SearchResult interface.

Wrapping the SearchResult Object with custom implementation

If you look at the source code for the LuceneSearchResult class, you will see that all of the index document fields are stored in a private map called results. You can use java reflection to get access to this field within your own plugin classes.

The following example wraps the LuceneSearchResult providing access to the internal results field.

public class LuceneV2Result {

    static private Field resultsField;

    static {
        try {
            resultsField = LuceneSearchResult.class.getDeclaredField("results");
            resultsField.setAccessible(true);
        } catch (Exception e) {
            // :(
        }
    }

    Map<String, String> fields;
   

    @SuppressWarnings("unchecked")
    public LuceneV2Result(SearchResult result) {
        try {
            fields = (Map) resultsField.get(result);
        } catch (Exception e) {
            // :(
        }
    }
    
    public Map<String, String> getFields(){
    	return fields;
    }	
}

It should be noted that this implementation is highly likely to break in future releases if Atlassian change the internal implementation of this class. Hopefully by that time there will be a way to access custom extractor fields directly.

Was this page helpful?
Powered by Confluence and Scroll Viewport