API search

The Xtended Search tool can allow you to perform searches obviously from the interface but also from a development.

It therefore provides you with a query API allowing you to perform searches in source data from your codes.

This can be particularly interesting because:

  • You benefit from a simple query API
  • You can therefore request a source data (with excellent performance and without memory increase)

The API presented here constitutes an evolution of the product which appears from version 1.4.7 (VDoc 11 compatible version). It cannot be used in previous versions.

Instantiating an ISearchModule

Instantiating a search module requires:

  • A search name
  • A context

Eventually, it will be possible to pass in addition to the input parameters (optional); these parameters will be merged with the “parameters” of the search.

ISearchModule iSearchModule = SearchHelper.getSearchModule(iContext, null, "MyNiceSearch");

Module release

SearchHelper.releaseModule(iSearchModule);

Adding constraints

You can then build the constraints that will define your filtering.

Constraints can be dropped:

  • On system customtags
  • On system customtags of an indexing class
  • On other customtags

To access the system customtags, you can use the ICustomTag interface.

It will also be possible to define or not the search operator (if nothing is defined, we will use “equals”).

To access the different operators, you can use the ISearchOperator interface.

iSearchModule.addConstraint(ICustomTag.System.REFERENCE, "test");
iSearchModule.addConstraint("annee", ISearchOperator.MINOR, new Float(1950));
ArrayList cDate = new ArrayList();
cDate.add(date1);
cDate.add(date2);
iSearchModule.addConstraint(ICustomTag.System.CREATIONDATE, ISearchOperator.BETWEEN, cDate);

Note on filtering value : the type passed will depend on the type of the customtag :

  • text : java.lang.String
  • number : java.lang.Float
  • date : java.util.Date
  • boolean : java.lang.Boolean
  • file : com.axemble.axvdocsearch.core.beans.File

If the tag is a “collection” or if we manage an “interval”, we can pass an ArrayList of the desired elements.

The ICustomTag interface includes a System subinterface with the names of general system customtags. There are also interfaces for each indexing class with their respective system customtags.

ICustomTag.BaseDirectoryUserIndexExtension.ORGANIZATION_NAME
ICustomTag.BaseDMVersionsSQLIndexExtension.DATA
ICustomTag.BaseFileCenterIndexExtension.FOLDER
...

Search evaluation method and return

The “evaluate” method will allow you to run the search and retrieve the results.

One can optionally provide the input method with a particular filtergroup. If the search does not have a filtergroup, this is not necessary. It is also possible to leave it blank even if the search includes filtergroups, the system will then choose the filtergroup by default.

The search method will return a Document Collection Map. Why this type of return?

We have a Collection Map because there can be a return sorted by ResultGroup if we have a ResultGroups configuration in place on the search. Thus, if we have this type of configuration, we have for each resultgroup an entry in the Map. If we have no configuration of this type, we have a “default” entry in the Map which integrates the Document Collection.

The Document represents an indexed element with its values for system custom tags and for other custom tags.

Concrete example of an agent

public class ExecuteSearchAgent extends BaseAgent {
	protected static final Logger log = Logger.getLogger(ExecuteSearchAgent.class);
    
	@Override
	protected void execute() {
		IContext iContext = getWorkflowModule().getContextByLogin("sysadmin");
		ISearchModule iSearchModule = SearchHelper.getSearchModule(iContext, null, "MyNiceSearch");
		try {
			iSearchModule.addConstraint("date", ISearchOperator.AFTER, aDate);
			iSearchModule.addConstraint("annee", ISearchOperator.MINOR, new Float(1950));
			iSearchModule.addConstraint(ICustomTag.System.FULLTEXT, ISearchOperator.CONTAINS, "nice car");

			Map<String, ArrayList<Document>> mCDocument = iSearchModule.evaluate();
			if ( (mCDocument != null) && (!mCDocument.isEmpty()) ) {
				ArrayList<Document> cDocument = mCDocument.values().iterator().next();
				for (Document document : cDocument) {
                    log.error("Document named '" + document.getReference() + " - " + document.getTitle() + "' is a result of my search !");
                }
			}
		} catch (Exception e) {
			String message = e.getMessage();
            if (message == null) {
                message = "";
            }
            log.error("Error in ExecuteSearchAgent execute method : " + e.getClass() + " - " + message);
		} finally {
			SearchHelper.releaseModule(iSearchModule);
		}
	}
}

Additional method, remarks

Normalization

Xtended Search maintains two copies of each indexed text:

  • A certified copy
  • A normalized copy (without special characters and accents)
  • By default, your constraints are set on the certified copy but you have a definition of the addConstraint method available to work on the standardized version.

At this point, you will also need to normalize your search filter so that the filtering is consistent, then you have on the searchModule a method called buildNormalizedString available.

iSearchModule.addConstraint("ChampTexte", ISearchOperator.CONTAINS, iSearchModule.buildNormalizedString("Fêtes de Noël"), true);

Note that it is not necessary to declare each custom tag for filtering. It is thus possible to filter on any indexed element even if it is not presented in your search.

The logic is of course similar for the results view. The API will return you the set of documents corresponding to your filtering and it is therefore not necessary to configure the columns of a results view.

Search extensions

If your search includes a search extension, it will also be called via our API execution (not on presentation view events).

Source : https://wiki.myvdoc.net/xwiki/bin/view/Dev+Floor/UseSearchAsAPI