结果分组

结果分组将具有公共字段值的文档分组,并返回每个组的顶部文档。

例如,如果您在电子零售商的电子商务网站上搜索“DVD”,您可能会得到三个类别,例如“电视和视频”、“电影”和“计算机”,每个类别有三个结果。在这种情况下,查询词“DVD”出现在所有三个类别中,因此 Solr 将它们分组在一起,以提高用户的相关性。

首选折叠和展开

Solr 的折叠和展开结果功能更新,并且大部分与结果分组重叠。两者都有独特的功能,并且具有不同的性能特征。也就是说,在大多数情况下,折叠和展开优于结果分组。

结果分组与分面是分开的。尽管概念上相似,但分面返回所有相关结果,并允许用户根据分面类别细化结果。例如,如果您在鞋类零售商的电子商务网站上搜索“鞋子”,Solr 将返回该查询词的所有结果,以及可选择的分面,例如“尺寸”、“颜色”、“品牌”等等。

但是,您可以将分组与分面结合使用。分组分面支持 facet.fieldfacet.range,但目前不支持日期和透视分面。分面计数基于第一个 group.field 参数计算,并忽略其他 group.field 参数。

分组分面与非分组分面不同 (所有分面之和) == (具有该属性的产品总数),如下例所示

对象 1

  • 名称:Phaser 4620a

  • ppm:62

  • product_range:6

对象 2

  • 名称:Phaser 4620i

  • ppm:65

  • product_range:6

对象 3

  • 名称:ML6512

  • ppm:62

  • product_range:7

如果您要求 Solr 按“product_range”对这些文档进行分组,则组的总数为 2,但 ppm 的分面为 62 的为 2,为 65 的为 1。

分组参数

结果分组采用以下请求参数。可以在单个请求中包含任意数量的这些请求参数

group

可选

默认值:false

如果为 true,则查询结果将被分组。

group.field

可选

默认值:无

用于对结果进行分组的字段的名称。该字段必须是单值字段,并且必须是已索引的字段,或者是具有值源并在函数查询中工作的字段类型,例如 ExternalFileField。它还必须是基于字符串的字段,例如 StrFieldTextField

group.func

可选

默认值:无

基于函数查询的唯一值进行分组。

此选项不适用于分布式搜索
group.query

可选

默认值:无

返回与给定查询匹配的单个文档组。

rows

可选

默认值:10

返回的组数。

开始

可选

默认值:无

指定组列表的初始偏移量。

group.limit

可选

默认值:1

指定每个组要返回的结果数。

group.offset

可选

默认值:无

指定每个组的文档列表的初始偏移量。

排序

可选

默认值:score desc

指定 Solr 如何对各组进行相互排序。例如,sort=popularity desc 将导致各组根据每组中最高受欢迎的文档进行排序。

group.sort

可选

默认值:请参阅说明

指定 Solr 如何对每个组内的文档进行排序。如果未指定 group.sort,则默认行为是使用与 sort 参数相同的有效值。

group.format

可选

默认值:grouped

如果此参数设置为 simple,则分组的文档将以单个平面列表形式呈现,并且 startrows 参数会影响文档的数量,而不是组的数量。此参数的另一个可选值是 grouped

group.main

可选

默认值:无

如果为 true,则第一个字段分组命令的结果将用作响应中的主要结果列表,使用 group.format=simple

group.ngroups

可选

默认值:false

如果为 true,Solr 会在结果中包含与查询匹配的组数。

在使用分片索引时,请参阅下面的分布式结果分组注意事项

group.truncate

可选

默认值:false

如果为 true,则分面计数基于与查询匹配的每个组中最相关的文档。

group.facet

可选

默认值:false

确定是否为 facet.field 参数中指定的字段分面计算分组的分面。分组的分面基于第一个指定的分组进行计算。与普通字段分面一样,字段不应被标记化(否则会为每个标记计算计数)。分组分面支持单值和多值字段。

此选项可能会导致严重的性能开销。

在使用分片索引时,请参阅下面的分布式结果分组注意事项

group.cache.percent

可选

默认值:0

将此参数设置为大于 0 的数字会启用结果分组的缓存。结果分组会执行两次搜索;此选项会缓存第二次搜索。

测试表明,组缓存仅在使用布尔、通配符和模糊查询时才能提高搜索速度。对于诸如术语或“匹配所有”查询之类的简单查询,组缓存会降低性能。

可以在单个请求中指定任意数量的组命令(例如,group.fieldgroup.funcgroup.query 等)。

分组示例

以下所有示例查询都适用于 Solr 的“bin/solr start -e techproducts”示例。

按字段分组结果

在此示例中,我们将基于 manu_exact 字段对结果进行分组,该字段指定示例数据集中项目的制造商。

