Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mongodb Meteor发布集合中字段的不同值_Mongodb_Meteor - Fatal编程技术网

Mongodb Meteor发布集合中字段的不同值

Mongodb Meteor发布集合中字段的不同值,mongodb,meteor,Mongodb,Meteor,我被困在《流星》中一个非常简单的场景中: 我有一个包含许多字段的庞大集合,其中一些包含相当多的文本 我想创建一个搜索该集合的页面 集合中每个项目的字段之一是“类别” 我想让用户能够按类别进行筛选 为此,我需要只发布集合中category字段的不同值 我想不出一个方法来做到这一点,而不公布整个收藏,这需要花费太长的时间。我如何只发布不同的类别,并使用它们填充下拉列表 额外的问题和一些相关的问题:如何在不发布整个集合的情况下发布集合中所有项目的计数?这些模式可能会对您有所帮助。以下是发布计数的出

我被困在《流星》中一个非常简单的场景中:

  • 我有一个包含许多字段的庞大集合,其中一些包含相当多的文本

  • 我想创建一个搜索该集合的页面

  • 集合中每个项目的字段之一是“类别”

  • 我想让用户能够按类别进行筛选

  • 为此,我需要只发布集合中category字段的不同值

我想不出一个方法来做到这一点,而不公布整个收藏,这需要花费太长的时间。我如何只发布不同的类别,并使用它们填充下拉列表


额外的问题和一些相关的问题:如何在不发布整个集合的情况下发布集合中所有项目的计数?

这些模式可能会对您有所帮助。以下是发布计数的出版物:

/*****************************************************************************/
/* Counts Publish Function
/*****************************************************************************/

// server: publish the current size of a collection
Meteor.publish("countsByProject", function (arguments) {
  var self = this;

    if (this.userId) {
        var roles = Meteor.users.findOne({_id : this.userId}).roles;
        if ( _.contains(roles, arguments.projectId) ) {

              //check(arguments.video_id, Integer);



              // 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.

              Videos.find({'projectId': arguments.projectId}).forEach(function (video) {
                  var count = 0;
                  var initializing = true;
                  var video_id = video.video_id;
                  var handle = Observations.find({video_id: video_id}).observeChanges({
                    added: function (id) {
                      //console.log(video._id);
                      count++;
                      if (!initializing)
                        self.changed("counts", video_id, {'video_id': video_id, 'observations': count});
                    },
                    removed: function (id) {
                      count--;
                      self.changed("counts", video_id, {'video_id': video_id, 'observations': count});
                    }
                    // don't care about changed
                  });



                  // Instead, we'll send one `self.added()` message right after
                  // observeChanges has returned, and mark the subscription as
                  // ready.
                  initializing = false;
                  self.added("counts", video_id, {'video_id': video_id, 'observations': count});
                  self.ready();

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


              }); // Videos forEach


        } //if _.contains
    } // if userId

  return this.ready();  

});
下面是一个从特定字段创建新集合的集合:

/*****************************************************************************/
/* Tags Publish Functions
/*****************************************************************************/

// server: publish the current size of a collection
Meteor.publish("tags", function (arguments) {
  var self = this;

    if (this.userId) {
        var roles = Meteor.users.findOne({_id : this.userId}).roles;
        if ( _.contains(roles, arguments.projectId) ) {

                var observations, tags, initializing, projectId;
                initializing = true;
                projectId = arguments.projectId;
                observations = Observations.find({'projectId' : projectId}, {fields: {tags: 1}}).fetch();
                tags = _.pluck(observations, 'tags');
                tags = _.flatten(tags);
                tags = _.uniq(tags);

                var handle = Observations.find({'projectId': projectId}, {fields : {'tags' : 1}}).observeChanges({
                    added: function (id, fields) {
                      if (!initializing) {
                        tags = _.union(tags, fields.tags);
                        self.changed("tags", projectId, {'projectId': projectId, 'tags': tags});
                      }
                    },
                    removed: function (id) {
                      self.changed("tags", projectId, {'projectId': projectId, 'tags': tags});
                    }
                });

                initializing = false;
                self.added("tags", projectId,  {'projectId': projectId, 'tags': tags});
                self.ready();

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

        } //if _.contains
    } // if userId

  return self.ready();  

});

