【问题标题】:Meteor: how to find a subdocument within a document (minimongo)Meteor:如何在文档中查找子文档(minimongo)
【发布时间】:2015-05-23 01:34:46
【问题描述】:

简短版

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

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

.. 并被客户订阅:

client/projects.js

Meteor.subscribe('projects');

简单。按预期工作。

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

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

并在需要时调用它:

Session.get('selectedProject');

一切都好。

现在我要搜索 selectedProject 的 ideas 条目,并找到第一个 task completed: 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?还是我错过了一些简单的东西?

【问题讨论】:

    标签: mongodb collections meteor subscribe minimongo


    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-04
      • 2017-03-14
      • 2022-10-01
      • 1970-01-01
      • 2021-07-25
      • 2016-08-25
      相关资源
      最近更新 更多