🎈在业务场景中遇到这样一个问题,根据某个字段进行条件查询出来的记录总数与后端 MongoDB 数据库中记录总数出现不一致的情形,经过分析之后发现是因为数据库中某个唯一字段的值重现重复的情况,导致了有多条重复的记录存在。
🎈因此,解决方法就是先筛选出指定字段有重复值的记录,再进行删除操作。因为使用的是 MongoDB 数据库,因此需要用到 MongoDB 相关的执行命令,这与 MySQL 中相关操作语句有较大差别,针对本问题的解决方法的执行命令如下:
db.getCollection('host').aggregate([{$group: { _id : '$host_id', count: {$sum: 1}}}, {$match: {count: {$gt: 1}}}], {allowDiskUse: true})
🎈上面的执行命令其实是 MongoDB 的聚合查询(聚合管道)语句,其中, $ group:{_id: ‘$ host_id’, count: {$ sum: 1}} 中的 “host_id” 便是需要进行筛选的字段(根据情况替换成自己要筛选的字段),而 count: {$ sum: 1} 表示按照 group 的条件, 满足一条就计数就加 1,也就是 count 是 group 中 每个 host_id 的出现的次数。
🎈而 $ match: {count: {$gt: 1}}} 表示匹配 count 值大于 1 的记录,也就是 host_id 字段值出现两次以上的记录。gt 的全城是 greater than,因此 $ gt:1 便表示大于1的意思。关于 MongoDB 中常用的比较运算符如下表所示:
简称 | 全称 |
$gt | greater than |
$gte | greater than or equal |
$lt | less than |
$lte | less than or equal |
$ne | not equal |
$in | in |
$nin | not in |
🎈此外,由于管道阶段的 RAM 限制为 100MB,如果要处理大型数据集,那么开启 allowDiskUse 选项启用聚合管道阶段,将数据写入临时文件,找个参数可以视情况而加。
🎈最后,将上面的聚合查询语句在 Robo3T 中的终端命令行执行,得到的结果如下图所示
🎈由上图可以看出,分别将出现重复值的 host_id 以及重复的次数查询出来。那么之后,便可以根据得到的 host_id 去后台数据库中根据 host_id 查询记录,再将记录删除,这里就不再叙述如何进行查询以及删除语句了,因为重点是关于如何利用聚合查询语句进行初步筛选得到重复值,这才是本篇博客记录的重点。