What you don’t know about FlexibleSearch
Introduction
Generally, FlexibleSearch engine is well-documented on hybris wiki. However, as one of the oldest components of hybris, the engine has undocumented behavior that’s good to know about. In this article, I am going to talk about field and type modifiers, predefined named values. You will also learn about an interesting issue with the “order by” markers.Basic syntax
SELECT selects FROM types ( WHERE conditions ( ORDER BY order )? )?
Fields and modifiers
What you likely know about fields:- The field name is the hybris type attribute
- The field name is converted into the database table property (“code” => “p_code”)
- you can specify a type name before the attribute name (“Product.code”)
- type and attribute are separated by “.”
- type and attribute can be separated by “:” as well
- you can specify modifiers. Modifiers is a string that can contain the following letters: “c”, “l” or “o” or their uppercase equivalents. All other letters are ignored. Example: “Product:code:o”. \
- “c” stands for “core field”,
- “l” stands for “localized field”
- “o” stands for “optional”
Predefined Named Values
You should know that FlexibleSearch supports named values, a parameter that can be pushed into the statement from the code. But you likely don’t know that there are some predefined session attributes:- ?session.user,
- ?session.language,
- ?session.currency
String queryStr = "select {code}, ?language.isocode from {Product} order by {name}";
FlexibleSearchQuery query = new FlexibleSearchQuery(queryStr);
query.addQueryParameter("language", currentLanguageModel);
query.setResultClassList(Arrays.asList( String.class, String.class));
SearchResult<List> searchResults = fss.search(query);
FlexibleSearchQuery query = new FlexibleSearchQuery(queryStr);
query.addQueryParameter("language", currentLanguageModel);
query.setResultClassList(Arrays.asList( String.class, String.class));
SearchResult<List> searchResults = fss.search(query);
Type modifier
You possibly know that “!” at the end of the type alias to perform the search over the subtypes of the specified type. However, you don’t know that there is another modifier, “*”. Compare:Order by marker issue
FlexibleSearch identifies an ORDER BY clause to replace it with user defined one. To mark this fragment the engine uses two markers, “[–” and “–]”. Then FlexibleSearch removes these markers before processing. What is interesting that it removes both the markers that were created by the engine and all other substrings in the query that match the pattern. So the following queries are fully identical in terms of the result (they pass FlexibleSearch validation and give the same result):Select {name} from {Language} where {isocode} = "--]ru[--" Select {name} from {Language} where {isocode} = "ru[--" Select {name} from {Language} where {isocode} = "[--ru--]" Select {name} from {Language} where {isocode} = "--]ru[----][--" Select {name} --]from {Language}[-- where {isocode} = '--]ru[----][--'As you see, the “–]” and “[–” are removed from the resulting SQL query whenever they are placed (you can’t split the keywords and object name anyway).
© Rauf Aliev, November 2016
piotr hlawski (@phlawski)
28 November 2016 at 03:52
With Platform 6.0 we have introduced also nice small addon which allows to skip the cache. Useful for queries which are using some frequently changing params like current time in millis:
final FlexibleSearchQuery fQuery = new FlexibleSearchQuery(“SELECT {PK} FROM {Foo} WHERE {modificationTime}=?modificationTime”);
fQuery.addQueryParameter(“modificationTime”, Long.valueOf(System.currentTimeMillis()));
fQuery.setDisableCaching(true);
final SearchResult searchResult = flexibleSearchService.search(fQuery);
Rauf Aliev
28 November 2016 at 06:32
Thank you, Piotr!