从集合中分类条目

时间:2016-02-01 13:44:28

标签: javascript mongodb meteor

在构建我的第一个Meteor应用程序时,我发现了一些我甚至不知道如何接近的东西。 我有一个集合中的条目列表,我想按日期对它们进行分类(而不是按日期对它们进行排序)。每个条目都有一个日期,我想构建类似时间轴的东西。以下是其中一个条目的外观:

{
  "_id": "xHmfEc5gMmGzDZgD2",
  "title": "sth",
  "labels": [
    "pv4LnWNheyYRJqG7D"
  ],
  "images": [
    "zitE3FwmesHsNCxGG",
    "kYQTJYApDxPr4sMdW",
    "4enopyawfqBXRDvuh"
  ],
  "author": "TMviRL8otm3ZsddSt",
  "createdAt": "2016-01-31T21:05:55.401Z",
  "date": "2016-01-31T21:05:55.401Z",
  "description": "desc"
}

最后我希望实现类似时间轴的东西,我希望这些条目属于一天。以下是在天数上划分的时间轴上的情况,每个条目属于一天:

日 - 2016年2月11日

条目 - xHmfEc5gMmGzDZgD2

条目 - ZhmfEc5gMmGzDZg8z

条目 - uafEc5gMmGzDZgD25

日 - 12.02.2016

条目 - xHmfEc5gMmGzDZgD2

条目 - ZhmfEc5gMmGzDZg8z

日 - 2016年2月17日

条目 - xHmfEc5gMmGzDZgD2

条目 - ZhmfEc5gMmGzDZg8z

条目 - xHmfEc5gMmGzDZgD2

条目 - ZhmfEc5gMmGzDZg8z

但是我希望从条目中获取日期,而不是为日历创建单独的集合。如果有可能......

实现这一目标的好方法是什么?

我现在想象的唯一方法就是将条目中的所有不同日期存储到一个单独的集合中,然后每天都应查询条目集合以获得适合的条目。但我认为这是一个非常糟糕的方式,因为每天我都会有数据库查询......

1 个答案:

答案 0 :(得分:2)

您可能希望使用 aggregation framework ,但由于meteor尚未支持聚合,因此您需要安装聚合框架包 - 它不会&# 39;做任何想要做的事,只为你包装一些Mongo方法。

只是流星添加 meteorhacks:aggregate ,您应该开展业务。这将为Meteor添加适当的聚合支持。

现在您需要此管道来实现所需的结果。在mongo shell中,运行以下命令:

var pipeline = [
    {
        "$project": {
            "yearMonthDay": { "$dateToString": { "format": "%Y-%m-%d", "date": "$date" } },         
        }
    },
    {
        "$group": {
            "_id": "$yearMonthDay",
            "entries": { "$push": "$_id" }
        }
    }
];

db.entry.aggregate(pipeline);

在Meteor中,您可以将这些结果发布到客户端的Entries集合中:

Meteor.publish('getDayCategorisedEntries', function (opts) {

    var initializing = 1;

    function run(action) {

        // Define the aggregation pipeline ( aggregate(pipeline) )
        var pipeline = [
            {
                "$project": {
                    "yearMonthDay": { "$dateToString": { "format": "%Y-%m-%d", "date": "$date" } },         
                }
            },
            {
                "$group": {
                    "_id": "$yearMonthDay",
                    "entries": { "$push": "$_id" }
                }
            }
        ];

        Entries.aggregate(pipeline).forEach(function(e){
            this[action]('day-entries', e._id, e)
            this.ready()
        });
    };

    // Run the aggregation initially to add some data to your aggregation collection
    run('added');

    // Track any changes on the collection we are going to use for aggregation
    var handle = Entries.find({}).observeChanges({
        added(id) {
            // observeChanges only returns after the initial `added` callbacks
            // have run. Until then, we don't want to send a lot of
            // `self.changed()` messages - hence tracking the
            // `initializing` state.
            if (initializing && initializing--) run('changed');
        },
        removed(id) {
            run('changed');
        },
        changed(id) {
            run('changed');
        },
        error(err) {
            throw new Meteor.Error('Uh oh! something went wrong!', err.message)
        }
    });

    // Stop observing the cursor when client unsubs.
    // Stopping a subscription automatically takes
    // care of sending the client any removed messages.
    this.onStop(function () {
        handle.stop();
    });
});

以上观察到变化,如有必要,重新进行汇总。