这些模式可能对您有所帮助。以下是发布计数的出版物:

/*****************************************************************************/
/* Counts Publish Function
/*****************************************************************************/

// server: publish the current size of a collection
Meteor.publish("countsByProject", function (arguments) {
  var self = this;

    if (this.userId) {
        var roles = Meteor.users.findOne({_id : this.userId}).roles;
        if ( _.contains(roles, arguments.projectId) ) {

              //check(arguments.video_id, Integer);



              // 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.

              Videos.find({'projectId': arguments.projectId}).forEach(function (video) {
                  var count = 0;
                  var initializing = true;
                  var video_id = video.video_id;
                  var handle = Observations.find({video_id: video_id}).observeChanges({
                    added: function (id) {
                      //console.log(video._id);
                      count++;
                      if (!initializing)
                        self.changed("counts", video_id, {'video_id': video_id, 'observations': count});
                    },
                    removed: function (id) {
                      count--;
                      self.changed("counts", video_id, {'video_id': video_id, 'observations': count});
                    }
                    // don't care about changed
                  });



                  // Instead, we'll send one `self.added()` message right after
                  // observeChanges has returned, and mark the subscription as
                  // ready.
                  initializing = false;
                  self.added("counts", video_id, {'video_id': video_id, 'observations': count});
                  self.ready();

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


              }); // Videos forEach


        } //if _.contains
    } // if userId

  return this.ready();  

});
下面是一个从特定字段创建新集合的集合:

/*****************************************************************************/
/* Tags Publish Functions
/*****************************************************************************/

// server: publish the current size of a collection
Meteor.publish("tags", function (arguments) {
  var self = this;

    if (this.userId) {
        var roles = Meteor.users.findOne({_id : this.userId}).roles;
        if ( _.contains(roles, arguments.projectId) ) {

                var observations, tags, initializing, projectId;
                initializing = true;
                projectId = arguments.projectId;
                observations = Observations.find({'projectId' : projectId}, {fields: {tags: 1}}).fetch();
                tags = _.pluck(observations, 'tags');
                tags = _.flatten(tags);
                tags = _.uniq(tags);

                var handle = Observations.find({'projectId': projectId}, {fields : {'tags' : 1}}).observeChanges({
                    added: function (id, fields) {
                      if (!initializing) {
                        tags = _.union(tags, fields.tags);
                        self.changed("tags", projectId, {'projectId': projectId, 'tags': tags});
                      }
                    },
                    removed: function (id) {
                      self.changed("tags", projectId, {'projectId': projectId, 'tags': tags});
                    }
                });

                initializing = false;
                self.added("tags", projectId,  {'projectId': projectId, 'tags': tags});
                self.ready();

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

        } //if _.contains
    } // if userId

  return self.ready();  

});

一个很好的起点是将
类别规范化为一个单独的数据库集合

但是,假设这不可能或不实用,最好(尽管不完美)的解决方案是发布集合的两个单独版本,一个只返回整个集合的
类别
字段,另一个只返回选定类别集合的所有字段。这将如下所示:

// SERVER
Meteor.startup(function(){

  Meteor.publish('allThings', function() {

    // return only id and categories field for all your things 
    return Things.find({}, {fields: {categories: 1}});

  });

  Meteor.publish('thingsByCategory', function(category) {

    // return all fields for things having the selected category
    // you can then subscribe via something like a client-side Session variable
    // e.g., Meteor.subscribe("thingsByCategory", Session.get("category"));

    return Things.find({category: category});
  });
});
请注意,您仍然需要从Things游标组装类别数组客户端(例如,通过使用下划线的u.pull和u.uniq方法获取类别并删除任何DUP)。但是数据集会小得多,因为您现在只处理单字段文档


