我有复杂的公式p / a^5
我想要对一个集合进行排序,其中p
和a
是集合Items
的属性。
在Meteor(MongoDB)中有没有办法做到这一点?
答案 0 :(得分:1)
不,你不能这样做。我建议添加另一个存储p / a^5
值的字段。例如。假设您将此字段称为pResult
,那么您可以这样做:
collection.find(selector, {sort: {pResult: 1}});
答案 1 :(得分:0)
您只需fetch()
该集合,然后使用常规Array.prototype.sort
或_.sortBy
进行排序。但是,这会破坏细粒度的反应性,因此如果您的集合很大或者渲染的元素足够复杂,并且集合会随着时间的推移而发生很大变化,那么您可能会遇到性能问题。
Template.whatever.helpers({
items: function () {
return _.sortBy(Items.find().fetch(), function (item) {
return item.p / Math.pow(item.a, 5);
});
}
});
<template name="whatever">
{{#each items}}
<!-- ... -->
{{/each}}
</template>
如果您需要细粒度的反应性,您可以查看我的包collection-view,但我不认为它已准备就绪。
答案 2 :(得分:0)
您可以使用 aggregation framework 。您可以构建聚合管道,以便它通过使用算术运算符 $multiply
执行指数函数,将n
称为n
指数的次数r
例如,以下聚合管道将添加一个额外的字段p / a^5
,这是操作exponents
的结果。
首先,在mongo shell中,在for(x=0; x < 10; x++){ db.exponents.insert({p: 5*x, a: x }); }
集合中创建一些示例文档:
var pipeline = [
{
"$match" : {
"a" : {
"$gt" : 0
}
}
},
{
"$project" : {
"p" : 1,
"a" : 1,
"r" : {
"$divide" : [
"$p",
{
"$multiply" : [
"$a",
"$a",
"$a",
"$a",
"$a"
]
}
]
}
}
},
{
"$sort" : {
"r" : 1
}
}
];
生成管道:
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
}
<强>输出强>:
.aggregate
您可以设置一个通用辅助函数来生成管道代码,以使用幂函数的文档表示中的算术运算符提取 $project
运算符。由于Meteor尚不支持聚合,请使用 meteorhacks:aggregate 包,为Meteor添加适当的聚合支持。此程序包在Mongo.Collection
个实例上公开了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);
参数:
STRING