Meteor:如何在文档中查找子文档(minimongo)

时间:2015-03-19 19:09:28

标签: mongodb collections meteor subscribe minimongo

简短版

要在集合中查找文档,它是

collection.findOne([...], [...])

如何在文档中找到子文档?

长版

我有一个收集条目如下:

db.projects.find()

{
  title: 'company.com'
  company: 'A Company'
  companyID: Random.id()
  category: 'website'
  starred: false
  timeline: {
    ideas: {
      task: {
        name: 'task1'
        completed: true
        todos: [
          {todo: 'a todo', completed: false, todoID: Random.id()}
          {todo: 'a todo', completed: false, todoID: Random.id()}
          {todo: 'a todo', completed: false, todoID: Random.id()}
        ]
      }
      task: {
        name: 'task2'
        completed: false
        todos: [
          {todo: 'another todo', completed: false, todoID: Random.id()}
          {todo: 'another todo', completed: false, todoID: Random.id()}
          {todo: 'another todo', completed: false, todoID: Random.id()}
        ]
      }
    }
    development: {
    ...
    }
    production: {
    ...
    }
  }
}

(以coffeescript编写)

该条目位于我的Projects集合中。它发布在服务器上:

服务器/ publications.js

Meteor.publish('projects', function() {
  return Projects.find();
});

..并由客户订阅:

的客户机/ projects.js

Meteor.subscribe('projects');

简单。按预期工作。

接下来,我选择Session变量来存储项目:

Session.set('selectedProject', this.id); 

并在需要时调用它:

Session.get('selectedProject');

一切都很好。

现在,我想搜索selectedProject的 ideas 条目,找到已完成的第一个任务:false

经过几个小时的阅读后,我认为我接近以下内容:

 ({
   currentTask: function() {
     return Projects.findOne({
       _id: Session.get('selectedProject', {
         'timeline.ideas.task.completed': false
       })
     }, {
       fields: 'timeline.ideas.task'
     });
   }
 });

我猜^可能会尝试返回一个项目而不是一个任务?

它会返回此错误:

Exception in template helper: Error: Match error: Failed Match.OneOf or Match.Optional validation

理论上应该是

selectedProject.findOne(....)

我是否在服务器上使用$ elemMatch?还是我错过了一些简单的东西?

1 个答案:

答案 0 :(得分:1)

请参阅使用聚合this答案。

Meteor用户:在撰写本文时(版本1.0.4.1),不支持客户端上的聚合。

我想将代码保存在客户端上,并且还想要反应性,所以这是我的解决方案:

db.projects

// simplified structure

{
      title: 'awebsite.com'
      company: 'a company'
      companyID: Random.id()
      category: 'website'
      starred: false
      tasks: [
          {
            completed: true
            name: 'task1'
            category: 'ideas'
            todos: [
              {todo: 'something', completed: false, todoID: Random.id()}
              {todo: 'something', completed: false, todoID: Random.id()}
              {todo: 'something', completed: false, todoID: Random.id()}
            ]
          }
          {
            completed: false
            name: 'task2'
            category: 'ideas'
            todos: [
              {todo: 'something', completed: false, todoID: Random.id()}
              {todo: 'something', completed: false, todoID: Random.id()}
              {todo: 'something', completed: false, todoID: Random.id()}
            ]
          }
        ]
    }

../ projects.coffee

Meteor.subscribe 'projects'
Tasks = new (Mongo.Collection)(null)   //use (null) to create client-only collection

Template.projects.rendered = ->
  results = Projects.findOne { title: 'awebsite.com' },
    fields: tasks: 1

  _.each results.tasks, (task) ->
    Tasks.insert (task)

Template.projects.helpers
  currentTask: ->
    Tasks.findOne completed: false