我有一个集合Cats
:
{
"_id" : "rRq76LxsnPfmuh9DD",
"register_id" : "20gnr3g",
"name" : "Meow",
"created_at": ...,
...
}
此合集中的每件商品都有唯一的_id
和唯一的register_id
。
我对猫也有RatingLog
,现在我想按照评级对猫进行排序。从RatingLog
我们可以获得按等级排序的cat register_id
数组:
[
"20gnr3g",
"3412r23",
"221n415",
"Q0g4rEg",
...
]
现在我想使用该数组对Cats
集合进行排序。请注意,Cats
中的所有条目可能未被评分,但应返回所有条目:RatingLog
订单中的第一个和created_at
字段中的其余项目。
我的出版物代码atm:
Meteor.publish('allCats', function(sortType) {
if (sortType == 'rating') {
return Cats.find({}, {sort: {
// How to sort by registerIds array???
}});
}
return Cats.find({}, {sort: { created_at: 1 }});
});
所以问题是:如何在Cats
数组和register_id
字段中对created_at
集合进行排序?
答案 0 :(得分:1)
如果你想反应性地做,你可以用猫存储评级或稍后在Javascript中映射它们。第三个非反应性选项可能是使用带有连接的MongoDB聚合管道(在3.2中添加),但我对此不太熟悉以提供示例。
如果您将评级与猫存储在一起,则变得非常简单:
Meteor.publish('allCats', function (sortType) {
/**
* Assuming that Cats contains contents of the form:
* {
* "_id" : "rRq76LxsnPfmuh9DD",
* "register_id" : "20gnr3g",
* "name" : "Meow",
* "created_at": ...,
* "rating": 123,
* ...
* }
**/
if (sortType == 'rating') {
return Cats.find({}, { sort: { rating: 1 } });
}
return Cats.find({}, { sort: { created_at: 1 } });
});
如果您选择将RatingLog分开并希望结果具有反应性,则需要在客户端执行排序;同时发布allCats
和allCatRatings
:
Meteor.publish('allCats', function() {
return Cats.find({}, {sort: { created_at: 1 }});
});
Meteor.publish('allCatRatings', function() {
return RatingLog.find();
});
订阅这两个后,检索评级并执行排序:
Template.myTemplate.helpers({
cats() {
const sortType = Template.instance().sortType;
if (sortType === 'rating') {
return getCatsByRating();
}
return getCatsByCreationDate();
}
});
function getCatsByCreationDate() {
return Cats.find({}, {sort: { created_at: 1 }});
}
function getCatsByRating() {
/**
* Assuming that RatingLog contains contents of the form { _id: catId, rating: 123 }
**/
const ratings = {};
RatingLog.find().forEach(entry=>ratings[entry._id] = entry.rating);
const defaultRating = 0;
return Cats.find().fetch().sort(function (catA, catB) {
const catARating = ratings[catA._id] || defaultRating;
const catBRating = ratings[catB._id] || defaultRating;
return catARating - catBRating;
});
}