【问题标题】:C# MongoDB Take 5 records from every n groupC# MongoDB 从每 n 组中获取 5 条记录
【发布时间】:2021-05-22 14:44:55
【问题描述】:

亲爱的开发者们,你好,

我在使用 MongoDB C# 驱动程序时遇到问题并寻求帮助。

我正在尝试按 machineCode 列对记录进行分组,并从每列中获取 5 条记录。并且还尝试按 insertDate 降序对所有记录进行排序。

到目前为止,我已经尝试了 SO 的几个线程,但在所有尝试中都失败了。

var list = d3TestCollection
    .AsQueryable<D3TestData>()
    .OrderByDescending(q => q.InsertDate)
    .GroupBy(f => f.machinecode)
    .Select(f => new D3MachineListResult {
        MachineCode = f.Key,
        Values = f.Select(q => new D3KeyValueMap { Key = q.Key, Value = q.Value })
                  .Take(5)
                  .ToList()
    }).ToList();

由于 Take(5),此代码抛出 Method Not Supported 错误。

谢谢大家。

示例集合:

{
    "_id" : ObjectId("60a607be339f7c44c0d43b70"),
    "key" : "KEY1",
    "machinecode" : "3DTEST1",
    "value" : false,
    "insertDate" : ISODate("2021-05-20T06:54:54.941Z")
},
{
    "_id" : ObjectId("60a607be339f7c44c0d43b70"),
    "key" : "KEY1",
    "machinecode" : "3DTEST2",
    "value" : false,
    "insertDate" : ISODate("2021-05-20T06:54:54.941Z")
},
{
    "_id" : ObjectId("60a607be339f7c44c0d43b70"),
    "key" : "KEY2",
    "machinecode" : "3DTEST3",
    "value" : false,
    "insertDate" : ISODate("2021-05-20T06:54:54.941Z")
},
{
    "_id" : ObjectId("60a607be339f7c44c0d43b70"),
    "key" : "KEY2",
    "machinecode" : "3DTEST4",
    "value" : false,
    "insertDate" : ISODate("2021-05-20T06:54:54.941Z")
}

【问题讨论】:

  • 尝试在GroupBy阶段内积累文件

标签: c# mongodb aggregation-framework mongodb-.net-driver


【解决方案1】:

您必须使用聚合然后与项目分组。 如果需要对内部数组进行切片,则必须在投影中使用Take,而不是在分组中。

var list = d3TestCollection //IMongoCollection<D3TestData>
        .Aggregate() //IAggregateFluent<D3TestData>
        .SortByDescending(field: x => x.InsertDate)
        .Group(
                id: x => x.machinecode,
                group: x => new D3MachineListResult
                {
                    MachineCode = x.Key,
                    Values = x
                        .Select(z => new D3KeyValueMap
                        {
                            Key = z.Key,
                            Value = z.Value
                        })
                }
            )
        .Project(
            projection: x => new D3MachineListResult
            {
                MachineCode = x.Key,
                Values = x
                    .Select(z => new D3KeyValueMap
                    {
                        Key = z.Key,
                        Value = z.Value
                    })
                    .Take(5)
                
            })
        .ToList();

【讨论】:

    【解决方案2】:

    您需要的聚合如下:

    db.collection.aggregate(
    [
        {
            $sort: { insertDate: -1 }
        },
        {
            $group: {
                _id: "$machinecode",
                docs: { $push: "$$ROOT" }
            }
        },
        {
            $project: {
                _id: 0,
                MachineCode: "$_id",
                Values: {
                    $map: {
                        input: { $slice: ["$docs", 5] },
                        as: "x",
                        in: {
                            key: "$$x.key",
                            value: "$$x.value"
                        }
                    }
                }
            }
        }
    ])
    

    这不能使用 mongo 驱动程序的有限 LINQ 能力来完成,至少不能以强类型的方式。

    【讨论】:

      猜你喜欢
      • 2019-08-03
      • 1970-01-01
      • 1970-01-01
      • 2022-11-17
      • 1970-01-01
      • 1970-01-01
      • 2016-11-26
      • 2022-12-07
      相关资源
      最近更新 更多