4.6. Field Stats
Field stats are used to retrieve statistics (max, min, sum, count, mean, missing, stddev and distinct calculations) of given fields from Solr. It is possible by providing StatsOptions
to your query and reading the FieldStatsResult
from the returned StatsPage
. This could be achieved for instance, using SolrTemplate
as follows:
// simple field stats
StatsOptions statsOptions = new StatsOptions().addField("price");
// query
SimpleQuery statsQuery = new SimpleQuery("*:*");
statsQuery.setStatsOptions(statsOptions);
StatsPage<Product> statsPage = solrTemplate.queryForStatsPage("collection-1", statsQuery, Product.class);
// retrieving stats info
FieldStatsResult priceStatResult = statResultPage.getFieldStatsResult("price");
Object max = priceStatResult.getMax();
Long missing = priceStatResult.getMissing();
The same result could be achieved annotating the repository method with @Stats
as follows:
@Query("name:?0")
@Stats(value = { "price" })
StatsPage<Product> findByName(String name, Pageable page);
Distinct calculation and faceting are also supported:
// for distinct calculation
StatsOptions statsOptions = new StatsOptions()
.addField("category")
// for distinct calculation
.setCalcDistinct(true)
// for faceting
.addFacet("availability");
// query
SimpleQuery statsQuery = new SimpleQuery("*:*");
statsQuery.setStatsOptions(statsOptions);
StatsPage<Product> statsPage = solrTemplate.queryForStatsPage("collection-1", statsQuery, Product.class);
// field stats
FieldStatsResult categoryStatResult = statResultPage.getFieldStatsResult("category");
// retrieving distinct
List<Object> categoryValues = priceStatResult.getDistinctValues();
Long distinctCount = categoryStatResult.getDistinctCount();
// retrieving faceting
Map<String, StatsResult> availabilityFacetResult = categoryStatResult.getFacetStatsResult("availability");
Long availableCount = availabilityFacetResult.get("true").getCount();
The annotated version of the sample above would be:
@Query("name:?0")
@Stats(value = "category", facets = { "availability" }, calcDistinct = true)
StatsPage<Product> findByName(String name);
In order to perform a selective faceting or selective distinct calculation, @SelectiveStats
may be used as follows:
// selective distinct faceting
...
Field facetField = getFacetField();
StatsOptions statsOptions = new StatsOptions()
.addField("price")
.addField("category").addSelectiveFacet("name").addSelectiveFacet(facetField);
...
// or annotating repository method as follows
...
@Stats(value = "price", selective = @SelectiveStats(field = "category", facets = { "name", "available" }))
...
// selective distinct calculation
...
StatsOptions statsOptions = new StatsOptions()
.addField("price")
.addField("category").setSelectiveCalcDistinct(true);
...
// or annotating repository method as follows
...
@Stats(value = "price", selective = @SelectiveStats(field = "category", calcDistinct = true))
...
4.7. Filter Query
Filter Queries improve query speed and do not influence document score. It is recommended to implement geospatial search as filter query. NOTE: Please note that in solr, unless otherwise specified, all units of distance are kilometers and points are in degrees of latitude,longitude.
Query query = new SimpleQuery(new Criteria("category").is("supercalifragilisticexpialidocious"));
FilterQuery fq = new SimpleFilterQuery(new Criteria("store")
.near(new Point(48.305478, 14.286699), new Distance(5)));
query.addFilterQuery(fq);
Simple filter queries can also be defined using @Query
. 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();
4.8. 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.
Query query = new SimpleQuery(new SimpleStringCriteria("field_1:value_1"));
// Allowing maximum of 100ms for this search
query.setTimeAllowed(100);
4.9. 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.
Page<Product> findByNameOrDescription(@Boost(2) String name, String description);
4.9.1. Index Time Boosts
Boosting documents score can be done on index time by using @SolrDocument
annotation on classes (for Solr documents) and/or @Indexed
on fields (for Solr fields).
import org.apache.solr.client.solrj.beans.Field;
import org.springframework.data.solr.repository.Boost;
@SolrDocument(boost = 0.8f)
public class MyEntity {
@Id
@Indexed
private String id;
@Indexed(boost = 1.0f)
private String name;
// setters and getters ...
}