1

如何在“任务”数组中找到并返回与完成匹配的第一个子文档:真?

usingfindOne返回整个文档.. 是否有返回子文档的另一个函数?

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

2 回答 2

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:46:43.153 回答
0

您可以通过聚合来做到这一点,您可以在其中利用$match管道的索引和限制。使用$unwind运算符将​​您的任务数组解构为可以匹配的文档流。由于您只想返回“ 'tasks' 数组中与 completed: true 匹配的第一个子文档”,因此您可以$limit在最后一个管道阶段使用运算符仅返回一个子文档:

db.collection.aggregate([
  { 
      $match: {
          "timeline.tasks.completed": true
      }
  },
  { 
      $unwind: "$timeline.tasks" 
  },
  { 
      $match: {
          "timeline.tasks.completed": true
      }
  },
  { 
      $group: {
           _id: {
                "tasks": "$timeline.tasks"
           }
      }
  },
  {
      $project: {
          _id: 0,
          tasks: "$_id.tasks"
      }
  },
  {
      $limit: 1
  }
])

结果是:

{
    "result" : [ 
        {
            "tasks" : {
                "name" : "task1",
                "completed" : true,
                "todos" : [ 
                    {
                        "todo" : "something",
                        "completed" : false,
                        "todoID" : "jfoe84jn"
                    }, 
                    {
                        "todo" : "something",
                        "completed" : false,
                        "todoID" : "yr934hjs"
                    }, 
                    {
                        "todo" : "something",
                        "completed" : false,
                        "todoID" : "84hdkl0t"
                    }
                ]
            }
        }
    ],
    "ok" : 1
}
于 2015-03-20T10:47:13.590 回答