mongodb查询来自多个集合的结果并保存为一个

时间:2016-05-12 01:41:46

标签: mongodb mongodb-query aggregation-framework

例如:

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操作不会   更改预先存在的集合。

那么,唯一的方法是预先处理每条记录并插入另一个集合吗?

1 个答案:

答案 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)
};