(请注意,理想情况下,您希望在publish函数中使用Mongo的distinct()方法仅发布不同的类别,但这不可能直接发布,因为它会返回无法发布的数组)

但是,假设这不可能或不实用,最好(尽管不完美)的解决方案是发布集合的两个单独版本,一个只返回整个集合的
类别
字段,另一个只返回选定类别集合的所有字段。这将如下所示:

// SERVER
Meteor.startup(function(){

  Meteor.publish('allThings', function() {

    // return only id and categories field for all your things 
    return Things.find({}, {fields: {categories: 1}});

  });

  Meteor.publish('thingsByCategory', function(category) {

    // return all fields for things having the selected category
    // you can then subscribe via something like a client-side Session variable
    // e.g., Meteor.subscribe("thingsByCategory", Session.get("category"));

    return Things.find({category: category});
  });
});
请注意,您仍然需要从Things游标组装类别数组客户端(例如,通过使用下划线的u.pull和u.uniq方法获取类别并删除任何DUP)。但是数据集会小得多,因为您现在只处理单字段文档


(请注意,理想情况下,您希望在publish函数中使用Mongo的distinct()方法仅发布不同的类别,但这是不可能的,因为它会返回一个无法发布的数组)。

您可以使用内部
this.\u documents.collectionName
只向客户端发送新类别。跟踪要删除的类别变得有点难看,因此最终您可能仍然会维护一个单独的“类别”集合

例如:

Meteor.publish( 'categories', function(){
  var self = this;
  largeCollection.find({},{fields: {category: 1}).observeChanges({
    added: function( id, doc ){
      if( ! self._documents.categories[ doc.category ] ) 
        self.added( 'categories', doc.category, {category: doc.category});         
    },
    removed: function(){
      _.keys( self._documents.categories ).forEach( category ){
        if ( largeCollection.find({category: category},{limit: 1}).count() === 0 )
          self.removed( 'categories', category );
      }
    }
  });

  self.ready();    
};

您可以使用内部
this.\u documents.collectionName
只向客户端发送新类别。跟踪要删除的类别变得有点难看,因此最终您可能仍然会维护一个单独的“类别”集合

例如:

Meteor.publish( 'categories', function(){
  var self = this;
  largeCollection.find({},{fields: {category: 1}).observeChanges({
    added: function( id, doc ){
      if( ! self._documents.categories[ doc.category ] ) 
        self.added( 'categories', doc.category, {category: doc.category});         
    },
    removed: function(){
      _.keys( self._documents.categories ).forEach( category ){
        if ( largeCollection.find({category: category},{limit: 1}).count() === 0 )
          self.removed( 'categories', category );
      }
    }
  });

  self.ready();    
};

回复:奖励问题,发布计数:看看陨石包发布计数。我想这正是你想要的。

Re:奖金问题,出版计数:看看陨石包的出版计数。我想这正是你想要的。

我还没有在Meteor上测试过它,根据回复,我对它是否有效表示怀疑,但使用mongoDB distinct就可以了


我还没有在Meteor上测试过它,根据回复,我怀疑它是否有效,但使用mongoDB distinct就可以了


谢谢,但这似乎很复杂。我不确定所有的userId/角色都和我的问题有什么关系。谢谢,但这看起来很复杂。不确定所有的userId/角色与我的问题有什么关系。没有真正解决问题的具体问题。如何在不公布整个收藏的情况下做到这一点?并没有真正解决问题的具体问题。如何在不发布整个收藏的情况下做到这一点?你不能像在Meteor中那样使用mongo distinct。Mongo驱动程序不支持它。有一些软件包添加了这一功能,但我相信它们只是在获取的数组上使用
\uuq.uniq
技巧。我不相信目前有一个好的方法可以得到清晰的反应结果。你不能像在Meteor中那样使用mongo distinct。Mongo驱动程序不支持它。有一些软件包添加了这一功能,但我相信它们只是在获取的数组上使用
\uuq.uniq
技巧。我不相信目前有一种好的方法可以得到明显的反应性结果。