根据MongoDB中的条件查询每组最多N条记录?

Query maximum N records of each group base on a condition in MongoDB?

我有一个关于在 MongoDB 中查询数据的问题。这是我的示例数据:

{
    "_id": 1,
    "category": "fruit",
    "userId": 1,
    "name": "Banana"
},
{
    "_id": 2,
    "category": "fruit",
    "userId": 2,
    "name": "Apple"
},
{
    "_id": 3,
    "category": "fresh-food",
    "userId": 1,
    "name": "Fish"
},
{
    "_id": 4,
    "category": "fresh-food",
    "userId": 2,
    "name": "Shrimp"
},
{
    "_id": 5,
    "category": "vegetable",
    "userId": 1,
    "name": "Salad"
},
{
    "_id": 6,
    "category": "vegetable",
    "userId": 2,
    "name": "carrot"
}

要求:

  1. 如果categoryfruit,returns所有记录匹配
  2. 如果category不是水果,returns按用户分组的每个类别最多10条记录
  3. 类别已知且稳定,因此我们可以在查询中进行硬编码。

我想在一次查询中完成。所以预期的结果应该是:

{
    "fruit": [
        ... // All records of 
    ],
    "fresh-food": [
        {
            "userId": 1,
            "data": [
            // Top 10 records of user 1 with category = "fresh-food"
            ]
        },
        {
            "userId": 2,
            "data": [
            // Top 10 records of user 2 with category = "fresh-food"
            ]
        },
        ...
    ],
    "vegetable": [
    {
            "userId": 1,
            "data": [
            // Top 10 records of user 1 with category = "vegetable"
            ]
        },
        {
            "userId": 2,
            "data": [
            // Top 10 records of user 2 with category = "vegetable"
            ]
        },
    ]   
}

我找到了使用 $group$slice 按每个组分组的指南,但我无法应用要求编号 #1。

如有任何帮助,我们将不胜感激。

你需要为此使用聚合

  • $facet 对传入的数据进行分类,我们分为两类。 1.水果和2.non_fruit
  • $match匹配条件
  • $group 第一组根据类别和用户对数据进行分组。第二组仅按类别分组
  • $objectToArray将对象做成键值对
  • $replaceRoot 使 non_fruit 用水果生根

这是代码

db.collection.aggregate([
  {
    "$facet": {
      "fruit": [
        { $match: { "category": "fruit"  } }
      ],
      "non_fruit": [
        {
          $match: {
            $expr: {
              $ne: [ "$category", "fruit" ]
            }
          }
        },
        {
          $group: {
            _id: { c: "$category", u: "$userId" },
            data: { $push: "$$ROOT" }
          }
        },
        {
          $group: {
            _id: "$_id.c",
            v: {
              $push: {
                uerId: "$_id.u",
                data: { "$slice": [ "$data", 3 ] }
              }
            }
          }
        },
        { $addFields: {  "k": "$_id", _id: "$$REMOVE" } }        
      ]
    }
  },
  { $addFields: { non_fruit: { "$arrayToObject": "$non_fruit" } }},
  {
    "$replaceRoot": {
      "newRoot": {
        "$mergeObjects": [ "$$ROOT", "$non_fruit" ]
      }
    }
  },
  { $project: { non_fruit: 0 } }
])

工作Mongo playground