这是我的文档:
var docIHave = {
_id: "someId",
things: [
{
name: "thing1",
stuff: [1,2,3,4,5,6,7,8,9]
},
{
name: "thing2",
stuff: [4,5,6,7,8,9,10,11,12,13,14]
},
{
name: "thing3",
stuff: [1,4,6,8,11,21,23,30]
}
]
}
这是我想要的文件:
var docIWant = {
_id: "someId",
things: [
{
name: "thing1",
stuff: [5,6,7,8,9]
},
{
name: "thing2",
stuff: [5,6,7,8,9,10,11]
},
{
name: "thing3",
stuff: [6,8,11]
}
]
}
docIWant的东西应该只包含大于min = 4的项目 小于max = 12。
背景: 我有一个流星应用程序,我订阅了一个给我docIHave的集合。根据参数min和max,我需要docisWant“动态”。不应修改原始文档。我需要一个查询或程序,它将docIWant返回给东西。
非常感谢实用的代码示例。
答案 0 :(得分:2)
使用 aggregation framework 。在聚合管道中,将$match
运算符视为您的第一个管道阶段。这对于优化聚合非常必要,因为您需要首先过滤与给定条件匹配的文档,然后再将其传递到管道上。
接下来使用$unwind
运算符。这将从输入文档中解构things
数组字段,以输出每个元素的文档。每个输出文档都是输入文档,其中数组字段的值由元素替换。
things.stuff
数组也需要进行另一次$unwind
操作。
然后,下一个管道阶段将过滤掉解构things.stuff
与给定的最小和最大标准匹配的掺杂。请使用$match
运算符。
然后,需要$group
运算符按指定的标识符表达式对输入文档进行分组,并将累加器表达式$push
应用于每个组。这会为每个组创建一个数组表达式。
通常你的聚合应该像这样结束(虽然我还没有真正测试过它,但这应该让你朝着正确的方向前进):
db.collection.aggregate([
{
"$match": {
"things.stuff": { "$gt": 4, "$lte": 11 }
}
},
{
"$unwind": "$things"
},
{
"$unwind": "$things.stuff"
},
{
"$match": {
"things.stuff": { "$gt": 4, "$lte": 11 }
}
},
{
"$group": {
"_id": {
"_id": "$_id",
"things": "$things"
},
"stuff": {
"$push": "$things.stuff"
}
}
},
{
"$group": {
"_id": "$_id._id",
"things": {
"$push": {
"name": "$_id.things.name",
"stuff": "$stuff"
}
}
}
}
])
答案 1 :(得分:2)
如果您需要在客户端上转换文档以进行显示,您可以执行以下操作:
Template.myTemplate.helpers({
transformedDoc: function() {
// get the bounds - maybe these are stored in session vars
var min = Session.get('min');
var max = Session.get('max');
// fetch the doc somehow that needs to be transformed
var doc = SomeCollection.findOne();
// transform the thing.stuff arrays
_.each(doc.things, function(thing) {
thing.stuff = _.reject(thing.stuff, function(n) {
return (n < min) || (n > max);
});
});
// return the transformed doc
return doc;
}
});
然后在您的模板中:{{#each transformedDoc.things}}...{{/each}}
答案 2 :(得分:1)
使用mongo aggregation如下:
首先使用$unwind这将取消stuff
,然后使用$match查找大于4
的元素。在基于things.name
的{{3}}数据之后,在$project
中添加必填字段。
查询如下:
db.collection.aggregate([
{
$unwind: "$things"
}, {
$unwind: "$things.stuff"
}, {
$match: {
"things.stuff": {
$gt: 4,
$lt:12
}
}
}, {
$group: {
"_id": "$things.name",
"stuff": {
$push: "$things.stuff"
}
}
}, {
$project: {
"thingName": "$_id",
"stuff": 1
}
}])