This post continues our series on Custom Queries in Spring Data Solr. We covered using the Java Criteria API along with Named and Annotated Queries. For good measure we covered Solr CRUD Operations as well. If you had read any of the posts you probably noticed (or had already known) how these Spring Data Solr operations are no different than querying, say, MySQL or some other relational database. This common API is, of course, one of Spring's great strengths.
Today we're going to look at a couple of Named Method Queries with Solr. We'll see how they are no different than any other Spring Data Named Method, yet with Solr as our data source we may encounter some surprises.
We're going to first retrieve all available products, where only instock:true items are displayed. Our ProductRepository query couldn't get any more straightforward.
The Solr Document field is actually “inStock” but we're using an interface for referencing fields in our Product Class. Now we can use our Named Method to search on the “available” field.
We retrieve the results in ProductService below. One point of interest here is that we have multiple document types in our Solr Index (books, money, etc) so to filter for products only we stream and filter the results.
We could have used a different Named Method and avoided filtering the results for a pure Named Method approach. In that case the ProductRepository Named Method would have been:
List<Product> findByAvailableTrueAndDoctype(String docType);
While the ProductService call would have been:
List<Product> products = productRepo.findByAvailableTrueAndDoctype(SolrDocType.PRODUCT);
Yeah, I like that better, too. Our result is the same.
I said that we're going to look at a Named Method with a Solr Twist, and I think this is an interesting one. Here's the Named Method Query. Like findByAvailableTrue() we couldn't get much simpler.
List<Product> findByNameStartingWith(String name);
We have a name field, so we assume (at least I assume) that we're only going to retrieve documents where the name field starts with our string, in this case, let's use “CO” to retrieve those two records we saw a minute ago that begin with “CORSAIR.”
Here's our call in SolrUI.
But our results are not what we were expecting. We retrieved all records where any WORD in the Name field started with “CO.” Worrrd!
This is because we tokenized our Name field, so Solr is performing exactly as designed. To search by start of field we can employ an interesting hack described here or perhaps duplicate the Name field on Solr input in a non-tokenized field. We'll probably revisit this issue in the future. For now, we've done our job and demonstrated a Solr Twist to Spring Data Named Method Queries.