mongodb实现exists去重

【字号: 日期:2023-06-26浏览:11作者:雯心

问题描述

db.getCollection(’user’).save({'uid':'1123', 'logTime':ISODate(’2016-05-23 11:11:23’)});db.getCollection(’user’).save({'uid':'1124', 'logTime':ISODate(’2016-05-23 05:11:23’)});db.getCollection(’user’).save({'uid':'1125', 'logTime':ISODate(’2016-05-23 08:11:23’)});db.getCollection(’user’).save({'uid':'1126', 'logTime':ISODate(’2016-05-23 09:12:23’)});db.getCollection(’user’).save({'uid':'1127', 'logTime':ISODate(’2016-05-23 11:23:23’)});db.getCollection(’user’).save({'uid':'1134', 'logTime':ISODate(’2016-05-23 11:11:23’)});db.getCollection(’user’).save({'uid':'1123', 'logTime':ISODate(’2016-05-21 11:11:23’)});db.getCollection(’user’).save({'uid':'1125', 'logTime':ISODate(’2016-05-22 11:11:23’)});db.getCollection(’user’).save({'uid':'2343', 'logTime':ISODate(’2016-04-23 11:11:23’)});db.getCollection(’user’).save({'uid':'9873', 'logTime':ISODate(’2016-04-23 11:11:23’)});db.getCollection(’user’).save({'uid':'4321', 'logTime':ISODate(’2016-04-20 11:11:23’)});

上面模拟一些数据 生产一个user集合来表示用户登录状况. 现在我想查询2016-05-23的新用户数(5-23号登录的用户但是在小于5-23号的记录中不存在) 比如第一条记录uid=’1123’在5-21也登录过 那么uid=’1123’就不算在5-23登录的用户数中

问题解答

回答1:

mongodb不支持支持join,下面这种方式可以达到你的目的

var list = [];db.getCollection(’user’).find({’logTime’: {’$lt’: ISODate(’2016-05-23’)}}, {’_id’: 0, ’uid’: 1}).forEach(function(item){ list.push(item[’uid’]);});db.getCollection(’user’).find({’logTime’: {’$gte’: ISODate(’2016-05-23’)}, ’uid’: {’$nin’: list}});回答2:

5-23号登录的用户但是在小于5-23号的记录中不存在

首先这种设计是有明显的缺陷的。

性能缺陷:小于23号的记录多了去了,1年、2年、10年前都算小于5月23号,你要往前扫多久?刚开始只有几天的数据可能还好,慢慢随着日志增多,你的程序就会跑得越来越吃力。而且这个过程会进行得很快。这时候你就会想到删除老日志,于是出现下面的问题。

不易维护:登录日志这种东西,量大而且对一般人来说又没太大用处,很少有人永久保存。可想而知当你删除一年前的日志后,一批不新的新用户就诞生了,因为他们首次登录的日志可能被你删掉了。

另外一般所指的新用户不就是新注册的用户吗,哪天注册算哪天,有什么特殊的理由一定要用这种算法来查找新用户?如果一定要把第一次登录这天算作新用户时间,那建议重新设计。比如以用户表为基础,找出还没登录过的用户,然后定期查找他们的登录日志,一旦找到则把首次登录日期记录到用户表中。这样理论上不管过多久,注册过但是没有登录过的用户的量不会有太大变化(并不是不会有变化,确实存在注册过但是从来不登录的用户,但是毕竟少),你的程序就不会随着时间推移性能变得很差。

并没有直接回答你的问题,因为我一惯的经验告诉我要从根本上解决问题,不要在一个错误基础上打补丁,只会把情况变得越来越糟。

PS:你的最后一句话逻辑是不是有问题?

相关文章: