Firstly, if you’re in need of a brief introduction to Project Bolt and our new search-driven API, we recommend that you check out these articles:
Secondly, we’re hosting a webinar about Ucommerce 9 on the 25th of March. Here, we will present and discuss the major news that we are bringing to the platform and organize a live Q&A. Click here to read more about the webinar and to sign up.
Ucommerce 9 is released 31rst of March!
What is BOLT API?
There is a close correlation between page load speeds and revenue. Simply put slower page load speed equals lost revenue as impatient customers are quick to move on to something better and faster.
Over the years, our partners have found that using read-fast technologies like search engines to power their solutions is a great way to ensure fast performance. However, there are many different search technologies out there and, even though they share a lot of common traits, they each have their own characteristics and requirements.
While our partners agree that a search engine is a great way to power their e-commerce solutions, they do not necessarily agree on which one to use.
To leverage search technology, our partners have built solutions specifically for each client, sometimes reusing their read-fast solution across clients. Always create at least one proprietary solution with its own characteristics and requirements for developers to use.
Fast performance to ensure maximum revenue for digital merchants, ability to support our partners’ favorite search technologies, unified and safe by default APIs to guide developers onto the path of success as they build e-commerce solutions. This is BOLT, the search-driven API of Ucommerce 9. We are incredibly excited to get this into your hands!
Getting Started Querying
Given all that, what does querying using BOLT API actually look like? Let’s dive in and find out.
Static Queries
Static queries are the bread and butter of an e-commerce website used to do product listings, catalog structure navigation like mega menus. Listing products in a category page is done simply like this:
var category = CatalogLibrary.GetCategory();
ResultSet<Product> productsInCategory = productIndex.Find()
.Where(x => x.Categories.Contains(category.Guid))
.ToList();
Notice how the Product.Categories collection doesn’t actually hold a full category object. The reasoning is to provide only flattened data to ensure faster performance because data doesn’t have to be correlated from multiple sources, e.g. a JOIN in SQL Server.
Each time data needs to be gathered from multiple sources an explicit request from each index is required.
Full Text Search
Full text search requires a bit more information to give you more flexibility. In the sample below we are doing a full text search with a degree of flexibility on how close the match should be to the value we are searching for.
var products = productIndex.Find()
.Where(product =>
product.LongDescription == Match.FullText("clues about blues", slop:3))
.ToList();
Notice how Match.FullText is used to provide additional arguments for the full text search to indicate that we are good with a bit of discrepancy between the search term “clues about blues” and the match within the index.
Match is a class you will become very familiar with as you expand queries to include full text search clauses. Full text search requires extra arguments beyond just variables and so we needed a way to include not just the value you are looking, but extra parameters like boosting, fuzziness, and more. In addition, it gives you a single entry point for all things more advanced than ==, !=, >, <, and so forth.
Faceting
Finally, faceted filtering enables you to narrow down a list of products or search results.
FacetResultSet<Product> productsInCategory = productIndex.Find()
.Where(x => x.Categories.Contains(category.Guid))
.ToFacets();
Notice how ToList() is swapped out with ToFacets(), which returns the results of the query as well as any facets associated with the results.
As a customer starts making selections in the front-end in the case “Red”, “Blue”, and “Green” are selected for the color facet and for size “S, “M”, and “L”. These are passed back to BOLT to refine the query like so:
var facetDictionary = new FacetDictionary {
{ "Color", new[] { "Red", "Blue", "Green" } },
{ "Size", new [] { "S", "M", "L" } }
}
FacetResultSet<Product> productsInCategory = productIndex.Find()
.Where(x => x.Categories.Contains(category.Guid))
.Where(facetDictionary)
.ToFacets();
The example above uses a combination of querying facets using a type-safe field (Categories) and using dynamic data (Color and Size). This allows you to strike a balance between safety and practicality without too much ceremony.
Pagination is now default
In the code above we didn’t indicate how many products to bring back. Because BOLT API is safe by default, we only receive back a maximum of 300 unless another quantity is given.
IList<Product> products = productIndex.Find<Product>()
.Skip(500)
.Take(500)
.ToList();
Product listings in an e-commerce solution should generally be paged to ensure as quick response times as possible, hence the decision to nudge developers towards a paged solution.
How to access an index
To get you started quickly, Ucommerce 9 includes pre-made indexes for products (including list prices), catalogs, categories and catalog groups.
If you’re using dependency injection, all you need to do to use an index is to declare it as a dependency.
public Index<Product> Products { get; set; }
Otherwise, you can access the index using service location.
var products = ObjectFactory.Instance.Resolve<IIndex<Product>>();
That is all you need to start querying the index.
ResultSet<Product> products = productIndex.Find().Skip(0).Take(50).ToList();
For optimal speed, each index is further split into languages. If your CMS has US English and German set up, Ucommerce 9 will create two versions of each index, one in US English and one in German, e.g. Products_en-US and Products_de-DE.
ResultSet<Product> products = productIndex.Find(CultureInfo.CreateCulture("de-DE")).Skip(0).Take(50).ToList();
In addition to the build-in indexes, Ucommerce 9 allows you to create your own, customizing which fields are indexed. In a later blog post, you will learn how to create your own indexes.
Using your own models, code-first style
The Product model we are working with above we refer to as a “return model”, which is used by BOLT API to represent the information in the index in a type-safe manner to make it more convenient to work with as a developer.
Ucommerce 9 ships with simple models for ProductCatalogGroup, ProductCatalog, Category, and Product (which is also used for variants). The models employed are configurable, so you can create a model specific to your solution close to the domain you are addressing with Ucommerce.
Let us imagine we created a class called Shirt to replace the built-in Product model. Inside Shirt we declared two more properties, Color and Size. Would it be great if we could have the product index return instances of Shirt, as well as use the Shirt model when writing where clauses?
ResultSet<Shirt> shirts = productIndex.Find<Shirt>().Where(shirt => shirt.Color == "Red" && shirt.Size == "XS").ToList();
The data stored within the indexes are flattened to make them perform as fast as possible. It is not possible to navigate relationships to other models like you may be used to. For instance, variants for a specific product are represented as IList<Guid> rather than IList<Variant>. This list of identifiers can be used for further querying to locate the corresponding documents within BOLT.
One of the benefits of this strategy is to make retrieving data safe by default; it’s easier to design a performant product listing when you know exactly which queries are run.
A word on availability
To get BOLT into the hands of developers as quickly as possible, BOLT V1 ships exclusively with Lucene as the sole out of the box provider. Please note that scaling using BOLT V1 will not be available out of the box as a result, but can be achieved by building a custom search provider.
Work on the ElasticSearch provider for BOLT will commence immediately upon release of BOLT V1 and will be made available in Q2’20.
To learn more about when to expect all of the abovementioned, take a look at our roadmap for the next four quarters here: Roadmap: What can you expect and when.
If you have any questions about querying, Project Bolt, or Ucommerce 9, we encourage you to sign up for our webinar on the 25th of March. Here, you have the opportunity to participate in a live Q&A as well as you can send your questions beforehand, then we’ll do our best to address it.