MongoDB 3.0.7和Mongoose 4.3.4。
架构:
var schema = new mongoose.Schema({
confirmed: { type: Boolean, default: false },
moves: [new mongoose.Schema({
name: { type: String, default: '' },
live: { type: Boolean, default: true }
})]
});
mongoose.model('Batches', schema);
查询:
var Batch = mongoose.model('Batches');
var query = {
confirmed: true,
moves: {
$elemMatch: {
live: true
}
}
};
Batch.find(query).exec(function(err, batches){
console.log('batches: ', batches);
});
我需要返回confirmed
的所有批次,以及返回的批次live
内的所有移动。
目前,上面只返回confirmed
批次(这是我想要的),但全部每个返回批次中的moves
(不是我想要的是)。因此,live
标志的移动限制无效。
如何限制返回的子文档??
理想情况下,我希望将控制query
内返回的数据的所有内容传递给find
,而不必在Batch
上调用更多方法。
答案 0 :(得分:1)
对于支持MongoDB服务器>=4.3.0
的Mongoose版本3.2.x
,您可以将 $filter
运算符与聚合框架一起使用来限制/选择子集移动数组以根据指定的条件返回。这将返回一个只包含与条件匹配的元素的数组,因此您将在 $project
阶段使用它来根据上面的过滤器修改移动数组。
以下示例说明了如何解决此问题:
var Batch = mongoose.model('Batches'),
pipeline = [
{
"$match": { "confirmed": true, "moves.live": true }
},
{
"$project": {
"confirmed": 1,
"moves": {
"$filter": {
"input": "$moves",
"as": "el",
"cond": { "$eq": [ "$$el.live", true ] }
}
}
}
}
];
Batch.aggregate(pipeline).exec(function(err, batches){
console.log('batches: ', batches);
});
或使用流畅的 aggregate()
API管道构建器:
Batch.aggregate()
.match({
"$match": { "confirmed": true, "moves.live": true }
})
.project({
"confirmed": 1,
"moves": {
"$filter": {
"input": "$moves",
"as": "el",
"cond": { "$eq": [ "$$el.live", true ] }
}
}
})
.exec(function(err, batches){
console.log('batches: ', batches);
});
对于支持MongoDB服务器~3.8.8, ~3.8.22, 4.x
的Mongoose版本>=2.6.x
,您可以使用 $map
和 {的组合过滤掉错误值{3}} 运营商:
var Batch = mongoose.model('Batches'),
pipeline = [
{
"$match": { "confirmed": true, "moves.live": true }
},
{
"$project": {
"confirmed": 1,
"moves": {
"$setDifference": [
{
"$map": {
"input": "$moves",
"as": "el",
"in": {
"$cond": [
{ "$eq": [ "$$el.live", true ] },
"$$el",
false
]
}
}
},
[false]
]
}
}
}
];
Batch.aggregate(pipeline).exec(function(err, batches){
console.log('batches: ', batches);
});
答案 1 :(得分:0)
您可以使用聚合框架的$unwind
方法将它们拆分为单独的文档,这里是示例代码。
Batches.aggregate(
{ $match: {'confirmed': true, 'moves.live': true}},
{$unwind: '$moves'},
{$project: {
confirmed: 1
name: '$moves.name',
live:'$moves.live'
}
}, function(err, ret){
})
答案 2 :(得分:0)
查询不限制活动标志的移动。该查询显示:查找至少有一次实时移动的所有已确认批次。
只有2个选项可以检索实时移动:检索所有移动,filter数组客户端;或map-reduce服务器端 - 展开所有移动,过滤实时移动,按文档ID分组。
前者更容易实现,但会导致客户端更多的数据传输,CPU和内存消耗。后者更有效,但实现起来要复杂一些 - 如果您希望响应中超过16Mb,则需要使用临时集合。