我有一个包含两个属性的MongoDB文档集合:type&值。
[
{type: "A", value: "1"},
{type: "A", value: "2"},
{type: "B", value: "1"},
{type: "B", value: "2"},
{type: "C", value: "1"},
{type: "C", value: "2"}
]
如何使用单个查询获取每种类型的随机文档?
我尝试使用聚合框架
来解决问题db.collection.aggregate([
{$group: {_id: "$type", item: {$push: "$$ROOT"}}},
{$sample: {size: 1}}
]);
不对每个组应用采样,只是选择其中一个组。
答案 0 :(得分:2)
或者,您可以迭代所有分组元素并以$sample
之外的其他方式处理随机:
db.collection.aggregate([
{ $group: { _id: "$type", item: { $push: "$$ROOT" } } }
]).forEach(function(data) {
var rand = data.item[Math.floor(Math.random() * data.item.length)];
// insert in a new collection if needed
// db.results.insert(rand);
printjson(rand);
});
从数组中选择一个随机元素:Getting a random value from a JavaScript array
如果您的集合中有type
的大不同值
答案 1 :(得分:0)
不确定这是否达到了您所寻找的目标,但我一直在尝试做类似的事情,我需要找到一组符合我标准的数据,然后从中获取随机样本。
我现在能够使用$ match和$ sample来实现这一点,如下所示:
db.collection('collectionname').aggregate(
{$match : {'type': 'B'}},
{$sample: {size: 1}}
);
答案 2 :(得分:0)
使用新的mapReduce
框架,一种方法是执行此操作:
db.coll.mapReduce(
/* group by type */
function() { emit(this.type, this.value); },
/* select one random index */
function(u, vs) { return vs[Math.round(Math.random() * vs.length)]; },
/* return the results directly, or use {out: "coll_name" } */
{out: {inline: 1}}
)
out
参数也可以是集合的名称。结果:
{
"results" : [
{
"_id" : "A",
"value" : "2"
},
{
"_id" : "B",
"value" : "2"
},
{
"_id" : "C",
"value" : "1"
}
],
"timeMillis" : 24,
"counts" : {
"input" : 6,
"emit" : 6,
"reduce" : 3,
"output" : 3
},
"ok" : 1
}