如何在Meteor(MongoDB)中使用复杂函数对集合进行排序
我有一个复杂的公式如何在Meteor(MongoDB)中使用复杂函数对集合进行排序,mongodb,sorting,meteor,Mongodb,Sorting,Meteor,我有一个复杂的公式p/a^5我想用它对集合进行排序,其中p和a是集合项的属性 在Meteor(MongoDB)中有没有任何可能的方法可以做到这一点?您可以只获取()集合,然后使用常规的数组.prototype.sort或.sortBy进行排序。但是,这会破坏细粒度的反应性,因此,如果您的集合很大,或者呈现的元素足够复杂,并且集合随时间变化很大,那么您可能会遇到性能问题 Template.whatever.helpers({ 项目:功能(){ return.sortBy(Items.find().
p/a^5
我想用它对集合进行排序,其中p
和a
是集合项的属性
在Meteor(MongoDB)中有没有任何可能的方法可以做到这一点?您可以只获取()集合,然后使用常规的数组.prototype.sort
或.sortBy
进行排序。但是,这会破坏细粒度的反应性,因此,如果您的集合很大,或者呈现的元素足够复杂,并且集合随时间变化很大,那么您可能会遇到性能问题
Template.whatever.helpers({
项目:功能(){
return.sortBy(Items.find().fetch(),函数(item){
返回项目p/Math.pow(项目a,5);
});
}
});
{{{#每项}
{{/每个}}
如果您需要细粒度的反应性,您可以查看我的包,虽然我不认为它已经准备好了。
< P>不,您不能这样做。我建议添加另一个存储p/a^5
值的字段。例如,假设您调用此字段pResult
,那么您可以执行以下操作:
collection.find(selector, {sort: {pResult: 1}});
您可以为此使用。通过使用算术运算符,调用它n
的次数,其中n
是指数,可以构造聚合管道,使其执行指数函数
例如,下面的聚合管道将添加一个额外字段r
,它是操作p/a^5
的结果
首先,在mongo shell中,在exponents
集合中创建一些示例文档:
for(x=0; x < 10; x++){ db.exponents.insert({p: 5*x, a: x }); }
使用上面的示例文档运行管道:
db.exponents.aggregate(pipeline);
输出:
/* 0 */
{
"result" : [
{
"_id" : ObjectId("561d1ced3d8f561c1548d393"),
"p" : 45,
"a" : 9,
"r" : 0.0007620789513793629
},
{
"_id" : ObjectId("561d1ced3d8f561c1548d392"),
"p" : 40,
"a" : 8,
"r" : 0.001220703125
},
{
"_id" : ObjectId("561d1ced3d8f561c1548d391"),
"p" : 35,
"a" : 7,
"r" : 0.002082465639316951
},
{
"_id" : ObjectId("561d1ced3d8f561c1548d390"),
"p" : 30,
"a" : 6,
"r" : 0.003858024691358025
},
{
"_id" : ObjectId("561d1ced3d8f561c1548d38f"),
"p" : 25,
"a" : 5,
"r" : 0.008
},
{
"_id" : ObjectId("561d1ced3d8f561c1548d38e"),
"p" : 20,
"a" : 4,
"r" : 0.01953125
},
{
"_id" : ObjectId("561d1ced3d8f561c1548d38d"),
"p" : 15,
"a" : 3,
"r" : 0.06172839506172839
},
{
"_id" : ObjectId("561d1ced3d8f561c1548d38c"),
"p" : 10,
"a" : 2,
"r" : 0.3125
},
{
"_id" : ObjectId("561d1ced3d8f561c1548d38b"),
"p" : 5,
"a" : 1,
"r" : 5
}
],
"ok" : 1
}
您可以设置用于生成管道代码的通用帮助函数,以从幂函数的文档表示中使用算术运算符提取运算符。由于Meteor中还不支持聚合,请使用为Meteor添加适当聚合支持的包。此包在Mongo.Collection
实例上公开.aggregate
方法
使用添加到您的应用程序
meteor add meteorhacks:aggregate
然后只需将.aggregate()
函数与泛型函数一起使用,即可生成管道,用作下面的.aggregate()
参数:
function power(exponent) {
var multiply = [];
for (var count = 0; count < exponent; count++){
multiply.push("$a");
}
return [
{ $match: { a: { $gt: 0} } },
{
$project: {
p: 1, a: 1, r : { $divide: [ "$p", { $multiply: multiply } ] }
}
},
{
"$sort": { r: 1 }
}
];
}
var pipeline = power(5),
exponents = new Mongo.Collection('exponents'),
result = exponents.aggregate(pipeline);
函数幂(指数){
var乘法=[];
对于(变量计数=0;计数<指数;计数++){
乘法推送($a);
}
返回[
{$match:{a:{$gt:0}},
{
$项目:{
p:1,a:1,r:{$divide:[“$p”,{$multiply:multiply}]}
}
},
{
“$sort”:{r:1}
}
];
}
var管道=功率(5),
exponents=新的Mongo.Collection('exponents'),
结果=指数。聚合(管道);
我考虑过这种方法,但是如果a
随着时间的推移而改变,比如,每小时我都应该更新a
的值?如果每个实体的p
值每小时增加1会怎样?不确定我是否正确回答了你的其他问题,但我认为如果你提出一个新问题,详细说明你在p
值发生变化时尝试过的方法,你会得到更好的回答。我想您需要基于计数器或setTimeout运行聚合?
function power(exponent) {
var multiply = [];
for (var count = 0; count < exponent; count++){
multiply.push("$a");
}
return [
{ $match: { a: { $gt: 0} } },
{
$project: {
p: 1, a: 1, r : { $divide: [ "$p", { $multiply: multiply } ] }
}
},
{
"$sort": { r: 1 }
}
];
}
var pipeline = power(5),
exponents = new Mongo.Collection('exponents'),
result = exponents.aggregate(pipeline);