从数组中查找并返回第一个匹配的子文档(Meteor / Mongo)
Posted
技术标签:
【中文标题】从数组中查找并返回第一个匹配的子文档(Meteor / Mongo)【英文标题】:Find & return first matching subdocument from array (Meteor / Mongo) 【发布时间】:2015-05-23 17:30:46 【问题描述】:如何在“tasks”数组中找到并返回第一个匹配完成的子文档:true?
使用findOne
返回整个文档.. 是否有另一个函数用于返回子文档?
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()
]
]
【问题讨论】:
【参考方案1】: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
【讨论】:
【参考方案2】:您可以通过 aggregation 执行此操作,您可以在其中利用$match
管道的索引和限制。使用 $unwind
运算符将您的任务数组解构为可以匹配的文档流。由于您只想返回“'tasks' 数组中与已完成匹配的第一个子文档: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
【讨论】:
以上是关于从数组中查找并返回第一个匹配的子文档(Meteor / Mongo)的主要内容,如果未能解决你的问题,请参考以下文章
MongoDB通过***属性和嵌套数组键查找文档,并返回匹配文档的一部分
如何从 Mongo DB 中的子文档数组中删除匹配条件的子文档
Excel - 需要从数组中搜索列表单元格的子字符串,无法获得索引/匹配工作吗?