根据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"
}
要求:
- 如果
category
是fruit
,returns所有记录匹配
- 如果
category
不是水果,returns按用户分组的每个类别最多10条记录
- 类别已知且稳定,因此我们可以在查询中进行硬编码。
我想在一次查询中完成。所以预期的结果应该是:
{
"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 } }
])
我有一个关于在 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"
}
要求:
- 如果
category
是fruit
,returns所有记录匹配 - 如果
category
不是水果,returns按用户分组的每个类别最多10条记录 - 类别已知且稳定,因此我们可以在查询中进行硬编码。
我想在一次查询中完成。所以预期的结果应该是:
{
"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 } }
])