The search server web application is responsible for providing searching and browsing functionality for both the storefront and the Commerce Manager (CM) client. At its heart is the Solr search engine, which sits on top of the Lucene indexes. If you wanted to leverage Solr's powerful search capabilities, you could use the Solr search APIs. However, these APIs require extensive knowledge of Solr syntax. Another option might be to use JPQL, which is basically an object oriented SQL. But this requires some JPQL specific knowledge to be able to retrieve data from the database.
In Elastic Path 6.1, a new set of APIs were created to allow developers to create complex, platform-independent search queries using a familiar syntax, but with the added benefits of an ecommerce domain-specific language. The new Elastic Path Query Language (EPQL) gives us the ability to be technology independent and makes the system more flexible.
The advanced search feature was introduced in Elastic Path Commerce 6.1, with the ability to handle products, categories, and catalogs initially. Its architecture, however, is extensible, and in the future, it will support searching for other types of domain objects, such as price lists, orders, and customers. The advanced search functionality is currently available within the CM client and the import-export tool. The CM client integration supports only products at this time, while the import-export tool can use advanced search for looking up sets of products, categories, and catalogs.
Advanced search is provided as a library that can be used into any application or a standalone program.
The syntax of the Elastic Path Query Language (EPQL) resembles the SQL language. A simple query consists of a single expression. An expression has the following form:
FIND Product WHERE <field> <operator> <value>
where
- <field> is the field you are searching. For example, if you want to look for products of a specific brand, you would include the BrandCode field in your query. The supported fields are described in Supported fields further in this article.
- <operator> is the operator you are using to perform the comparison.
- <value> is the literal value you want to compare to the field value.
For example, the following query matches the product whose code is 10030205
FIND Product WHERE ProductCode = '10030205' |
In addition to searching for field values, you can also search for attribute values. To search for a value in an attribute, the expression has the following form:
Attribute{<attribute_name>} <operator> <value>
where <attribute_name> is the name of a product attribute or product SKU attribute.
For example, the following query matches all products that have the Header / Model attribute set to MX:
FIND Product WHERE Attribute{Header / Model} = 'MX' |
Here is a more complicated query that finds all Nike and Adidas products that cost less than $200 USD and belong to catalog A:
FIND Product WHERE Catalog = 'A' AND Price{A}[USD] < 200 AND (BrandName [en] = 'Nike' OR BrandName [en] = 'Adidas') |
You can run queries immediately using the CM client's UI. This is convenient for testing, but it doesn't allow you to schedule actions on the query results. Let's say you want to perform a daily action on products that match the criteria in the previous example. To do that, you would need to create a class that retrieves the products using EPQL and sends that information to a third party system for processing.
To use the EPQL search APIs, you need to add com.elasticpath.core.jar and com.elasticpath.ql.jar file to your project's classpath.
Next, add the required Spring bean definitions. Create a file named serviceEPQL.xml in the project's conf/spring/service folder and add a reference to it from the Spring application-context.xml. For an example, take a look at the com.elasticpath.cmclient.core RCP plugin or the import/export tool.
Create a Java class that will be used to retrieve the products using EPQL. The following code shows how to execute an EPQL query:
public boolean doDailyTask() { // get a search engine instance EpQLSearchEngine searchEngine = getElasticPath().getBean("epQLSearchEngine"); // create a query String searchString = "FIND Product WHERE Catalog = 'A' " + "AND Price{A}[USD] < 200 AND (BrandName [en] = 'Nike' " + "OR BrandName [en] = 'Adidas')"; // get a parser and use it to validate the query EPQueryParser parser = searchEngine.getEpQueryParser(); try { parser.verify(query); } catch (EpQLParseException exception){ LOG.warn(exception); return false; } // if the query is okay, execute it and get the results SolrIndexSearchResult result = searchEngine.search(searchString); List<Long> productUids = result.getSearchResults(); // ... Do some processing on the results return true; } |
The EpQLSearchEngine class has a search method that executes a query and returns the results. Before executing a query, you should make sure that it is syntactically valid.
The EPQLQueryParser class provides a verify method that takes a query string as an argument. If there's an error in the query, it throws an exception, including a detailed description to help you fix the problem. The search result set contains the list of UIDs of the objects that matched the query.