1

短版

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

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: {
    ...
    }
  }
}

(用咖啡脚本写的)

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

服务器/publications.js

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

..并由客户订阅:

客户端/projects.js

Meteor.subscribe('projects');

简单的。按预期工作。

接下来,我使用 Session 变量在项目被选中时存储它:

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

并在需要时调用它:

Session.get('selectedProject');

一切都好。

现在我想搜索 selectedProject 的想法条目并找到第一个已完成的任务: 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 吗?还是我错过了一些简单的东西?

4

1 回答 1

1

请参阅使用聚合的这个答案。

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

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

数据库项目

// 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
于 2015-03-20T13:50:57.687 回答