例如:
1.使用find,测试每个集合:
var objIdMin = ObjectId(Math.floor((new Date('2016/05/01 00:00:00'))/1000).toString(16) + "0000000000000000");
var objIdMax = ObjectId(Math.floor((new Date('2016/05/11 00:00:00'))/1000).toString(16) + "0000000000000000");
db.getCollection('google').find({ _id:{$gt: objIdMin, $lt: objIdMax}, 'result.text':/phone/}).count();
google collection结果计数为50。
db.getCollection('apple').find({ _id:{$gt: objIdMin, $lt: objIdMax}, 'result.text':/phone/}).count();
苹果收集结果计数为100。
2.然后我转而实现我的目的:
var cols = db.getCollectionNames();
var objIdMin = ObjectId(Math.floor((new Date('2016/05/01 00:00:00'))/1000).toString(16) + "0000000000000000");
var objIdMax = ObjectId(Math.floor((new Date('2016/05/11 00:00:00'))/1000).toString(16) + "0000000000000000");
var cols_in = ['google', 'apple'];
for (var i=0; i<cols_in.length; i++){
db.getCollection(cols_in[i]).aggregate([ { $match: { _id:{$gt: objIdMin, $lt: objIdMax}, 'result.text':/phone/}}, { $out: "target" } ]);
};
target collection
的结果计数等于100(与apple collection
相同),所以后面的集合会覆盖前者,如何解决?
修改: 我发现这是由于:
替换现有收藏
如果$ out操作指定的集合已经存在,那么 完成聚合后,$ out阶段自动替换 具有新结果集合的现有集合。 $ out 操作不会更改先前存在的任何索引 采集。如果聚合失败,则$ out操作不会 更改预先存在的集合。
那么,唯一的方法是预先处理每条记录并插入另一个集合吗?
答案 0 :(得分:0)
根据评论 - &gt;在mongo中没有UNION ALL,它可以将来自许多查询的输出合并为一个逻辑块。
因此,使用for迭代集合的解决方案是一种非常好的方法,但是每次传递都会覆盖示例中名为 target 的输出集合
要在for
循环中解决此问题,请保存聚合&#39;输出&#39;作为数组,然后插入。
请看下颚:
for (var i = 0; i < cols_in.length; i++) {
var documents = db.getCollection(cols_in[i]).aggregate([{
$match : {
_id : {
$gt : objIdMin,
$lt : objIdMax
},
}
}
]).toArray();
db.target.insert(documents)
};