按集合字段对 solr 搜索结果进行分组的解决方法

Workaround to group solr search result by collection field

我是 Solr 的初学者。可能会有错误。对不起。 我使用的是 7.7.1 版。 假设有下一个文件:

{
  "documents": [
    {
      "id": 1,
      "category": [
        "a",
        "b"
      ],
      "score":0.10 //lucene score
    },
    {
      "id": 2,
      "category": [
        "b",
        "c",
        "d",
        "e"
      ],
      "score":0.20 //lucene score
    },
    {
      "id": 3,
      "category": [
        "a",
        "e"
      ],
      "score":0.30 //lucene score
    },
    {
      "id": 4,
      "category": [
        "d",
        "e"
      ],
      "score":0.40 //lucene score
    },
    {
      "id": 5,
      "category": [
        "a",
        "c"
      ],
      "score":0.50 //lucene score
    }
  ]
}

接下来就是主要任务了。我得到 3 个或更多不同的类别,我只需要一个每个类别得分最高的文档。换句话说,我需要按类别字段对结果进行分组,每个组都必须按分数 desc 排序,并且每个组都必须限制为 1.

例如,对于 a、b、c 类别结果必须包含 3 个文档

document with id == 5 for a category
document with id == 2 for b category
document with id == 5 for c category

是否可以通过单个请求创建 solr 查询来获得这样的结果?

我尝试了下一种方法,但它们没有帮助或效果不佳:

  1. 由于类别字段是集合,因此不考虑分组。

  2. 分面 returns 只有结果数。我需要一份完整的文件。

  3. 可以对每个类别进行请求。但是一次可以有50个分类我估计在solr中发出50个请求会很耗时

感谢和问候

json.facet 在这里很有用。您可以使用以下查询,它会根据您的需要给您答复。此查询将首先为按升序排序的类别字段创建存储桶,然后使用通过“qq”参数传递的查询的 lucene 分数排序的嵌套 ID 存储桶。

我使用了一个函数查询,我们用它来评估给定查询的 lucene 分数。目前,这是一个简单的查询,但您也可以创建一个复杂的查询并传入 qq 参数。阅读此处:- https://lucene.apache.org/solr/guide/6_6/function-queries.html 或获取有关函数查询的更多信息。

q=*&qq=category:a&json.facet={
categories:{
    type:terms,
    field:category,
    sort:{index:asc},
    facet:{
        id:{
            type:terms,
            field:id,
            sort:"query_score desc",
            facet:{
                query_score:"min(if(exists(query($qq)),query($qq),0))"
            }
        }
    }
}

}

[上述查询的响应]

{
  "responseHeader":{
    "status":0,
    "QTime":7,
    "params":{
      "qq":"category:a",
      "q":"*",
      "json.facet":"{ categories:{ type:terms, field:category, sort:{index:asc}, facet:{ id:{ type:terms, field:id, sort:\"query_score desc\", facet:{ query_score:\"min(if(exists(query($qq)),query($qq),0))\" } } } } }",
      "indent":"on",
      "fl":"*,query($qq,-1)",
      "rows":"0",
      "wt":"json"}},
  "response":{"numFound":5,"start":0,"docs":[]
  },
  "facets":{
    "count":5,
    "categories":{
      "buckets":[{
          "val":"a",
          "count":3,
          "id":{
            "buckets":[{
                "val":"1",
                "count":1,
                "query_score":0.5389965176582336},
              {
                "val":"3",
                "count":1,
                "query_score":0.5389965176582336},
              {
                "val":"5",
                "count":1,
                "query_score":0.5389965176582336}]}},
        {
          "val":"b",
          "count":2,
          "id":{
            "buckets":[{
                "val":"1",
                "count":1,
                "query_score":0.5389965176582336},
              {
                "val":"2",
                "count":1,
                "query_score":0.0}]}},
        {
          "val":"c",
          "count":2,
          "id":{
            "buckets":[{
                "val":"5",
                "count":1,
                "query_score":0.5389965176582336},
              {
                "val":"2",
                "count":1,
                "query_score":0.0}]}},
        {
          "val":"d",
          "count":2,
          "id":{
            "buckets":[{
                "val":"2",
                "count":1,
                "query_score":0.0},
              {
                "val":"4",
                "count":1,
                "query_score":0.0}]}},
        {
          "val":"e",
          "count":3,
          "id":{
            "buckets":[{
                "val":"3",
                "count":1,
                "query_score":0.5389965176582336},
              {
                "val":"2",
                "count":1,
                "query_score":0.0},
              {
                "val":"4",
                "count":1,
                "query_score":0.0}]}}]}}}

有关 json.facet 的更多信息:- https://lucene.apache.org/solr/guide/7_2/json-facet-api.html