流星和DBRefs [英] Meteor and DBRefs

查看:72
本文介绍了流星和DBRefs的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Win7(32)中使用流星0.3.7,并尝试使用2个MongoDB集合创建一个简单的日志记录系统来存储由DBRef链接的数据.

I'm using meteor 0.3.7 in Win7(32) and trying to create a simple logging system using 2 MongoDB collections to store data that are linked by DBRef.

当前的伪模式为:

    Users {
      username : String,
      password : String,
      created  : Timestamp,
    }

    Logs {
      user_id : DBRef {$id, $ref}
      message : String
    }

我使用服务器方法来插入日志,以便可以对客户端集合进行一些更新.

I use server methods to insert the logs so I can do some upserts on the clients collection.

现在,我想做一个旧的左连接"并显示带有嵌入的用户名的最后n个日志的列表. 我不想在用户中嵌入日志,因为最常用的操作是获取最近的n条日志.我认为嵌入将对性能产生重大影响.

Now I want to do an old "left join" and display a list of the last n logs with the embedded User name. I don't want to embed the Logs in Users because the most used operation is getting the last n logs. Embedding in my opinion was going to have a big impact in performance.

实现此目标的最佳方法是什么?

What is the best approach to achieve this?

接下来,最好编辑用户名,并且所有项目都更改其名称

Next it was great if possible to edit the User name and all items change theis name

致谢

推荐答案

玩Cursor.observe回答了我的问题.这样做可能不是最有效的方法,但解决了我将来取消引用DBRefs链接"的问题.

Playing around with Cursor.observe answered my question. It may not be the most effective way of doing this, but solves my future problems of derefering DBRefs "links"

因此对于服务器,我们需要发布一个特殊的集合.它可以枚举光标,并且可以为每个文档搜索相应的DBRef. 请记住,此实现是硬编码的,应作为UnRefCollection之类的程序包完成.

So for the server we need to publish a special collection. One that can enumerate the cursor and for each document search for the corresponding DBRef. Bare in mind this implementation is hardcoded and should be done as a package like UnRefCollection.

服务器端

    CC.Logs = new Meteor.Collection("logs");
    CC.Users = new Meteor.Collection("users");

Meteor.publish('logsAndUsers', function (page, size) {
    var self = this;
    var startup = true;  
    var startupList = [], uniqArr = [];

    page = page || 1;
    size = size || 100;
    var skip = (page - 1) * size;

    var cursor = CC.Logs.find({}, {limit : size, skip : skip});
    var handle = cursor.observe({
        added : function(doc, idx){
            var clone = _.clone(doc);
            var refId = clone.user_id.oid; // showld search DBRefs
            if (startup){
                startupList.push(clone);    
                if (!_.contains(uniqArr, refId))
                    uniqArr.push(refId);
            } else {
                // Clients added logs
                var deref = CC.Users.findOne({_id : refid});
                clone.user = deref;
                self.set('logsAndUsers', clone._id, clone);
                self.flush();
            }
        },
        removed : function(doc, idx){
            self.unset('logsAndUsers', doc._id, _.keys(doc));
            self.flush();
        },
        changed : function(new_document, idx, old_document){
            var set = {};
            _.each(new_document, function (v, k) {
              if (!_.isEqual(v, old_document[k]))
                set[k] = v;
            });
            self.set('logsAndUsers', new_document._id, set);
            var dead_keys = _.difference(_.keys(old_document), _.keys(new_document));
            self.unset('logsAndUsers', new_document._id, dead_keys);
            self.flush();
        },
        moved : function(document, old_index, new_index){
            // Not used
        }
    });

    self.onStop(function(){
        handle.stop();
    });

    //  Deref on first Run
    var derefs = CC.Users.find({_id : {$in : uniqArr} }).fetch();
    _.forEach(startupList, function (item){
        _.forEach(derefs, function(ditems){
            if (item["user_id"].oid === ditems._id){
                item.user = ditems;
                return false;
            }
        });
        self.set('logsAndUsers', item._id, item);
    });
    delete derefs; // Not needed anymore

    startup = false;
    self.complete();
    self.flush();
});

对于每个添加的日志文档,它将搜索用户集合,并尝试将缺少的信息添加到日志集合中. 在第一次运行时,为日志集中的每个文档调用了添加的函数,我创建了一个startupList和一个唯一用户ID数组,因此对于第一次运行,它将仅查询数据库一次.最好使用分页机制来加快速度.

For each added logs document it'll search the users collection and try to add to the logs collection the missing information. The added function is called for each document in the logs collection in the first run I created a startupList and an array of unique users ids so for the first run it'll query the db only once. Its a good idea to put a paging mechanism to speed up things.

客户端

Client Side

如果要进行更改,请在客户端上订阅logsAndUsers集合.

On the client, subscribe to the logsAndUsers collection, if you want to make changes do it directly to the Logs collection.

LogsAndUsers = new Meteor.collection('logsAndUser');
Logs = new Meteor.colection('logs'); // Changes here are observed in the LogsAndUsers collection

Meteor.autosubscribe(function () {
    var page = Session.get('page') || 1;
    Meteor.subscribe('logsAndUsers', page);
});

这篇关于流星和DBRefs的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