Meteor 和 DBRefs [英] Meteor and DBRefs

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

问题描述

我在 Win7(32) 中使用 Meteor 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();
});

对于每个添加的日志文档,它会搜索用户集合并尝试将丢失的信息添加到日志集合中.在第一次运行时,为日志集合中的每个文档调用了添加的函数,我创建了一个启动列表和一个唯一用户 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.

客户端

在客户端,订阅 logsAndUsers 集合,如果您想直接对 Logs 集合进行更改.

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);
});

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

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