流星:如何在文档中查找子文档(minimongo)
Meteor: how to find a subdocument within a document (minimongo)
短版
要在 collection 中查找文档,它是
collection.findOne([...], [...])
如何在文档中查找子文档?
长版
我有一个 collection 条目如下:
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 编写)
该条目在我的项目中 collection。它在服务器上发布:
server/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 条目并找到已 completed 的第一个 task:假.
经过几个小时的阅读,我认为我接近以下几点:
({
currentTask: function() {
return Projects.findOne({
_id: Session.get('selectedProject', {
'timeline.ideas.task.completed': false
})
}, {
fields: 'timeline.ideas.task'
});
}
});
我想 ^ 可能会尝试 return 一个项目而不是一项任务?
它 return 是这个错误:
Exception in template helper: Error: Match error: Failed Match.OneOf or Match.Optional validation
理论上应该是这样的
selectedProject.findOne(....)
我是否考虑在服务器上使用 $elemMatch?还是我漏掉了一些简单的东西?
请参阅 使用 聚合 的答案。
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
短版
要在 collection 中查找文档,它是
collection.findOne([...], [...])
如何在文档中查找子文档?
长版
我有一个 collection 条目如下:
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 编写)
该条目在我的项目中 collection。它在服务器上发布:
server/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 条目并找到已 completed 的第一个 task:假.
经过几个小时的阅读,我认为我接近以下几点:
({
currentTask: function() {
return Projects.findOne({
_id: Session.get('selectedProject', {
'timeline.ideas.task.completed': false
})
}, {
fields: 'timeline.ideas.task'
});
}
});
我想 ^ 可能会尝试 return 一个项目而不是一项任务?
它 return 是这个错误:
Exception in template helper: Error: Match error: Failed Match.OneOf or Match.Optional validation
理论上应该是这样的
selectedProject.findOne(....)
我是否考虑在服务器上使用 $elemMatch?还是我漏掉了一些简单的东西?
请参阅
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