前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring认证中国教育管理中心-Apache Solr 的 Spring 数据教程三

Spring认证中国教育管理中心-Apache Solr 的 Spring 数据教程三

原创
作者头像
IT胶囊
发布2022-01-06 15:10:01
6070
发布2022-01-06 15:10:01
举报
文章被收录于专栏:IT技能应用IT技能应用

原标题:Spring认证中国教育管理中心-Apache Solr 的 Spring 数据教程三(Spring中国教育管理中心)

Apache Solr 的 Spring 数据教程三
Apache Solr 的 Spring 数据教程三

4. 杂项 Solr 操作支持

本章涵盖了对无法通过存储库接口直接访问的 Solr 操作(例如分面)的额外支持。建议将这些操作添加为自定义实现,如Spring Data Repositories 的自定义实现中所述。

4.1.集合/核心名称

使用@SolrDocument注释,可以通过给它一个静态值或使用SpEL 进行动态评估来自定义使用的集合名称。

代码语言:javascript
复制
@SolrDocument(collection = "techproducts")
class StaticCollectionName { ... }

@SolrDocument(collection = "#{@someBean.getCollectionName()}")
class DynamicCollectionName { ... }

注释的类型@SolrDocument可通过targetType表达式中的变量获得。

4.2.部分更新

PartialUpdates 可以使用PartialUpdatewhich implements来完成Update。

代码语言:javascript
复制
PartialUpdate update = new PartialUpdate("id", "123");
update.add("name", "updated-name");
solrTemplate.saveBean("collection-1", update);

4.3.投影

可以通过@Query使用字段值来应用投影。

代码语言:javascript
复制
@Query(fields = { "name", "id" })
List<ProductBean> findByNameStartingWith(String name);

4.4.刻面

使用 不能直接应用分面SolrRepository,但SolrTemplate支持此功能。以下示例显示了一个方面查询:

代码语言:javascript
复制
FacetQuery query = new SimpleFacetQuery(new Criteria(Criteria.WILDCARD).expression(Criteria.WILDCARD))
  .setFacetOptions(new FacetOptions().addFacetOnField("name").setFacetLimit(5));
FacetPage<Product> page = solrTemplate.queryForFacetPage("collection-1", query, Product.class);

字段或查询的方面也可以使用@Facet. 请记住,结果是FacetPage.

Using@Facet允许您定义使用输入参数作为值的占位符。

以下示例使用@Facet注释来定义构面查询:

代码语言:javascript
复制
@Query(value = "*:*")
@Facet(fields = { "name" }, limit = 5)
FacetPage<Product> findAllFacetOnName(Pageable page);

以下示例显示了另一个带有前缀的构面查询:

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

Solr 允许在每个字段的基础上定义方面参数。为了向定义的字段添加特殊的方面选项,请使用FieldWithFacetParameters,如以下示例所示:

代码语言:javascript
复制
// produces: f.name.facet.prefix=spring
FacetOptions options = new FacetOptions();
options.addFacetOnField(new FieldWithFacetParameters("name").setPrefix("spring"));

4.4.1.范围分面

您可以通过在 上配置所需范围来创建范围分面查询FacetOptions。您可以通过创建FacetOptions实例、将选项设置为 aFacetQuery并通过 查询分面页面来请求范围SolrTemplate,如下所示。

代码语言:javascript
复制
FacetOptions facetOptions = new FacetOptions()
  .addFacetByRange(
     new FieldWithNumericRangeParameters("price", 5, 20, 5)
       .setHardEnd(true)
       .setInclude(FacetRangeInclude.ALL)
  )
  .addFacetByRange(
    new FieldWithDateRangeParameters("release", new Date(1420070400), new Date(946684800), "+1YEAR")
      .setInclude(FacetRangeInclude.ALL)
      .setOther(FacetRangeOther.BEFORE)
  );
facetOptions.setFacetMinCount(0);

Criteria criteria = new SimpleStringCriteria("*:*");
SimpleFacetQuery facetQuery = new SimpleFacetQuery(criteria).setFacetOptions(facetOptions);
FacetPage<ExampleSolrBean> statResultPage = solrTemplate.queryForFacetPage("collection-1", facetQuery, ExampleSolrBean.class);

构面范围请求的字段有两种实现:

  • 数字分面范围:用于对数字字段执行范围分面。要请求范围分面,您可以使用org.springframework.data.solr.core.query.FacetOptions.FieldWithNumericRangeParameters该类的实例。它的实例化需要一个字段名、一个起始值(数字)、一个结束值(数字)和一个间隙(数字);
  • 日期分面范围:用于对日期字段执行范围分面。要请求范围分面,您可以使用org.springframework.data.solr.core.query.FacetOptions.FieldWithDateRangeParameters该类的实例。它的实例化需要一个字段名、一个开始值(日期)、一个结束值(日期)和一个间隙(字符串)。您可以使用org.apache.solr.util.DateMathParser(例如,+6MONTHS+3DAYS/DAY表示未来六个月零三天,四舍五入到最近的一天)来定义此类字段的差距。

