这个功能真的是写死我了,对于MongoDB一点都不熟悉,本来想使用spring与MongoDB的融合mongoDBTemplate,发现压根不是web项目,懒得配置那些配置文件,就使用最原始的数据库操作,事实证明,是真的很费劲,根本不知道那些操作嘛意思。庆幸的是,姐姐写出来了。

需求

现有MongoDB数据库,数据格式如下

  

  data是一数组,查询每条记录中data中存在的重复数据,并删除重复,保留第一条记录

思路

  根据字段 r ,以及 data 中的 t ,查出重复的数据,再根据重复数据查出完整记录,然后删除重复

ps : 思路是有的,执行是困难的

代码

1. 连接MongoDB数据库,一般可以配置到spring中,我这里使用原始的连接

  

@SuppressWarnings({"unchecked", "rawtypes" })
public static void main(String args[]){
logger.info(String.format("------------------开始处理重复数据,开始时间%s----------------------", new Date()));
// 当年年初
Date date = new Date();
date = DateUtils.truncate(date, Calendar.YEAR); // 连接到 mongodb 服务,官方文档和源代码均建议使用MongoClient类,而且,在不久的将来,会废弃Mongo类
MongoClient mongoClient = new MongoClient( "127.0.0.1" , 27017 ); // 连接数据库,你需要指定数据库名称,如果指定的数据库不存在,mongo会自动创建数据库(未测试是否创建,网查可以创建)
MongoDatabase database = mongoClient.getDatabase("test"); //连接到collection
MongoCollection coll = database.getCollection("test_data"); List<Document> list = new ArrayList<Document>();
//固定时间区间,从年初到现在
Document matchDoc = new Document("t",new Document("$gte", date).append("$lte", new Date())); // 过滤 $match:用于过滤数据,只输出符合条件的文档
Document match = new Document("$match",matchDoc);
//$unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值
//拆开data数组
Document unwind = new Document("$unwind","$data"); // 依据字段 r 与 data中的 t 进行分组,并计算条数
Document groupD = new Document("_id",new Document("r","$r").append("t", "$data.t"))
.append("count", new Document("$sum", 1));
Document group = new Document("$group", groupD); // $project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
// 重新定义输出的字段
Document project = new Document("$project",new Document("r","$_id.r").append("t", "$_id.t").append("num", "$count")); // 查询条数大于1的数据
Document match2 = new Document("$match",new Document("num",new Document("$gt",1))); list.add(match);
list.add(unwind);
list.add(group);
list.add(project);
list.add(match2); //Mongodb规定了aggregate管道聚合的返回数据不能超过16M,超过16M就会报异常错误,需要设置allowDiskUse:true,即允许使用磁盘缓存
AggregateIterable<Document> doc = coll.aggregate(list,Document.class).allowDiskUse(true); //也可以使用for循环
doc.forEach(new Block<Document>() { @Override
public void apply(Document t) {
// TODO Auto-generated method stub
logger.info(String.format("重复数据,详情:%s", t));
//处理重复数据
handleSingleDocument(coll,t);
logger.info("---------------------分割线-----------------");
} }); // 一定要记得关闭连接
mongoClient.close();
mongoClient = null;
logger.info(String.format("------------------处理重复数据结束,结束时间%s----------------------", new Date()));
}

  

