如何对 Solr 中的多个字段执行嵌套聚合?

Posted

技术标签:

【中文标题】如何对 Solr 中的多个字段执行嵌套聚合?【英文标题】:How to perform nested aggregation on multiple fields in Solr? 【发布时间】:2013-10-06 08:55:03 【问题描述】:

我正在尝试以嵌套方式按多个字段执行搜索结果聚合(计数和总和)分组。

例如,使用本文末尾显示的架构,我希望能够获得按“类别”分组并按“子类别”进一步分组的“大小”总和,并得到类似这个:

<category name="X">
  <subcategory name="X_A">
    <size sum="..." />
  </subcategory>
  <subcategory name="X_B">
    <size sum="..." />
  </subcategory>
</category>
....

我主要关注 Solr 的 Stats 组件,据我所知,它不允许嵌套聚合。

如果有人知道使用或不使用 Stats 组件的某种方式来实现这一点,我将不胜感激。

这是目标架构的精简版:

<types>
  <fieldType name="string" class="solr.StrField" />
  <fieldType name="text" class="solr.TextField">
    <analyzer><tokenizer class="solr.StandardTokenizerFactory" /></analyzer>
  </fieldType>
  <fieldType name="date" class="solr.DateField" />
  <fieldType name="int" class="solr.TrieIntField" precisionStep="0" omitNorms="true" positionIncrementGap="0" />
</types>

<fields>
  <field name="id" type="string" indexed="true" stored="true" />
  <field name="category" type="text" indexed="true" stored="true" />
  <field name="subcategory" type="text" indexed="true" stored="true" />
  <field name="pdate" type="date" indexed="true" stored="true" />
  <field name="size" type="int" indexed="true" stored="true" />
</fields>

【问题讨论】:

【参考方案1】:

1.计数

要获得计数,您可以使用Pivot Faceting。它将生成一个与您所要求的非常相似的列表,但仅包含计数。

您需要将此附加到您的查询中:

&facet=true&facet.pivot=category,subcategory

请注意,这适用于 Solr 4.0 及更高版本。


2。总和

至于总和,我认为您可以使用普通构面来实现它们,但使用构面查询而不是构面字段。我不完全确定这一点,如果找到我会尝试并重新发布任何有用的东西。

【讨论】:

【参考方案2】:

有一个补丁SOLR-3583,它通过使用范围分面内部结构为分面、枢轴分面和分布式枢轴分面添加百分位数和平均值。通过改进此补丁,可以将总和添加到枢轴分面。

例如,可以使用此 url 计算类别的平均值:

http://localhost:8983/solr/select?q=*%3A*
&facet=true
&facet.pivot=category,subcategory
&facet.stats.percentiles=true
&facet.stats.percentiles.averages=true
&facet.stats.percentiles.field=size
&f.size.stats.percentiles.requested=25,50,75
&f.size.stats.percentiles.lower.fence=0
&f.size.stats.percentiles.upper.fence=1000
&f.size.stats.percentiles.gap=10

有关详细信息,另请参阅this video and slides。

【讨论】:

找不到链接的页面【参考方案3】:

Solr 5.1 中新的 faceting 模块可以做到这一点,它是在https://issues.apache.org/jira/browse/SOLR-7214 中添加的

这是您如何将 sum(size) 添加到每个构面桶,并按该统计数据降序排序。

json.facet=
  categories:terms:
    field:category,
    sort:"total_size desc",  // this will sort the facet buckets by your stat 
    facet:
      total_size:"sum(size)"  // this calculates the stat per bucket
    
  

这就是您在子类别中添加子方面的方式:

json.facet=
  categories:terms:
    field:category,
    sort:"total_size desc",
    facet:
      total_size:"sum(size)",
      subcat:terms: // this will facet on the subcategory field for each bucket
        field:subcategory,
        facet:
         sz:"sum(size)"  // this calculates the sum per sub-cat bucket          
      
    
  

因此,以上内容将为您提供类别和子类别级别的总和(大小)。新方面模块的文档目前位于http://yonik.com/json-facet-api/

【讨论】:

以上是关于如何对 Solr 中的多个字段执行嵌套聚合?的主要内容,如果未能解决你的问题,请参考以下文章

Solr的聚合统计功能

将一个字段转换为Solr中的多个字段

在 Solr 中按特定顺序按多个字段排序

如何获得具有多个字段的 Elasticsearch 聚合

(Elasticsearch)如何获取所有文档的嵌套字段的最后一个元素然后执行子聚合

是否可以结合多个字段进行 Solr 分面,例如 RMDB 中多个列上的不同?