数据结构:

{
  "year": 2020,
  "college": {
    "code": "10003",
    "cnName": "清华大学",
    "categories": ["综合"]
  },
  "rank": 1
}

需求:

按照College.Categories数组中的项分组,取每组Rank前三

查询脚本:

POST myindex/_search
{
  "query": {
    "term": {
      "year": {
        "value": "2020"
      }
    }
  },
  "size": 0,
  "aggs": {
    "categories": {
      "terms": {
        "field": "college.categories" //指定用于分组的字段
      },
      "aggs": {
        "ranks": {
          "top_hits": { //top_hits函数用于排序
            "sort": [ //指定排序的方式和字段
              {
                "rank": {
                  "order": "asc"
                }
              }
            ],
            "size": 3, //指定每组的条数
            "_source": { //指定返回的字段,如果不指定,会返回全部的字段
              "includes": [
                "college.cnName",
                "college.code"
              ]
            }
          }
        }
      }
    }
  }
}

查询结果:

{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1252,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "categories" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 532,
      "buckets" : [
        {
          "key" : "综合",
          "doc_count" : 416,
          "ranks" : {
            "hits" : {
              "total" : {
                "value" : 416,
                "relation" : "eq"
              },
              "max_score" : null,
              "hits" : [
                {
                  "_index" : "myindex",
                  "_type" : "_doc",
                  "_id" : "d21c5bc6-416b-4bc3-a836-27bda316d215",
                  "_score" : null,
                  "_source" : {
                    "college" : {
                      "code" : "xxx",
                      "cnName" : "清华大学"
                    }
                  },
                  "sort" : [
                    1
                  ]
                },
                {
                  "_index" : "myindex",
                  "_type" : "_doc",
                  "_id" : "1f9a04ff-b58e-4c49-aa73-352ed52f15fe",
                  "_score" : null,
                  "_source" : {
                    "college" : {
                      "code" : "xxx",
                      "cnName" : "北京大学"
                    }
                  },
                  "sort" : [
                    2
                  ]
                },
                {
                  "_index" : "myindex",
                  "_type" : "_doc",
                  "_id" : "1826c73d-3062-4f49-9bda-0b63d065e3fe",
                  "_score" : null,
                  "_source" : {
                    "college" : {
                      "code" : "xxx",
                      "cnName" : "浙江大学"
                    }
                  },
                  "sort" : [
                    3
                  ]
                }
              ]
            }
          }
        },
        {
          "key" : "理工",
          "doc_count" : 332,
          "ranks" : {
            "hits" : {
              "total" : {
                "value" : 332,
                "relation" : "eq"
              },
              "max_score" : null,
              "hits" : [
                {
                  "_index" : "myindex",
                  "_type" : "_doc",
                  "_id" : "1c71ea27-f29c-44a4-9cd9-ae0d147d9e5b",
                  "_score" : null,
                  "_source" : {
                    "college" : {
                      "code" : "xxx",
                      "cnName" : "中国科学院大学"
                    }
                  },
                  "sort" : [
                    12
                  ]
                },
                {
                  "_index" : "myindex",
                  "_type" : "_doc",
                  "_id" : "f1838123-5c5b-483a-8e79-502c22276509",
                  "_score" : null,
                  "_source" : {
                    "college" : {
                      "code" : "xxx",
                      "cnName" : "北京航空航天大学"
                    }
                  },
                  "sort" : [
                    13
                  ]
                },
                {
                  "_index" : "myindex",
                  "_type" : "_doc",
                  "_id" : "2bf43eb9-b23e-457a-923d-e37e8db6107f",
                  "_score" : null,
                  "_source" : {
                    "college" : {
                      "code" : "xxx",
                      "cnName" : "哈尔滨工业大学"
                    }
                  },
                  "sort" : [
                    16
                  ]
                }
              ]
            }
          }
        }
      ]
    }
  }
}

翻译成 C#代码:

var response = await Client.SearchAsync<CollegeGlobalRank>(x => x.Index(IndexName)
                .Query(y => y.Bool(c => c.Must(conditions)))
                .Aggregations(
                    aggs =>
                        aggs.Terms("categories", t => t.Field(f => f.College.Categories).Size(count)
                            .Aggregations(agg => agg.TopHits("ranks", tt => tt.Sort(sort => sort.Ascending(f => f.Rank)).Size(3).Source(source => source.Includes(f => f.Fields(ff => ff.College.CnName, ff => ff.Rank))))))
                ));

取值:

翻译完之后取值也是花费了一些功夫研究的,取值代码如下:

            var result = new List<NameValue<IList<CollegeGlobalRank>>>();
            foreach (var aggsItem in response.Aggregations)
            {
                var buckets = (BucketAggregate)aggsItem.Value;
                if (buckets.IsNotNull() && buckets.Items.Count > 0)
                {
                    foreach (var bucket in buckets.Items)
                    {
                        var bucketItem = (KeyedBucket<object>)bucket;
                        foreach (var aggregate in bucketItem.Values)
                        {
                            var values = (TopHitsAggregate)aggregate;
                            var ranks = values.Documents<CollegeGlobalRank>().ToList();
                            var item = new NameValue<IList<CollegeGlobalRank>>()
                            {
                                Name = bucketItem.Key.ToString(),
                                Value = ranks
                            };
                            result.Add(item);
                        }
                    }
                }
            }
最后修改:2021 年 12 月 10 日
如果觉得我的文章对你有用,请随意赞赏