假设我在名为“Store”的集合中有以下四个文档:
{ item: 'chair', modelNum: 1154, votes: 75 }
{ item: 'chair', modelNum: 1152, votes: 16 }
{ item: 'table', modelNum: 1017, votes: 24 }
{ item: 'table', modelNum: 1097, votes: 52 }
我想找到每种商品类型的票数最多的文件。 这个简单示例的结果将返回modelNum:1154和modelNum:1097。根据客户输入的投票得分,向我展示最受欢迎的椅子和桌子模型。
编写此查询并按降序投票对其进行排序的最佳方法是什么?我正在使用流星开发,但我不认为这会产生影响。
Store.find({????}).sort({votes: -1});
答案 0 :(得分:1)
您可以使用$first
或$last
聚合运算符来实现您的目标。这些运算符仅在$group
跟$sort
后有用。使用$first
的示例:
db.collection.aggregate([
// Sort by "item" ASC, "votes" DESC
{"$sort" : {item : 1, votes : -1}},
// Group by "item" and pick the first "modelNum" (which will have the highest votes)
{"$group" : {_id : "$item", modelNum : {"$first" : "$modelNum"}}}
])
这是输出:
{
"result" : [
{
"_id" : "table",
"modelNum" : 1097
},
{
"_id" : "chair",
"modelNum" : 1154
}
],
"ok" : 1
}
答案 1 :(得分:1)
如果您希望在Meteor和客户端上执行此操作,我只需使用每个循环和基本查找。 Minimongo将数据保存在内存中,因此我认为额外的find
调用并不昂贵。
Template.itemsList.helpers({
items: function(){
var itemNames = Store.find({}, {fields: {item: 1}}).map(
function( item ) { return item.item; }
);
var itemsMostVotes = _.uniq( itemNames ).map(
function( item ) {
return Store.findOne({item: item}, {sort: {votes: -1}});
}
);
return itemsMostVotes;
}
});
我已经切换到findOne
所以这会返回一个对象数组,而不是find
那样的光标。如果您真的想要光标,那么您可以使用itemMostVotes中的_ids查询minimongo。
您也可以使用underscore groupBy and sortBy函数执行此操作。
答案 2 :(得分:0)
您需要使用聚合框架。
所以
db.Store.aggregate(
{$group:{_id:"$item", "maxVotes": {$max:"$votes"}}}
);