我有一个 MongoDB 集合,其文档结构如下:
{
"index": 23,
"chapter": "b11"
},
{
"index": 25,
"chapter": "b11"
},
{
"index": 26,
"chapter": "b14"
},
{
"index": 27,
"chapter": "b14"
},
{
"index": 28,
"chapter": "b16"
}
在我的集合中,我有带有“索引”字段和代表不同章节名称的“章节”字段的文档。
我需要根据特定章节名称(例如“b11”和“b16”)获取一组随机文档(例如,20 个随机文档)。我查询的章节数量可能会有所不同(例如,我可能需要获取“b11”、“b12”、“m14”等三个章节)。关键是我需要为每个指定的章节名称提供相同数量的随机文档。
我知道我需要检索的文档总数应该能被我正在查询的章节数整除。
使用 MongoDB 和 Node.js 作为后端实现这一目标的最有效方法是什么?任何代码示例或见解将不胜感激。谢谢!
我尝试使用基本查询从 MongoDB 集合中获取随机文档,但这并不能保证指定章节名称中文档的均匀分布。我期望为每个章节名称检索均衡数量的文档,但结果参差不齐。我现在正在寻找有关如何实施解决方案的指导,以确保所提供的章节名称的随机文档均匀分布。
我正在考虑使用
$sample
,因为@Fourchette的评论对我来说很有意义。但是,我发现 $sample
不能接受变量作为参数。 (参见这个)
所以我必须在聚合管道中执行以下操作:
$match
只有你想要的章节$divide
目标章节数均匀分布在提取的章节中$lookup
。使用 $setWindowFields
计算章节内的 $rank
并使用 $rand
作为决胜局db.collection.aggregate([
{
"$match": {
chapter: {
$in: [
"b11",
"b14",
"m14"
]
}
}
},
{
$group: {
_id: null,
chapter: {
$addToSet: "$chapter"
}
}
},
{
$set: {
numPerChapter: {
"$divide": [
10,
{
$size: "$chapter"
}
]
}
}
},
{
"$unwind": "$chapter"
},
{
"$lookup": {
"from": "collection",
"let": {
numPerChapter: "$numPerChapter"
},
"localField": "chapter",
"foreignField": "chapter",
"pipeline": [
{
$set: {
randKey: {
"$rand": {}
}
}
},
{
"$setWindowFields": {
"sortBy": {
"randKey": 1
},
"output": {
"rank": {
$rank: {}
}
}
}
},
{
"$match": {
$expr: {
$lte: [
"$randKey",
"$$numPerChapter"
]
}
}
},
{
"$unset": [
"randKey",
"rank"
]
}
],
"as": "picked"
}
},
{
"$unwind": "$picked"
},
{
"$replaceRoot": {
"newRoot": "$picked"
}
}
])