我正在研究Meteor应用程序,我有每周时间表格式的数据 -
events:
event:
day: "Monday"
time: "9am"
location: "A"
event:
day: "Monday"
time: "10am"
location: "B"
每天都有很多条目。我可以运行一个返回格式对象的查询 -
day: "Monday"
events:
event:
time: "9am"
location: "A"
event:
time: "10am"
location: "B"
我可以将对象存储为第二种格式,但更喜欢第一种格式,以便于删除和更新单个事件。
如果有一个很好的方法,我也希望按星期几的顺序返回它们。
答案 0 :(得分:0)
要获得所需的结果,请使用 aggregation framework ,其中 $group
管道运算符对所有输入文档进行分组并应用累加器表达式< strong> $push
到该组以获取事件数组。
你的管道看起来像这样:
var Events = new Mongo.Collection('events');
var pipeline = [
{
"$group": {
"_id": "$day",
"events": {
"$push": {
"time": "$time"
"location": "$location"
}
}
}
},
{
"$project": {
"_id": 0, "day": "$_id", "events": 1
}
}
];
var result = Events.aggregate(pipeline);
console.log(result)
您可以添加 meteorhacks:aggregate package 来实现Meteor中的聚合:
使用
添加到您的应用中meteor add meteorhacks:aggregate
由于此程序包在Mongo.Collection实例上公开 .aggregate
方法,因此您可以定义获取聚合结果数组的方法。例如
if (Meteor.isServer) {
var Events = new Mongo.Collection('events');
Meteor.methods({
getGroupedDailyEvents: function () {
var pipeline = [
{
"$group": {
"_id": "$day",
"events": {
"$push": {
"time": "$time"
"location": "$location"
}
}
}
},
{
"$project": {
"_id": 0, "day": "$_id", "events": 1
}
}
];
var result = Events.aggregate(pipeline);
return result;
}
});
}
if (Meteor.isClient) {
Meteor.call('getGroupedDailyEvents', logResult);
function logResult(err, res) {
console.log("Result: ", res)
}
}
答案 1 :(得分:0)
有几个选择:
您可以使用聚合命令但要注意,您将失去反应性:这意味着除非您重新加载模板,否则您将无法获得外部更新。您还需要使用a package to add the aggregation command to Meteor才能实现这一目标。
我个人的最爱:您不需要聚合(和松散的反应性)来实现数据转换。您可以使用简单的Collection.find()
查询,并使用cursor.Observe()
和条件修改的巧妙组合来扩展/缩小/修改它。看看这个答案,它为我做了伎俩(我需要一些黑色列表中的一些字段,但你可以轻松地将它调整到你的组/排序案例):https://stackoverflow.com/a/30813050/3793161。如果您需要有关此
insert
更新它们。编辑以下是您对评论的一些看法:
如果你坚持你在问题中描述的内容,你需要七个文件,每天一个,events
字段,你可以放置所有事件。如果您需要在发送之前重新设计集合结构,那么我的第二个解决方案是好的。但是,在您的情况下,您只需要一个对象week
,其中有7个子对象与星期几匹配。
我建议你采取可能的方法:
$group
文档中所述$ group未订购其输出文件
因此,在返回方法结果之前,您需要使用例如_.sortBy()
对它们进行排序(按天和按天计算)。顺便说一句,如果您想知道方法调用中发生了什么, clientside ,这就是您应该如何编写调用:
Meteor.call("getGroupedDailyEvents", userId, function(error, result){
if(error){
console.log("error", error);
}
if(result){
//do whatever you need
}
});
在客户端进行数据排序。您正在寻找一种矫枉过正的解决方案,因为afaik,您不需要过滤任何数据以使其不受用户影响,并且您仍将发送数据(仅使用其他结构)。在模板中制作一个简单的帮助器要容易得多:
Template.displaySchedule.helpers({
"monday_events": function() {
return _.sortBy (events.find({day:"Monday"}).fetch(), "time")
},
//add other days
);
它假设您的time
字段的格式可以这种方式排序。如果没有,您只需要创建一个函数来根据它们的格式对它们进行排序,或者将原始格式更改为更适合的格式。
其余的(HTML)只是使用{{#each monday_events}}