Mongodb查询,用于从集合中拾取随机文档,直到达到数量
我收集了如下文件: 歌曲Mongodb查询,用于从集合中拾取随机文档,直到达到数量,mongodb,Mongodb,我收集了如下文件: 歌曲 { "title": "Highway To Hell", "duration": 4 "tags": [{"label":"rock"},{"label":"heavy"}] } { "title": "Never Be The Same", "duration": 3 "tags": [{"label":"pop"}] } { "title": "Wake Up", "duration": 4 "tags": [{"label":
{
"title": "Highway To Hell",
"duration": 4
"tags": [{"label":"rock"},{"label":"heavy"}]
}
{
"title": "Never Be The Same",
"duration": 3
"tags": [{"label":"pop"}]
}
{
"title": "Wake Up",
"duration": 4
"tags": [{"label":"metal"},{"label":"heavy"}]
}
{
"title": "Catharsis",
"duration": 3
"tags": [{"label":"metal"},{"label":"heavy"}]
}
我想查询最长持续时间为8分钟、标签为“重”的随机歌曲
查询结果1
{
"title": "Highway To Hell",
"duration": 4
"tags": [{"label":"rock"},{"label":"heavy"}]
}
{
"title": "Wake Up",
"duration": 4
"tags": [{"label":"metal"},{"label":"heavy"}]
}
查询结果2
{
"title": "Highway To Hell",
"duration": 4
"tags": [{"label":"rock"},{"label":"heavy"}]
}
{
"title": "Catharsis",
"duration": 3
"tags": [{"label":"metal"},{"label":"heavy"}]
}
我已经检查了$sample操作符,但您需要随机文档的数量,但在本例中,数量不是固定的。需要一个变量来保存“持续时间”,但我不确定如何实现这一点。您可以尝试这种聚合吗
$match
-仅匹配标记包含重$sample
-获取n个样本(未保证的元素顺序)$group
-按id分组,以便在下一阶段减少$project
-使用$reduce计算每首歌曲的持续时间和最大持续时间,如果未达到最大持续时间,则将歌曲添加到数组中,否则忽略它$unwind
-解除过滤后的歌曲$replaceRoot
-获取原始文档结构中的歌曲 db.songs.aggregate(
[
{$match : {"tags.label" : "heavy"}},
{$sample : {size : 8}},
{$group : {_id : null, songs : {$push : "$$ROOT"}}},
{$project : {
songs : {
$reduce : {
input : "$songs",
initialValue : { filtered : [], total : 0 },
in : {
total : {$add : ["$$value.total",{$cond :[{$lte : [{$add : ["$$value.total", "$$this.duration"]}, 8]},"$$this.duration", 0]}]},
filtered : {$concatArrays : [ "$$value.filtered", {$cond :[{$lte : [{$add : ["$$value.total", "$$this.duration"]}, 8]},["$$this"], []]}]}
}
}
}
}
},
{$unwind : "$songs.filtered"},
{$replaceRoot : {newRoot : "$songs.filtered"}}
]
).pretty()
为问题中的测试数据生成的可能输出
> db.songs.aggregate( [ {$match : {"tags.label" : "heavy"}}, {$sample : {size : 8}}, {$group : {_id : null, songs : {$push : "$$ROOT"}}}, {$project : { songs : { $reduce : { input : "$songs", initialValue : { filtered : [], total : 0 }, in : { total : {$add : ["$$value.total",{$cond :[{$lte : [{$add : ["$$value.total", "$$this.duration"]}, 8]},"$$this.duration", 0]}]}, filtered : {$concatArrays : [ "$$value.filtered", {$cond :[{$lte : [{$add : ["$$value.total", "$$this.duration"]}, 8]},["$$this"], []]}]} } } } } }, {$unwind : "$songs.filtered"}, {$replaceRoot : {newRoot : "$songs.filtered"}} ] ).pretty()
{
"_id" : ObjectId("5a7739693eafa689da47ba81"),
"title" : "Wake Up",
"duration" : 4,
"tags" : [
{
"label" : "metal"
},
{
"label" : "heavy"
}
]
}
{
"_id" : ObjectId("5a7739693eafa689da47ba7f"),
"title" : "Highway To Hell",
"duration" : 4,
"tags" : [
{
"label" : "rock"
},
{
"label" : "heavy"
}
]
}
>
> db.songs.aggregate( [ {$match : {"tags.label" : "heavy"}}, {$sample : {size : 8}}, {$group : {_id : null, songs : {$push : "$$ROOT"}}}, {$project : { songs : { $reduce : { input : "$songs", initialValue : { filtered : [], total : 0 }, in : { total : {$add : ["$$value.total",{$cond :[{$lte : [{$add : ["$$value.total", "$$this.duration"]}, 8]},"$$this.duration", 0]}]}, filtered : {$concatArrays : [ "$$value.filtered", {$cond :[{$lte : [{$add : ["$$value.total", "$$this.duration"]}, 8]},["$$this"], []]}]} } } } } }, {$unwind : "$songs.filtered"}, {$replaceRoot : {newRoot : "$songs.filtered"}} ] ).pretty()
{
"_id" : ObjectId("5a7739693eafa689da47ba7f"),
"title" : "Highway To Hell",
"duration" : 4,
"tags" : [
{
"label" : "rock"
},
{
"label" : "heavy"
}
]
}
{
"_id" : ObjectId("5a7739693eafa689da47ba82"),
"title" : "Catharsis",
"duration" : 3,
"tags" : [
{
"label" : "metal"
},
{
"label" : "heavy"
}
]
}
> db.songs.aggregate( [ {$match : {"tags.label" : "heavy"}}, {$sample : {size : 8}}, {$group : {_id : null, songs : {$push : "$$ROOT"}}}, {$project : { songs : { $reduce : { input : "$songs", initialValue : { filtered : [], total : 0 }, in : { total : {$add : ["$$value.total",{$cond :[{$lte : [{$add : ["$$value.total", "$$this.duration"]}, 8]},"$$this.duration", 0]}]}, filtered : {$concatArrays : [ "$$value.filtered", {$cond :[{$lte : [{$add : ["$$value.total", "$$this.duration"]}, 8]},["$$this"], []]}]} } } } } }, {$unwind : "$songs.filtered"}, {$replaceRoot : {newRoot : "$songs.filtered"}} ] ).pretty()
{
"_id" : ObjectId("5a7739693eafa689da47ba82"),
"title" : "Catharsis",
"duration" : 3,
"tags" : [
{
"label" : "metal"
},
{
"label" : "heavy"
}
]
}
{
"_id" : ObjectId("5a7739693eafa689da47ba81"),
"title" : "Wake Up",
"duration" : 4,
"tags" : [
{
"label" : "metal"
},
{
"label" : "heavy"
}
]
}
>
你能提出你的问题吗?