为了账号安全,请及时绑定邮箱和手机立即绑定

ElasticSearch NEST - GroupBy then OrderBy

ElasticSearch NEST - GroupBy then OrderBy

C#
烙印99 2022-08-20 16:51:36
我需要将 linq 查询转换为 NEST。这就是我的 linq 查询的样子:var result = studentList             .GroupBy(student => student.Name)             .Select(group => group.OrderByDescending(student => student.grade).Take(3))             .SelectMany(p => p);它应该:按学生姓名分组按年级对每个组进行个人排序,降序从每个小组中选出成绩最好的前X名学生它正在与linq一起工作,但是如何使用NEST做到这一点?我尝试聚合,子聚合,排序桶,但没有成功。我知道如何按名称分组,但接下来呢?client.Search<Students>(s => s .Aggregations(a => a     .Terms("group_by_name", ts => ts         .Field(o => o.Name))));如何对每个小组进行排序,如何从每个小组的顶尖学生中取出?
查看完整描述

1 回答

?
侃侃尔雅

TA贡献1801条经验 获得超16个赞

假设模型像


public class Student 

{

    public int Id { get; set; }

    public string Name { get; set; }

    public int Grade { get; set; }

}

以下内容将按学生姓名分组,然后按年级降序排列每个组中的前 x 个匹配项


private static void Main()

{

    var defaultIndex = "students";

    var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));


    var settings = new ConnectionSettings(pool)

        .DefaultIndex(defaultIndex);


    var client = new ElasticClient(settings);


    if (client.IndexExists(defaultIndex).Exists)

        client.DeleteIndex(defaultIndex);


    var createIndexResponse = client.CreateIndex(defaultIndex, c => c

        .Settings(s => s

            .NumberOfShards(1)

            .NumberOfReplicas(0)

        )

        .Mappings(m => m

            .Map<Student>(mm => mm

                .AutoMap()

            )

        )

    );


    var students = Enumerable.Range(1, 20).Select(i =>

        new Student 

        {

            Id = i,

            Name = i % 2 == 0 ? "Foo" : "Bar",

            Grade = i

        }

    );


    var bulkResponse = client.Bulk(b => b

        .IndexMany(students)

        .Refresh(Refresh.WaitFor) // refresh, so that documents indexed are available to search immediately

    );


    var topX = 10;


    var searchResponse = client.Search<Student>(s => s

        .Aggregations(a => a

            .Terms("student_name", t => t

                .Field(f => f.Name.Suffix("keyword"))

                .Aggregations(aa => aa

                    .TopHits("top_grades", th => th

                        .Sort(so => so

                            .Descending(f => f.Grade)

                        )

                        .Size(topX)

                    )

                )

            )

        )

    );


    var studentNames = searchResponse.Aggregations.Terms("student_name");


    foreach(var bucket in studentNames.Buckets)

    {

        var header = $"Student Name: {bucket.Key}";

        Console.WriteLine(header);

        Console.WriteLine(new string('-', header.Length));

        foreach(var hit in bucket.TopHits("top_grades").Documents<Student>())

        {

            Console.WriteLine($"Id: {hit.Id}, Grade: {hit.Grade}");

        }

        Console.WriteLine();

    }

}

它打印出来


Student Name: Bar

-----------------

Id: 19, Grade: 19

Id: 17, Grade: 17

Id: 15, Grade: 15

Id: 13, Grade: 13

Id: 11, Grade: 11

Id: 9, Grade: 9

Id: 7, Grade: 7

Id: 5, Grade: 5

Id: 3, Grade: 3

Id: 1, Grade: 1


Student Name: Foo

-----------------

Id: 20, Grade: 20

Id: 18, Grade: 18

Id: 16, Grade: 16

Id: 14, Grade: 14

Id: 12, Grade: 12

Id: 10, Grade: 10

Id: 8, Grade: 8

Id: 6, Grade: 6

Id: 4, Grade: 4

Id: 2, Grade: 2


查看完整回答
反对 回复 2022-08-20
  • 1 回答
  • 0 关注
  • 138 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号