mongoDB踩坑:aggregate + group + sort

最近使用mongo时遇到一个问题,场景是:使用聚合 aggregate 函数,分页查找一张日志表。

一. 初始

查找规则是按照创建时间字段降序,并按照其中一个字段分组,然后通过skip、limit,实现分页的效果。

示例sql如下:

db.collection1
    .aggregate([ 
        { "$match" : { "filed1" : "value1"}}, 
        { "$sort" : { "createTime" : -1}},
        { "$group" : { "_id" : "$field2"}},
        { "$skip" : 0},
        { "$limit" : 20}
    ]
);

结果发现有以下几个问题:

1.实际查找的顺序并不是从(整表)后向前,而是从前向后。即顺序和指定的createTime顺序相反;

2.返回的每页数据实际存在乱序和丢失的情况。即返回的一页 field2 并不是准确的这一页数据包含的field2,顺序也不对。

二. 第一次修改

怀疑是先sort再group会打乱顺序,于是将sort放在group之后执行。

示例:

db.collection1
    .aggregate([ 
        { "$match" : { "filed1" : "value1"}}, 
        { "$group" : { "_id" : "$field2"}},
        { "$sort" : { "createTime" : -1}},
        { "$skip" : 0},
        { "$limit" : 20}
    ]
);

结果发现返回的顺序仍是乱掉的。

通过查看返回结果,发现实际只返回了分组的field2这一列属性,不包含排序的createTime字段,所以猜测排序实际没有意义。

三. 第二次修改:

分组时,返回每组第一条数据的createTime。

示例:

db.collection1
    .aggregate([ 
        { "$match" : { "filed1" : "value1"}}, 
        { "$group" : { "_id" : "$field2", "createTime":{$first:"$createTime"}}},
        { "$sort" : { "createTime" : -1}},
        { "$skip" : 0},
        { "$limit" : 20}
    ]
);

然后再获取结果,果然符合预期了。

PS:

1.mongodb的资料很少,自己只能去官网看,而且一些使用细节也没有详细说明;

2.mongo 的 group 和 mysql 的 group 不一样,mysql 会返回select 指定的字段,且默认取第一条(一般按照主键id升序);mongo 聚合中使用group的话,默认只会返回 “_id” 对应的字段,其余字段需要显示设置获取规则,才会返回。

建议:

日志类数据还是老老实实用ES存吧,mongo并不适合

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值