- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章使用aggregate在MongoDB中查询重复数据记录的方法由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。有点类似sql语句中的 count(*).
aggregate() 方法 。
MongoDB中聚合的方法使用aggregate().
语法 。
aggregate() 方法的基本语法格式如下所示:
1
|
>db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
|
我们知道,MongoDB属于文档型数据库,其存储的文档类型都是JSON对象。正是由于这一特性,我们在Node.js中会经常使用MongoDB进行数据的存取。但由于Node.js是异步执行的,这就导致我们无法保证每一次的数据库save操作都是原子型的。也就是说,如果客户端连续两次发起同一事件将数据存入数据库,很可能会导致数据被重复保存。高并发的情况下,哪怕是你在代码中已经做了非常严格的校验,例如插入数据前判断要保存的数据是否已经存在,但仍然有可能会出现数据被重复保存的风险。因为在异步执行中,你没有办法保证哪个线程先执行,哪个线程后执行,客户端发起的所有请求并非按我们想象的都是顺序执行的。一个较好的解决办法是在Mongo数据库的所有表中创建唯一索引。事实上,MongoDB默认会为所有表创建一个_id字段的唯一索引(可以取消)。如果你想在Node.js中通过mongoose.schema来自动创建索引,可以参考下面的代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
var
mongoose = require(
'mongoose'
);
var
Schema = mongoose.Schema;
var
customerSchema =
new
mongoose.Schema({
cname: String,
cellPhone, String,
sender: String,
tag: String,
behaviour: Number,
createTime: {
type: Date,
default
: Date.now
},
current:{
type: Boolean,
default
:
true
}
}, {
versionKey:
false
});
customerSchema.index({cname:1,cellPhone:1,sender:1,tag:1,behaviour:1}, {unique:
true
});module.exports = mongoose.model(
'customer'
, customerSchema);
|
上面的model中我们定义了表customer的结构,并通过index()方法在字段cname,cellPhone,sender,tag,behaviour上创建了唯一索引,这样当包含这些字段的重复数据被插入时,数据库会抛出异常。借用mongoose,如果数据库表之前已经被创建并且程序正在运行中,当我们修改model并添加索引,然后重新启动app,只要有对该model的访问,mongoose会自动进行检测并创建索引。当然,如果数据出现重复,则索引创建会失败。此时我们可以通过在创建索引时添加dropDups选项,让数据库自动将重复的数据删除,如:
1
|
customerSchema.index({cname:1,cellPhone:1,sender:1,tag:1,behaviour:1}, {unique:
true
, dropDups:
true
});
|
不过据MongoDB的官方说明,自3.0以后的版本不再使用该选项,而且也并没有提供替代的解决办法。貌似官方不再提供创建索引时自动删除重复记录的功能。那如何才能快速有效地找出重复的记录并且删除呢?首先我们要找出这些记录,然后通过remove()方法进行删除。下面的查询语句可以找出给定字段有重复数据的记录:
1
2
3
4
5
6
7
8
9
10
|
db.collection.aggregate([
{ $group: {
_id: { firstField:
"$firstField"
, secondField:
"$secondField"
},
uniqueIds: { $addToSet:
"$_id"
},
count: { $sum: 1 }
}},
{ $match: {
count: { $gt: 1 }
}}
])
|
替换_id属性的值以指定你想要进行判断的字段。相应地,在Node.js中代码如下:
1
2
3
4
5
6
7
8
|
var
deferred = Q.defer();
var
group = { firstField:
"$firstField"
, secondField:
"$secondField"
};
model.aggregate().group({
_id: group,
uniqueIds: {$addToSet:
'$_id'
},
count: {$sum: 1}
}).match({ count: {$gt: 1}}).exec(deferred.makeNodeResolver());
return
deferred.promise;
|
上述代码使用了Q来替换函数执行中的回调。在Node.js的异步编程中,使用Q来处理回调是个不错的选择.
下面是返回的结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
/* 1 */
{
"result"
: [
{
"_id"
: {
"cellPhone"
:
"15827577345"
,
"actId"
: ObjectId(
"5694565fa50fea7705f01789"
)
},
"uniqueIds"
: [
ObjectId(
"569b5d03b3d206f709f97685"
),
ObjectId(
"569b5d01b3d206f709f97684"
)
],
"count"
: 2.0000000000000000
},
{
"_id"
: {
"cellPhone"
:
"18171282716"
,
"actId"
: ObjectId(
"566b0d8dc02f61ae18e68e48"
)
},
"uniqueIds"
: [
ObjectId(
"566d16e6cf86d12d1abcee8b"
),
ObjectId(
"566d16e6cf86d12d1abcee8a"
)
],
"count"
: 2.0000000000000000
}
],
"ok"
: 1.0000000000000000
}
|
从结果中可以看到,一共有两组数据相同的记录,所以返回的result数组的长度为2。uniqueIds属性为一个数组,其中存放了重复记录的_id字段的值,通过该值我们可以使用remove()方法来查找并删除对应的数据.
最后此篇关于使用aggregate在MongoDB中查询重复数据记录的方法的文章就讲到这里了,如果你想了解更多关于使用aggregate在MongoDB中查询重复数据记录的方法的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我有一个网站。 必须登录才能看到里面的内容。 但是,我使用此代码登录。 doc = Jsoup.connect("http://46.137.207.181/Account/Login.aspx")
我正在尝试为我的域创建一个 SPF 记录并使我的邮件服务器能够对其进行评估。我在邮件服务器上使用 Postfix 并使用 policyd-spf (Python) 来评估记录。目前,我通过我的私有(p
我需要为负载平衡的 AWS 站点 mywebsite.com 添加 CName 记录。记录应该是: @ CNAME mywebsite.us-east-1.elb.amazon
我目前正在开发一个相当大的多层应用程序,该应用程序将部署在海外。虽然我希望它在解聚后不会折叠或爆炸,但我不能 100% 确定这一点。因此,如果我知道我可以请求日志文件,以准确找出问题所在以及原因,那就
我使用以下命令从我的网络摄像头录制音频和视频 gst-launch-0.10 v4l2src ! video/x-raw-yuv,width=640,height=480,framerate=30/1
我刚刚开始使用 ffmpeg 将视频分割成图像。我想知道是否可以将控制台输出信息保存到日志文件中。我试过“-v 10”参数,也试过“-loglevel”参数。我在另一个 SO 帖子上看到使用 ffmp
我想针对两个日期查询我的表并检索其中的记录。 我这样声明我的变量; DECLARE @StartDate datetime; DECLARE @EndDate datetime; 并像这样设置我的变量
在 javascript 中,我可以使用简单的 for 循环访问对象的每个属性,如下所示 var myObj = {x:1, y:2}; var i, sum=0; for(i in myObj) s
最近加入了一个需要处理大量代码的项目,我想开始记录和可视化调用图的一些流程,让我更好地理解一切是如何组合在一起的。这是我希望在我的理想工具中看到的: 每个节点都是一个函数/方法 如果一个函数可以调用另
如何使用反射在F#中创建记录类型?谢谢 最佳答案 您可以使用 FSharpValue.MakeRecord [MSDN]创建一个记录实例,但是我认为F#中没有任何定义记录类型的东西。但是,记录会编译为
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 3年前关闭。 Improve thi
我是 Sequelize 的新手并且遇到了一些语法问题。我制作了以下模型: // User sequelize.define('user', { name: { type: DataTyp
${student.name} Notify 这是我的output.jsp。请注意,我已经放置了一个链接“Notify”以将其转发到 display.jsp 上。但我不确定如何将 Stud
例如,这是我要做的查询: server:"xxx.xxx.com" AND request_url:"/xxx/xxx/xxx" AND http_X_Forwarded_Proto:(https O
我一直在开发大量 Java、PHP 和 Python。所有这些都提供了很棒的日志记录包(分别是 Log4J、Log 或logging)。这在调试应用程序时有很大帮助。特别是当应用程序 headless
在我的Grails应用程序中,我异步运行一些批处理过程,并希望该过程记录各种状态消息,以便管理员以后可以检查它们。 我考虑过将log4j JDBC附加程序用作最简单的解决方案,但是据我所知,它不使用D
我想将进入 MQ 队列的消息记录到数据库/文件或其他日志队列,并且我无法修改现有代码。是否有任何方法可以实现某种类似于 HTTP 嗅探器的消息记录实用程序?或者也许 MQ 有一些内置的功能来记录消息?
如果我有一条包含通用字段的记录,在更改通用字段时是否有任何方法可以模仿方便的 with 语法? 即如果我有 type User = // 'photo can be Bitmap or Url {
假设我有一个名为 Car 的自定义对象。其中的所有字段都是私有(private)的。 public class Car { private String mName; private
当记录具有特定字段时,我需要返回 true 的函数,反之亦然。示例: -record(robot, {name, type=industrial, ho
我是一名优秀的程序员,十分优秀!