This encapsulates the execution of search against different indexing mechanisms. Solr provides indexing of metadata and the plain text of content. This can be queried using various query languages. The query languages supported include:
- LANGUAGE_FTS_ALFRESCO
- LANGUAGE_CMIS_ALFRESCO
- LANGUAGE_CMIS_STRICT
- LANGUAGE_LUCENE
- LANGUAGE_SOLR_ALFRESCO
- LANGUAGE_SOLR_CMIS
- LANGUAGE_SOLR_FTS_ALFRESCO
- LANGUAGE_XPATH
Alfresco Full Text Search (FTS) is Alfresco’s native query language. It supports searching by single term, phrase, exact term, term expansion, conjunctions, disjunctions, negation, optional, mandatory, excluded, fields, wildcards, ranges, fuzzy matching, proximity, boosts and grouping. For example: ASPECT:'cm:titled' AND cm:title:'*Sample*' AND TEXT:'code'
A CMIS query is based upon SQL-92. The query is read-only and presents no data manipulation capabilities. The CMIS specification supports a subset of Alfresco FTS, which can be embedded in CMIS-SQL using the contains() predicate function. CMIS query example: SELECT * FROM cm:titledWHERE cm:titlelike '%Sample%' AND CONTAINS('code')
Examples using the SearchService languages FTS and CMIS:
ResultSet results = serviceRegistry.getSearchService().query(storeRef, SearchService.LANGUAGE_FTS_ALFRESCO, "ASPECT:'cm:titled' AND cm:title:'*Sample*' AND TEXT:'code'"); results = serviceRegistry.getSearchService().query(storeRef, SearchService.LANGUAGE_CMIS_ALFRESCO, "SELECT * FROM cm:titledWHERE cm:titlelike '%Sample%' AND CONTAINS('code')");
Using SearchService to get a NodeRef for an XPath (as seen in NodeBrowser) using language LUCENE:
/** * Get a NodeRef by its path. * * @path as displayed by the NodeBrowser. * @return the NodeRef, or null if no NodeRef matches this path. */ private NodeRef getNode(String path) { ResultSet results = null; try { StoreRef storeRef = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore"); results = serviceRegistry.getSearchService().query(storeRef, SearchService.LANGUAGE_LUCENE, "PATH:\"" + path + "\""); if (results.length() == 0) { logger.debug("Zero matches for path: " + path); returnnull; } NodeRef nodeRef = results.getNodeRef(0); logger.debug("NodeRef for \"" + path + "\" is " + nodeRef); return nodeRef; } catch(Exception e) { logger.debug("Exception while searching for path: " + path, e); returnnull; // The node does not exist } finally { if (results != null) { results.close(); } } }
Use this method as in the following example:
NodeRef someNodeRef = getNode("/app:company_home/app:shared/cm:abc/cm:def/cm:My_x0020_Document.txt");
Map<String,Serializable> params = new HashMap<>(); params.put("query", "/app:company_home/app:shared/cm:abc/cm:def/cm:My_x0020_Document.txt"); NodeRef nodeRef = serviceRegistry.getNodeLocatorService().getNode("xpath",null,params);
If the search result is getting big you can use paging. There are two ways to query with the SearchService (excluding the selectNodes/selectProperties calls). One way is to specify all your arguments directly to the query method as seen above. This has the advantage of being concise, but the disadvantage is that you don’t get all the options. Alternately, you can query with a SearchParameters object. This lets you do everything the simple query does, and more. Included in that more are setLimit, setSkipCount and setMaxItems, which will allow you to do your paging.
If your query used to be something like:
serviceRegistry.getSearchService().query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_LUCENE, myQuery);
You would instead do something like this:
SearchParameters sp = new SearchParameters(); sp.addStore(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE); sp.setLanguage(SearchService.LANGUAGE_LUCENE); sp.setQuery(myQuery); sp.setMaxItems(100); sp.setSkipCount(100); // Execute query. ResultSet resultSet = serviceRegistry.getSearchService().query(sp); for (NodeRef result : resultSet.getNodeRefs()) { // Do stuff } resultSet.close();
Set up search params with unlimited results and sorting on cm:modified property (might not always be a good idea with unlimited result, unless you know approximately how many nodes will be the limit):
SearchParameters sp = new SearchParameters(); sp.addStore(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE); sp.setLanguage(SearchService.LANGUAGE_LUCENE); // Can be lucene, FTS, CMIS, etc. sp.setQuery(myQuery); sp.setMaxItems(Integer.MAX_VALUE); sp.setMaxPermissionChecks(Integer.MAX_VALUE); sp.addSort("@" + ContentModel.PROP_MODIFIED, false); // Execute query. ResultSet resultSet = serviceRegistry.getSearchService().query(sp); for (NodeRef result : resultSet.getNodeRefs()) { // Do stuff } resultSet.close();
See also the Full Text Search Reference section in the Alfresco Search Services documentation.