handleSingleDocument
@SuppressWarnings({ "unchecked", "rawtypes" })
private static void handleSingleDocument(MongoCollection coll,Document t){ //根据重复的条件 r 与 data.t 查询具体的重复数据
Document unwind = new Document("$unwind","$data");
Document match = new Document("$match",new Document("r",t.getInteger("r"))
.append("data.t",t.getDate("t"))); List<Document> list = new ArrayList<Document>();
list.add(unwind);
list.add(match);
AggregateIterable<Document> doc = coll.aggregate(list,Document.class).allowDiskUse(true); int i = 0;
for(Document dd :doc){
//用了最笨的方法,过滤到第一条数据
if(i==0){
i++;
continue;
}
logger.info(String.format("删除数据:%s", dd));
Document ment = (Document) dd.get("data"); Document subMatch = new Document("r",t.getInteger("r"))
.append("t", DateUtils.truncate(t.getDate("t"), Calendar.DAY_OF_MONTH)); // updateOne方法,第一个参数是查询符合条件数据,第二个参数是需要做的操作
// $pull修饰符会删除掉数组中符合条件的元素
coll.updateOne(subMatch, new Document("$pull",new Document("data",ment))); }

至此结束,写完觉得还是使用自己不知道的东西有成就感,再接再厉

MongoDB实现数组中重复数据删除的更多相关文章

  1. 关于iOS去除数组中重复数据的几种方法

    关于iOS去除数组中重复数据的几种方法   在工作工程中我们不必要会遇到,在数组中有重复数据的时候,如何去除重复的数据呢? 第一种:利用NSDictionary的AllKeys(AllValues)方 ...

  2. php去除数组中重复数据

    <?php /** * 去除数组中重复数据 * by www.jbxue.com **/ $input = array("a" => "green" ...

  3. php获取数组中重复数据的两种方法

    分享下php获取数组中重复数据的两种方法. 1,利用php提供的函数,array_unique和array_diff_assoc来实现 <?php function FetchRepeatMem ...

  4. PHP去除数组中重复数据的两个例子

    例一: <?php$input = array("a" => "green","", "red"," ...

  5. iOS - 去除数组中重复数据的几种方法

    第一种:利用NSDictionary的AllKeys(AllValues)方法 代码: NSArray *dataArray = @[@"2018-02-01",@"20 ...

  6. jst通用删除数组中重复的值和删除字符串中重复的字符

    以下内容属于个人原创,转载请注明出处,非常感谢! 删除数组中重复的值或者删除字符串重复的字符,是我们前端开发人员碰到很多这样的场景.还有求职者在被面试时也会碰到这样的问题!比如:问删除字符串重复的字符 ...

  7. 查询和删除表中重复数据sql语句

      1.查询表中重复数据.select * from peoplewhere peopleId in (select   peopleId   from   people   group   by   ...

  8. Leetcode#442. Find All Duplicates in an nums(数组中重复的数据)

    题目描述 给定一个整数数组 a,其中1 ≤ a[i] ≤ n (n为数组长度), 其中有些元素出现两次而其他元素出现一次. 找到所有出现两次的元素. 你可以不用到任何额外空间并在O(n)时间复杂度内解 ...

  9. ROWID面试题-删除表中重复数据(重复数据保留一个)

    /* ROWID是行ID,通过它一定可以定位到r任意一行的数据记录 ROWID DNAME DEPTNO LOC ------------------ ------------------------ ...

随机推荐

  1. C# 不卡屏延时方法,延迟系统时间,但系统又能同时能执行其它任务

    //延迟系统时间,但系统又能同时能执行其它任务,不卡屏延时方法 public static void Delay(int milliSecond) { int start = Environment. ...

  2. 【sqli-labs】 less10 GET - Blind - Time based. - Double quotes (基于时间的双引号盲注)

    这个和less9一样,单引号改完双引号就行了 http://localhost/sqli/Less-10/?id=1" and sleep(5)%23 5s后页面完成刷新 http://lo ...

  3. git_安装与配置

    安装 windows平台安装 在windows平台安装git,需要下载exe.文件,下载地址:https://gitforwindows.org/,双击下载的.exe文件,按照提示进行安装,安装完成后 ...

  4. Java基础学习笔记之:System类;Math类;Arrays类BigInteger,BigDecimal

    System类 在API中System类介绍的比较简单,我们给出定义,System中代表程序所在系统,提供了对应的一些系统属性信息,和系统操作.System类不能手动创建对象,因为构造方法被priva ...

  5. day36 类的三大特性---封装以及Property特性

    目录 类的封装 如果真的要拿 类的property特性 setter & deleter 类属性用法 类与对象的绑定方法和非绑定方法 对象方法&类方法&静态方法 隐藏模块内的函 ...

  6. 从读写分离到 CQRS,张大胖是如何解决性能问题的?

    转自:https://mp.weixin.qq.com/s/rpiYZkxiLKa77OFw8XaBwA 不堪重负的数据库 张大胖公司的数据库已经不堪重负了. 这个系统最早是两个实习生写的, 按照最初 ...

  7. C++ 资源大全中文版

    标准库 C++标准库,包括了STL容器,算法和函数等. C++ Standard Library:是一系列类和函数的集合,使用核心语言编写,也是C++ISO自身标准的一部分. Standard Tem ...

  8. centos7关闭防火墙以及查看防火墙状态

    1.关闭firewall:systemctl stop firewalld.service #停止firewall systemctl disable firewalld.service #禁止fir ...

  9. jenkins+svn+tomcat部署war包

    svn是版本控制器,是提供一个版本库让程序员把项目提交上去,每一次更新代码提交后都会记录 jenkins是持续部署的工具,是让项目自动部署发布出去的工具,当项目代码发生改变时就需要重新打包成war包, ...

  10. linux邮件服务

    linux本地常见邮件服务有: Centos5:默认使用sendmail邮件服务,开启方式/etc/init.d/sedmail start Centos6:默认使用postfix邮件服务,开启方式/ ...