https://127.0.0.1:8983/solr/techproducts/select?fl=id,name&q=solr+memory&group=true&group.field=manu_exact
{
"..."
"grouped":{
  "manu_exact":{
    "matches":6,
    "groups":[{
        "groupValue":"Apache Software Foundation",
        "doclist":{"numFound":1,"start":0,"docs":[
            {
              "id":"SOLR1000",
              "name":"Solr, the Enterprise Search Server"}]
        }},
      {
        "groupValue":"Corsair Microsystems Inc.",
        "doclist":{"numFound":2,"start":0,"docs":[
            {
              "id":"VS1GB400C3",
              "name":"CORSAIR ValueSelect 1GB 184-Pin DDR SDRAM Unbuffered DDR 400 (PC 3200) System Memory - Retail"}]
        }},
      {
        "groupValue":"A-DATA Technology Inc.",
        "doclist":{"numFound":1,"start":0,"docs":[
            {
              "id":"VDBDB1A16",
              "name":"A-DATA V-Series 1GB 184-Pin DDR SDRAM Unbuffered DDR 400 (PC 3200) System Memory - OEM"}]
        }},
      {
        "groupValue":"Canon Inc.",
        "doclist":{"numFound":1,"start":0,"docs":[
            {
              "id":"0579B002",
              "name":"Canon PIXMA MP500 All-In-One Photo Printer"}]
        }},
      {
        "groupValue":"ASUS Computer Inc.",
        "doclist":{"numFound":1,"start":0,"docs":[
            {
              "id":"EN7800GTX/2DHTV/256M",
              "name":"ASUS Extreme N7800GTX/2DHTV (256 MB)"}]
        }
      }]}}}

响应表明我们的查询共有六个匹配项。对于 group.field 的五个唯一值中的每一个,Solr 返回该 groupValuedocList,使得 numFound 指示该组中的文档总数,并且根据隐含的默认 group.limit=1group.sort=score desc 参数返回顶部文档。然后,根据每个组内顶部文档的分数,基于隐含的 sort=score desc 对结果组进行排序,并且返回的组数限制为隐含的 rows=10

我们可以使用请求参数 group.main=true 运行相同的查询。这会将结果格式化为单个平面文档列表。此平面格式不包含与正常结果分组查询结果一样多的信息(特别是每个组中的 numFound),但对于现有的 Solr 客户端来说,它可能更容易解析。

https://127.0.0.1:8983/solr/techproducts/select?fl=id,name,manufacturer&q=solr+memory&group=true&group.field=manu_exact&group.main=true
{
  "responseHeader":{
    "status":0,
    "QTime":1,
    "params":{
      "fl":"id,name,manufacturer",
      "indent":"true",
      "q":"solr memory",
      "group.field":"manu_exact",
      "group.main":"true",
      "group":"true"}},
  "grouped":{},
  "response":{"numFound":6,"start":0,"docs":[
      {
        "id":"SOLR1000",
        "name":"Solr, the Enterprise Search Server"},
      {
        "id":"VS1GB400C3",
        "name":"CORSAIR ValueSelect 1GB 184-Pin DDR SDRAM Unbuffered DDR 400 (PC 3200) System Memory - Retail"},
      {
        "id":"VDBDB1A16",
        "name":"A-DATA V-Series 1GB 184-Pin DDR SDRAM Unbuffered DDR 400 (PC 3200) System Memory - OEM"},
      {
        "id":"0579B002",
        "name":"Canon PIXMA MP500 All-In-One Photo Printer"},
      {
        "id":"EN7800GTX/2DHTV/256M",
        "name":"ASUS Extreme N7800GTX/2DHTV (256 MB)"}]
  }
}

按查询分组

在此示例中,我们将使用 group.query 参数在两个不同的价格范围内查找“memory”的前三个结果:0.00 到 99.99,以及 100 以上。

https://127.0.0.1:8983/solr/techproducts/select?indent=true&fl=name,price&q=memory&group=true&group.query=price:[0+TO+99.99]&group.query=price:[100+TO+*]&group.limit=3
{
  "responseHeader":{
    "status":0,
    "QTime":42,
    "params":{
      "fl":"name,price",
      "indent":"true",
      "q":"memory",
      "group.limit":"3",
      "group.query":["price:[0 TO 99.99]",
      "price:[100 TO *]"],
      "group":"true"}},
  "grouped":{
    "price:[0 TO 99.99]":{
      "matches":5,
      "doclist":{"numFound":1,"start":0,"docs":[
          {
            "name":"CORSAIR ValueSelect 1GB 184-Pin DDR SDRAM Unbuffered DDR 400 (PC 3200) System Memory - Retail",
            "price":74.99}]
      }},
    "price:[100 TO *]":{
      "matches":5,
      "doclist":{"numFound":3,"start":0,"docs":[
          {
            "name":"CORSAIR  XMS 2GB (2 x 1GB) 184-Pin DDR SDRAM Unbuffered DDR 400 (PC 3200) Dual Channel Kit System Memory - Retail",
            "price":185.0},
          {
            "name":"Canon PIXMA MP500 All-In-One Photo Printer",
            "price":179.99},
          {
            "name":"ASUS Extreme N7800GTX/2DHTV (256 MB)",
            "price":479.95}]
      }
    }
  }
}

在这种情况下,Solr 找到了五个“memory”的匹配项,但仅返回了按价格分组的四个结果。这是因为“memory”的一个结果没有分配价格。

分布式结果分组注意事项

分组支持分布式搜索,但有一些注意事项

  • 目前,任何分布式搜索都不支持 group.func

  • group.ngroupsgroup.facet 要求每个组中的所有文档必须位于同一分片上,才能返回准确的计数。通过复合键进行文档路由在许多情况下可能是一个有用的解决方案。