3. Miscellaneous Solr Operation Support

Abstract

This chapter covers additional support for Solr operations (such as faceting) that cannot be directly accessed via the repository interface. It is recommended to add those operations as custom implementation as described in Section 1.3, “Custom implementations for Spring Data repositories” .

3.1 Partial Updates

PartialUpdates can be done using PartialUpdate which implements Update .

[Note]Note
Partial updates require Solr 4.x. With Solr 4.0.0 it is not possible to update mulitvalue fields.

[Note]Note
With Solr 4.1.0 you have to take care on parameter order when setting null values. Order parameters with nulls last.

Example 3.1. 

PartialUpdate update = new PartialUpdate("id", "123");
update.add("name", "updated-name");
solrTemplate.saveBean(update);

3.2 Projection

Projections can be applied via @Query using the fields value.

Example 3.2. 

@Query(fields = { "name", "id" })
List<ProductBean> findByNameStartingWith(String name);

3.3 Faceting

Faceting cannot be directly applied using the SolrRepository but the SolrTemplate holds support for this feature.

Example 3.3. 

FacetQuery query = new SimpleFacetQuery(new Criteria(Criteria.WILDCARD).expression(Criteria.WILDCARD))
  .setFacetOptions(new FacetOptions().addFacetOnField("name").setFacetLimit(5));
FacetPage<Product> page = solrTemplate.queryForFacetPage(query, Product.class);

Facets on fields and/or queries can also be defined using @Facet . Please mind that the result will be a FacetPage .

[Note]Note
Using @Facet allows you to define place holders which will use your input parameter as value.

Example 3.4. 

@Query(value = "*:*")
@Facet(fields = { "name" }, limit = 5)
FacetPage<Product> findAllFacetOnName(Pageable page);

Example 3.5. 

@Query(value = "popularity:?0")
@Facet(fields = { "name" }, limit = 5, prefix="?1")
FacetPage<Product> findByPopularityFacetOnName(int popularity, String prefix, Pageable page);

3.4 Terms

Terms Vector cannot directly be used within SolrRepository but can be applied via SolrTemplate. Please mind, that the result will be a TermsPage.

Example 3.6. 

TermsQuery query = SimpleTermsQuery.queryBuilder().fields("name").build();
TermsPage page = solrTemplate.queryForTermsPage(query);
			

3.5 Filter Query

Filter Queries improve query speed and do not influence document score. It is recommended to implement geospatial search as filter query.

[Note]Note
Please note that in solr, unless otherwise specified, all units of distance are kilometers and points are in degrees of latitude,longitude.

Example 3.7. 

Query query = new SimpleQuery(new Criteria("category").is("supercalifragilisticexpialidocious"));
FilterQuery fq = new SimpleFilterQuery(new Criteria("store")
  .near(new GeoLocation(48.305478, 14.286699), new Distance(5)));
query.addFilterQuery(fq);

Simple filter queries can also be defined using @Query .

[Note]Note
Using @Query allows you to define place holders which will use your input parameter as value.

@Query(value = "*:*", filters = { "inStock:true", "popularity:[* TO 3]" })
List<Product> findAllFilterAvailableTrueAndPopularityLessThanEqual3();

3.6 Time allowed for a search

It it possible to set the time allowed for a search to finish. This value only applies to the search and not to requests in general. Time is in milliseconds. Values less than or equal to zero implies no time restriction. Partial results may be returned, if there are any.

Example 3.8. 

                Query query = new SimpleQuery(new SimpleStringCriteria("field_1:value_1"));
                // Allowing maximum of 100ms for this search
                query.setTimeAllowed(100);
            

3.7 Boost document Score

Boost document score in case of matching criteria to influence result order. This can be done by either setting boost on Criteria or using @Boost for derived queries.

Example 3.9. 

Page<Product> findByNameOrDescription(@Boost(2) String name, String description);

3.8 Select Request Handler

Select the request handler via qt Parameter directly in Query or add @Query to your method signature.

Example 3.10. 

@Query(requestHandler = "/instock")
Page<Product> findByNameOrDescription(String name, String description);

3.9 Using Join

Join attributes within one solr core by defining Join attribute of Query.

[Note]Note
Join is not available prior to solr 4.x.

Example 3.11. 

SimpleQuery query = new SimpleQuery(new SimpleStringCriteria("text:ipod"));
query.setJoin(Join.from("manu_id_s").to("id"));

3.10 Highlighting

To highlight matches in search result add HighlightOptions to the SimpleHighlightQuery. Providing HighlightOptions without any further attributes will highlight apply highlighting on all fields within a SolrDocument.

[Note]Note
Field specific highlight parameters can be set by adding FieldWithHighlightParameters to HighlightOptions.

Example 3.12. 

SimpleHighlightQuery query = new SimpleHighlightQuery(new SimpleStringCriteria("name:with"));
query.setHighlightOptions(new HighlightOptions());
HighlightPage<Product> page = solrTemplate.queryForHighlightPage(query, Product.class);

Not all parameters are available via setters/getters but can be added directly.

Example 3.13. 

SimpleHighlightQuery query = new SimpleHighlightQuery(new SimpleStringCriteria("name:with"));
query.setHighlightOptions(new HighlightOptions().addHighlightParameter("hl.bs.country", "at"));

In order to apply Highlighting to derived queries use @Highlight. If no fields are defined highlighting will be aplied on all fields.

Example 3.14. 

@Highlight(prefix = "<b>", postfix = "</b>")
HighlightPage<Product> findByName(String name, Pageable page);