1

'tasks' 配列で、completed: true に一致する最初のサブドキュメントを見つけて返すにはどうすればよいですか?

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、最後のパイプライン ステージで演算子を使用して、 1 つのサブドキュメントのみを返すことができます。

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 に答える