首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MongoDB分组查询

MongoDB分组查询
EN

Stack Overflow用户
提问于 2015-07-20 16:06:40
回答 2查看 140关注 0票数 1

我正在做一个流星应用程序,我有每周格式时间表的数据-

代码语言:javascript
复制
events:
    event:
       day: "Monday"
       time: "9am"
       location: "A"
    event:
       day: "Monday"
       time: "10am"
       location: "B"

每天都有许多条目。我能不能运行一个查询来返回一个格式的对象-

代码语言:javascript
复制
day: "Monday"
   events:
      event:
         time: "9am"
         location: "A"
      event:
         time: "10am"
         location: "B"

我可以将对象存储在第二种格式中,但为了便于删除和更新单个事件,我更喜欢使用第一种格式。

如果有很好的方法,我也想把每周一天的订单退回去。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-07-20 16:37:43

若干备选方案:

  1. 您可以使用聚合命令,但请注意,您将失去反应性:这意味着,除非您重新加载您的模板,您将不会得到外部更新。为了实现这一点,您还需要使用将聚合命令添加到Meteor的包
  2. 我个人最喜欢的是:您不需要聚合(和松散的反应性)来实现数据转换。您可以使用一个简单的Collection.find()查询,并使用cursor.Observe()和条件修改的巧妙组合扩展/减少/修改它。看看这个答案,它对我来说很管用(我需要一个带有黑名单的字段的和,但是您可以很容易地将它调整到您的组/排序案例中):https://stackoverflow.com/a/30813050/3793161。如果您需要更多关于这方面的详细信息,请评论
  3. 如果您计划拥有多个服务器,请注意,每个服务器都必须进行观察,因此可能会导致不必要的负载。因此,我的第三个解决方案是使用集合钩子或方法更新一个额外的字段,其中包含每天/用户(您需要的).See @David回答的每个事件:https://stackoverflow.com/a/31190896/3793161。在您的情况下,这可能意味着重新考虑您的数据库结构以满足您的需要(即添加更多的字段,以便您可以在insert上更新它们。

编辑在这里对您的评论有一些想法:

如果您坚持您在问题中描述的内容,您将需要七个文档,每天一个文档,其中包含一个events字段,您可以在其中放置所有事件。我的第二个解决方案是很好的,如果您需要在发送之前重新工作一个集合结构。但是,在您的示例中,您只需要一个对象week,其中有7个子对象与一周中的时间相匹配。

我建议你采取可能的办法:

  • 在方法中使用聚合,如@chridam所述。请注意,如mongo $group文档所述,您将无法直接获得排序数组。

$group不订购它的输出文档。

因此,您需要在返回方法结果之前使用_.sortBy()对它们进行排序(按日排序和每天按小时排序)。顺便说一句,如果您想知道方法调用( clientside )中发生了什么,那么应该如何编写这个调用:

代码语言:javascript
复制
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":函数()){返回_.sortBy (events.find({day:“周一”}).fetch(),“time”} },//添加其他天数);

它假设time字段的格式是这样排序的。如果没有,您只需要创建一个函数来对其格式进行相应的排序,或者将原始格式更改为更适合的格式。

其余的(HTML)只是在周一事件上使用{{#each monday_events}}迭代

票数 0
EN

Stack Overflow用户

发布于 2015-07-20 16:36:48

要实现所需的结果,请使用聚合框架,其中$group管道操作符对所有输入文档进行分组,并将累加器表达式$push应用到组中以获取事件数组。

你的管道应该是这样的:

代码语言:javascript
复制
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)

您可以添加陨石:总包来实现Meteor中的聚合:

添加到您的应用程序

代码语言:javascript
复制
meteor add meteorhacks:aggregate

因为这个包在.aggregate实例上公开了Mongo.Collection方法,所以您可以定义一个获取聚合结果数组的方法。例如

代码语言:javascript
复制
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)
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31521229

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档