此外,可以为具有范围参数 ( org.springframework.data.solr.core.query.FacetOptions.FieldWithRangeParameters)的字段配置以下属性:

  • Hard End:setHardEnd(Boolean)定义最后一个范围是否应该突然结束,即使结束不满足(start - end) % gap = 0。
  • 包括:setInclude(org.apache.solr.common.params.FacetParams.FacetRangeInclude)定义范围方面请求上的边界(下限和上限)应如何处理(不包括或不包括在内)。
  • 其他:setOther(org.apache.solr.common.params.FacetParams.FacetRangeOther)定义范围分面的附加(其他)计数(例如范围分面开始之前、范围分面结束之后或什至开始和结束之间的文档计数)。

4.4.2.枢轴刻面

也支持Pivot faceting(决策树),可以使用@Facet注解查询,如下:

代码语言:javascript
复制
public interface {

	@Facet(pivots = @Pivot({ "category", "dimension" }, pivotMinCount = 0))
	FacetPage<Product> findByTitle(String title, Pageable page);

	@Facet(pivots = @Pivot({ "category", "dimension" }))
	FacetPage<Product> findByDescription(String description, Pageable page);

}

或者,可以使用 查询SolrTemplate,如下所示:

代码语言:javascript
复制
FacetQuery facetQuery = new SimpleFacetQuery(new SimpleStringCriteria("title:foo"));
FacetOptions facetOptions = new FacetOptions();
facetOptions.setFacetMinCount(0);
facetOptions.addFacetOnPivot("category","dimension");
facetQuery.setFacetOptions(facetOptions);
FacetPage<Product> facetResult = solrTemplate.queryForFacetPage("collection-1", facetQuery, Product.class);

要检索数据透视结果,请使用以下getPivot方法:

代码语言:javascript
复制
List<FacetPivotFieldEntry> pivot = facetResult.getPivot(new SimplePivotField("categories","available"));

4.5.条款

术语向量不能直接在其中使用,SolrRepository但可以通过 应用SolrTemplate。请记住,结果是TermsPage. 以下示例显示了如何创建术语查询:

代码语言:javascript
复制
TermsQuery query = SimpleTermsQuery.queryBuilder().fields("name").build();
TermsPage page = solrTemplate.queryForTermsPage("collection-1", query);

4.6.结果分组和字段折叠

结果分组不能直接在内部使用,SolrRepository但可以通过 应用SolrTemplate。请记住,结果是GroupPage. 以下示例显示了如何创建结果组:

代码语言:javascript
复制
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<Product> page = solrTemplate.queryForGroupPage("collection-1", query, Product.class);

GroupResult<Product> fieldGroup = page.getGroupResult(field);
GroupResult<Product> funcGroup = page.getGroupResult(func);
GroupResult<Product> queryGroup = page.getGroupResult(query);

4.7.现场统计

现场统计用于检索统计(max,min,sum,count,mean,missing,stddev,和distinct计算)从给定的Solr领域。您可以提供StatsOptions您的查询并FieldStatsResult从返回的StatsPage. 例如,您可以使用SolrTemplate,如下所示:

代码语言:javascript
复制
// 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();

您可以通过使用 注释存储库方法来获得相同的结果@Stats,如下所示:

代码语言:javascript
复制
@Query("name:?0")
@Stats(value = { "price" })
StatsPage<Product> findByName(String name, Pageable page);

还支持不同的计算和分面:

代码语言:javascript
复制
// 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();

前面示例的注释(因此更短)版本如下:

代码语言:javascript
复制
@Query("name:?0")
@Stats(value = "category", facets = { "availability" }, calcDistinct = true)
StatsPage<Product> findByName(String name);

为了执行选择性分面或选择性不同计算,您可以使用@SelectiveStats,如下所示:

代码语言:javascript
复制
// 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.8.过滤查询

过滤查询提高了查询速度并且不影响文档分数。我们建议将地理空间搜索作为过滤查询来实现。

在 Solr 中,除非另有说明,所有距离单位都是公里,点的单位是纬度和经度。

以下示例显示了地理点(在本例中为奥地利)的过滤器查询:

代码语言:javascript
复制
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);

您还可以使用 定义简单的过滤器查询@Query。

Using@Query允许您定义使用输入参数作为值的占位符。

以下示例显示了带有占位符 ( :)的查询:

代码语言:javascript
复制
@Query(value = "*:*", filters = { "inStock:true", "popularity:[* TO 3]" })
List<Product> findAllFilterAvailableTrueAndPopularityLessThanEqual3();

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 4. 杂项 Solr 操作支持
  • 4.1.集合/核心名称
  • 4.2.部分更新
  • 4.3.投影
  • 4.4.刻面
  • 4.4.1.范围分面
  • 4.4.2.枢轴刻面
  • 4.5.条款
  • 4.6.结果分组和字段折叠
  • 4.7.现场统计
  • 4.8.过滤查询
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档