In this article of Spring Data Solr Dynamic Queries, we will learn how to write dynamic queries using Spring Data Solr repositories. We will see several cases of dynamic queries for the Solr Core.
We will now implement a dynamic search function with Spring Data Solr. Although our search function is rather simple, we should now be able to implement more complex queries as well.
In the article, I will create some dynamic queries that are mostly required at time of development for your real projects such as filter queries, faceting, pivoting, and grouping etc. Let’s see the following sections about Spring Data Solr Dynamic Queries:
There are the following queries related to the Solr in the Spring Data Solr Queries:
Projections can be applied via @Query using the value of the field.
@Query(fields = { "oname", "oid" }) List<Order> findByOrderNameStartingWith(String name);
Let’s see faceting query using the SolrTemplate, it holds support for this feature.
FacetQuery query = new SimpleFacetQuery(new Criteria(Criteria.WILDCARD).expression(Criteria.WILDCARD)) .setFacetOptions(new FacetOptions().addFacetOnField("oname").setFacetLimit(5)); FacetPage<Order> page = solrTemplate.queryForFacetPage("Order", query, Order.class);
In the above code snippet, you have seen how to write facet query using SolrTemplate and FacetQuery. The FacetOptions class provides a way to set facet fields and you can also set facet limit using setFacetLimit() method. The FacetQuery returns result in a FacetPage.
You can also define the Facets on fields and/or queries using @Facet annotation. As similar to above that the result will be a FacetPage. You can define placeholders which will use your input parameter as the value using @Facet annotation, let’s see as the following code snippet:
@Query(value = "*:*") @Facet(fields = { "oname" }, limit = 5) FacetPage<Order> findAllFacetOnOName(Pageable page); @Query(value = "odesc:?0") @Facet(fields = { "oname" }, limit = 5, prefix="?1") FacetPage<Order> findByOrderDescFacetOnName(Sttring orderDesc, String prefix, Pageable page);
As you have seen in the above faceting Solr queries, you can use either SolrTemplate or @Facet annotation in the Spring Data Solr repository to make a facet query. In the next section, we will discuss how to fire a Pivot faceting query.
Spring Data Solr also supports the Pivot faceting Solr queries using @Facet annotation as follows:
public interface SolrOrderRepository{ @Facet(pivots = @Pivot({ "category", "product" }, pivotMinCount = 0)) FacetPage<Order> findByOrderTitle(String title, Pageable page); @Facet(pivots = @Pivot({ "category", "product" })) FacetPage<Order> findByOrderDesc(String orderDesc, Pageable page); }
As you have seen in the above code snippet how to write the Pivot Faceting Solr Query. Let’s move to the next section and learn how to fire Solr queries by the grouping of results and field collapsing.
Result grouping cannot directly be used within SolrRepository but can be applied via SolrTemplate. Please mind, that the result will be a GroupPage.
Field field = new SimpleField("popularity"); Function func = ExistsFunction.exists("description"); Query query = new SimpleQuery("inStock:true"); SimpleQuery groupQuery = new SimpleQuery(new SimpleStringCriteria("*:*")); GroupOptions groupOptions = new GroupOptions() .addGroupByField(field) .addGroupByFunction(func) .addGroupByQuery(query); groupQuery.setGroupOptions(groupOptions); GroupPage<Order> page = solrTemplate.queryForGroupPage("Order", query, Order.class); GroupResult<Order> fieldGroup = page.getGroupResult(field); GroupResult<Order> funcGroup = page.getGroupResult(func); GroupResult<Order> queryGroup = page.getGroupResult(query);
Let’s see how to write filter Solr queries in the next section.
In this section, we will see how to write filter Solr query. The Filter Queries improve query speed without impacting document score. It is recommended to implement geospatial search as filter query.
NOTE: In this distance based filter Solr query, all units of distance are kilometres and points are in degrees of latitude, longitude.
Let’s see the following filter Solr query:
Query query = new SimpleQuery(new Criteria("category").is("java-book")); FilterQuery fq = new SimpleFilterQuery(new Criteria("shops") .near(new Point(43.2012413, 13.534223), new Distance(3))); query.addFilterQuery(fq);
The above filer Solr query we can use with the SolrTemplate. You can also create simple filter queries by using @Query annotation. The @Query annotation allows you to define placeholders which use to take your input parameter as value. Let’s see the following query:
@Query(value = "*:*", filters = { "category:java-book", "rank:[* TO 5]" }) List<Book> findAllJavaBookAndRankLessThanEqual5();
In the above code snippet, we have written a Solr query to find all Java books whose rank less than or equal to 5. In the next section, we will learn to apply Highlighting to matches in the search result.
Spring Data Solr provides the SimpleHighlightQuery class to highlight matches in the search result by adding HighlightOptions with it. So, you have to provide HighlightOptions with attributes by adding FieldWithHighlightParameters to HighlightOptions otherwise it will apply to highlight on all fields within a SolrDocument. Let’s see the following code snippet:
SimpleHighlightQuery query = new SimpleHighlightQuery(new SimpleStringCriteria("oname:with")); query.setHighlightOptions(new HighlightOptions()); HighlightPage<Order> page = solrTemplate.queryForHighlightPage("Order", query, Order.class);
Using with attributes:
SimpleHighlightQuery query = new SimpleHighlightQuery(new SimpleStringCriteria("oname:with")); query.setHighlightOptions(new HighlightOptions()); HighlightPage<Order> page = solrTemplate.queryForHighlightPage("Order", query, Order.class); query.setHighlightOptions(new HighlightOptions().addHighlightParameter("hl.bs.country", "at"));
Same things you can also do by using @Highlight annotation. If no fields are defined highlighting will be applied in all fields.
@Highlight(prefix = "<b>", postfix = "</b>") HighlightPage<Order> findByOrderName(String orderName, Pageable page);
As you can see in the above code snippet, the return result of a Solr query will be highlighted using given prefix and postfix attribute. Let’s see how to implement spellchecking functionality using the Spring Data Solr in the following section:
This feature of the Solr offers search term suggestions based on the actual query. Let’s see the following code snippet:
The following code snippet has used the Spellcheck Options. Spellcheck query parameters are added to request when SpellcheckOptions are set.
SimpleQuery q = new SimpleQuery("oname:andr"); q.setSpellcheckOptions(SpellcheckOptions.spellcheck() .dictionaries("dict1", "dict2") .count(5) .extendedResults()); q.setRequestHandler("/spell"); SpellcheckedPage<Order> orders = solrTemplate.query(q, Order.class);
Enable spell check by setting SpellcheckOptions. Sets spellcheck=on request parameter.
In the above code snippet, there are the following to be noticed:
We have seen how to write a query for spellcheck. Let’s see how to write this query using annotation in the following section:
Let’s see in the following code snippet and how to use @Spellcheck annotation to allow usage of the spellcheck feature on Repository level.
public interface SolrOrderRepository extends Repository<Order, Long> {
@Query(requestHandler = “/spell”)
@Spellcheck(dictionaries = { “dict1”, “dic2” }, count=5, extendedResults = true)
SpellcheckedPage findByOrderName(String orderName, Pageable page);
}
We have seen in this article, how to write dynamic Solr queries either using annotations or SolrTemplate.
Thanks for learning with the Dineshonjava!!!
Strategy Design Patterns We can easily create a strategy design pattern using lambda. To implement…
Decorator Pattern A decorator pattern allows a user to add new functionality to an existing…
Delegating pattern In software engineering, the delegation pattern is an object-oriented design pattern that allows…
Technology has emerged a lot in the last decade, and now we have artificial intelligence;…
Managing a database is becoming increasingly complex now due to the vast amount of data…
Overview In this article, we will explore Spring Scheduler how we could use it by…