mongodb数组去重(mongodb 去重查询)

本文目录
- mongodb 去重查询
- php删除数组指定元素并重建索引
- MongoDB内嵌数组文档,怎么只针对数组里的数据做增删改查
- mongo中的高级查询之聚合操作(distinct,count,group)与数据去重
- 如何在Mongodb集合中统计去重之后的数据
- MongoDB字符串替换
- node.js中删除mongodb数组子文档元素
mongodb 去重查询
在MongoDB中,文档是对数据的抽象,它被使用在Client端和Server端的交互中。所有的Client端(各种语言的Driver)都会使用这种抽象,它的表现形式就是我们常说的BSON(Binary JSON )。
BSON是一个轻量级的二进制数据格式。
MongoDB能够使用BSON,并将BSON作为数据的存储存放在磁盘中。
当Client端要将写入文档,使用查询等等操作时,需要将文档编码为BSON格式,然后再发送给Server端。同样,Server端的返回结果也是编码为BSON格式再放回给Client端的。
php删除数组指定元素并重建索引
mongodb中使用aggregate可以返回数组字段数组的指定索引的元素
参考语句:
{$match:{’duid’:15}},
{$project:{duid:1,"default":1}},
{$unwind:"$default.styles"},
{$match:{’default.styles.status’:1}},
{$group:{_id:"$_id","defaults":{$push:"$default.styles"}}}
解释:
1:过滤数据{$match:{’duid’:15}}
2:获取想要的列{$project:{duid:1,"default":1}}
3:获取展开后数组字段{$unwind:"$default.styles"}
4:条件查询数组元素{$match:{’default.styles.status’:1}}
5:分组后保存结果{$group:{_id:"$_id","defaults":{$push:"$default.styles"}}}
MongoDB内嵌数组文档,怎么只针对数组里的数据做增删改查
有一个user类,他包含一个标签属性,这个标签是一个数组,数组里面的元素是内嵌文档,格式如下:
《!-- lang: js --》
{
"_id" : "195861",
"tags" : [
{
"tagId" : NumberLong(766),
"optDate" : ISODate("2013-08-12T15:21:02.930Z"),
"enable" : true
},
{
"tagId" : NumberLong(778),
"optDate" : ISODate("2013-08-12T15:21:02.930Z"),
"enable" : true
}
]
}
下面对这个文档中的tag进行增删该查操作,这里用到了spring mongodb 里面的MongoTemplate类。我这里把tags里的内嵌文档抽象成了Tag类。代码删除和修改本身就包含查询方法,所以没写查询方法
代码如下:
《!-- lang: java --》
/**
*
* @author zhangdonghao
*
*/
@Component("UserrTagServiceImpl")
public class UserrTagServiceImpl implements UserrTagService {
/**
* Mongo DB Spring Template
*/
@Resource
protected MongoTemplate mongoTemplate = null;
public UserrTagServiceImpl() {
}
/**
**给tags数组添加一个元素
*/
@Override
public Response《Integer》 addTag(String id, Long tagId) {
try {
Tag tag = new Tag(tagId);
tag.setOptDate(new Date());
tag.setEnable(true);
Query query = Query.query(Criteria.where("_id").is(id));
Update update = new Update();
update.addToSet("tags", tag);
mongoTemplate.upsert(query, update, User.class);
} catch (Exception e) {
return new Response《Integer》(0);
}
return new Response《Integer》(1);
}
/**
**修改tags数组中内嵌文档指定一个元素的值
*/
@Override
public Response《Integer》 disableTag(String id, Long tagId) {
try {
Query query = Query.query(Criteria.where("_id").is(id)
.and("tags.tagId").is(tagId));
Update update = new Update();
update.set("tags.$.enable", false);
mongoTemplate.updateFirst(query, update, User.class);
} catch (Exception e) {
return new Response《Integer》(0);
}
return new Response《Integer》(1);
}
/**
**删除tags数组中指定的内嵌文档
*/
@Override
public Response《Integer》 removeTag(String id, Long tagId) {
try {
Query query = Query.query(Criteria.where("_id").is(id)
.and("tags.tagId").is(tagId));
Update update = new Update();
update.unset("tags.$");
mongoTemplate.updateFirst(query, update, User.class);
} catch (Exception e) {
return new Response《Integer》(0);
}
return new Response《Integer》(1);
}
public MongoTemplate getMongoTemplate() {
return mongoTemplate;
}
public void setMongoTemplate(MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate;
}
}
mongo中的高级查询之聚合操作(distinct,count,group)与数据去重
Mongodb中自带的基本聚合函数有三种:count、distinct和group。下面我们分别来讲述一下这三个基本聚合函数。
(1)count
作用:简单统计集合中符合某种条件的文档数量。
使用方式:db.collection.count(《query》)或者db.collection.find(《query》).count()
参数说明:其中《query》是用于查询的目标条件。如果出了想限定查出来的最大文档数,或者想统计后跳过指定条数的文档,则还需要借助于limit,skip。
举例:
db.collection.find(《query》).limit();
db.collection.find(《query》).skip();
(2)distinct
作用:用于对集合中的文档针进行去重处理
使用方式:db,collection.distinct(field,query)
参数说明:field是去重字段,可以是单个的字段名,也可以是嵌套的字段名;query是查询条件,可以为空;
举例:
db.collection.distinct("user",{“age":{$gt:28}});//用于查询年龄age大于28岁的不同用户名
除了上面的用法外,还可以使用下面的另外一种方法:
db.runCommand({"distinct":"collectionname","key":"distinctfied","query":《query》})
collectionname:去重统计的集合名,distinctfield:去重字段,,《query》是可选的限制条件;
举例:
这两种方式的区别:第一种方法是对第二种方法的封装,第一种只返回去重统计后的字段值集合,但第二种方式既返回字段值集合也返回统计时的细节信息。
(3)group
作用:用于提供比count、distinct更丰富的统计需求,可以使用js函数控制统计逻辑
使用方式:db.collection.group(key,reduce,initial)
备注说明:在2.2版本之前,group操作最多只能返回10000条分组记录,但是从2.2版本之后到2.4版本,mongodb做了优化,能够支持返回20000条分组记录返回,如果分组记录的条数大于20000条,那么可能你就需要其他方式进行统计了,比如聚合管道或者MapReduce;
===========================================================
mongo中的高级查询之聚合操作(distinct,count,group)
1.distinct的实现:
2.count的实现
3.group的实现
(1).分组求和:类似于mysql中的 select act,sum(count) from consumerecords group by act
(2).分组求和,过滤。类似mysql中的select act,sum(count) from consumerecords group by act having act=’charge’;
(3).将时间格式化并且按时间分组求count,不推荐使用这种方法。
db.playerlogs.aggregate({ concat:},{ dayOfMonth:" group:{_id:" sum:1}}},{$sort:{con:1}}) ;
group按时间分组(时间格式化)
***隐藏网址***
javascriptz中时间的相关函数参考:
***隐藏网址***
(4).group 分组方法实现的讲解。
group 的完整语法是。
参数解释:
key:需要分组的键或是函数(function),group分组实例3中的key就是一个函数值
initial:声明并且初始化变量。每一组共享一个变量值。多个变量之间用逗号隔开
$reduce:循环体,集合中有多少个文档,就会循环多少次。函数(function)中变量doc表示当前文档对象,
prev表示累积处理的结果对象(这个地方可能描述的不是很情况,自己慢慢体会)
finalize:可选参数,可以简单理解为对分组之后的结果的再次处理,doc表示group之后的文档对象(这一步也是一个循环体
condition:可选参数,对已经分组好的结果进行过滤,有点类似于mysql中的having
4.mapReduce:暂缺,要想玩转这个方法需要有很强的JavaScript功能。
据说mapReduce 可以实现很复杂的查询,可以将一个复杂的查询分拆到多个机器上运行,
然后把各个结果集组合起来,形成最终结果。但是很慢。
mapreduce用法大全
***隐藏网址***
mapreduce性能调优
***隐藏网址***
数组中去除重复值示例
***隐藏网址***
5.db.runCommand的相关命令.
db.runCommand({distinct:"consumerecords",key:"userId"}):键值去重 类似于mysql中的 select distinct userId from consumerecords
db.runCommand({distinct:"consumerecords",key:"userId"}).values.length:去重之后求记录数,类似于mysql中的 select count(distinct userId) from consumerecords
db.runCommand({distinct:"consumerecords",key:"userId",query:{act:"charge"}}):去重之后求记录数,类似于mysql中的 select distinct userId from consumerecords where act="charge"
db.runCommand(
... {
... group:
... {
... ns:"test2", # 集合名
... key:{iname:true}, # 分组字段
... initial:{dd:0}, # 按照来初始化该值
... reduce之后 ,function返回的值
... {
... prev.dd=doc.iage+prev.dd #
... }
...
... }
... }
... )
数值以字符串形式存储的解决方案:
db.runCommand(
{
group:
{
ns:"consumerecords",
key:{act:true},
initial:{ct:100,tt:0},
$reduce:function(doc,prev)
{
},
}
}
)
去重
1, 直接使用distinct 语句查询, 这种查询会将所有查询出来的数据返回给用户, 然后对查询出来的结果集求总数(耗内存,耗时一些)
var len = db.student.distinct("name",{"age" : 18}).length;
print(len)
注,使用这种方法查询时,查询的结果集大于16M 时会查询失败,失败信息如下:
{“message” : “distinct failed: MongoError: distinct too big, 16mb cap”,”stack” : “script:1:20”}
2, 使用聚合函数,多次分组统计结果,最终将聚合的结果数返回给用户
db.student.aggregate([
{ project:{"name":true}},
{ name"}},
{ sum:1}}}
])
注,这种查询数据量大时就不会出现如上查询失败的情况,而且这种查询不管是内存消耗还是时间消耗都优于上面一种查询
ps:根据id分组,id指定为组合项的话,因为id不会重复,所以作用相当于把组合项去重了。
假如现在需要拿出collection的其他field的话,可以使用$push关键字
// 根据name和sex分组
// 把分组后的name,sex,age放到对应的Document下,形成一个数组
db.student.aggregate(
[
{
name", sex: " push: " push: " push: "$age"}
}
}
]
). forEach(function(x){
db.temp.insert(
{
name: x.name,
sex : x.sex,
age: x.age
}
);
});
如何在Mongodb集合中统计去重之后的数据
比方说我们有个Mongodb集合,
以这个简单的集合为例,我们需要集合中包含多少不同的手机号码,首先想到的应该就是使用distinct关键字,
db.tokencaller.distinct(’Caller’).length
如果想查看具体的而不同的手机号码,那么可以省略后面的length属性,因为db.tokencaller.distinct(’Caller’)返回的是由所有去重手机号码组成的数组。
但是,这种方式对于所有情况都是满足的嘛?并不如此,如果要统计的集合记录数较大,如千万级别的,那么在这么统计的时候往往会报10044错误,提示信息“exception : distinct too big , 16mb cap”. 后面我们将通过其他方式进行解决。
另外一种方式可以使用runCommand结合distinct进行使用,
db.runCommand({"distinct":"tokencaller","key":"Caller"})
可见在values上显示了去重之后的手机号码,,看结果是一个Json格式的,于是尝试了下看看能不能取出values的大小,因为如果对于大数据量的集合来说,直接显示去重的号码明显不合适,于是尝试了下面的写法:
发现是可以的,于是对大数据量使用了这种方式看看是否能取出结果,发现不存在length属性,想了想应该跟mongodb的客户端版本有关系吧,还待验证!!!
两种方式都不行,于是试了下mapReduce方式,具体如下:
然后我们会发现,他会将查询出来的结果输出到一个称为“callerstatis”的结合,如下所示:
然后使用db.callerstatis.count()就可以知道有多少不同的手机号码了。
使用这种方式,我们同样在大数据量的集合上试了一下,可惜还是失败了!!!!(桑心T_T),如果有谁有好的方法,麻烦也告诉我一下,小的感激不尽啊^_^
如果您对我的技术专栏文章感兴趣并支持我继续深入的写下去,您可以扫码支持我,毕竟英雄惜英雄嘛,不管多少我都真心的感谢您,毕竟都是对我劳动成果的认可,谢谢(^_^)。。。
MongoDB字符串替换
1、第一部分 {member_icon:{"$exists":true}} 是匹配查询,用于过滤要更新的文档,并且该位置可以加快查询速度。
2、第二部分 ($set: { member_icon: {...) 是更新聚合管道(请注意方括号表示使用聚合管道)
attachments 是一个数组, urls 是 attachments 里的数组,我们需要迭代 attachments.urls 数组的循环并替换 urls 。 $map 迭代 attachments.urls 数组的循环, $replaceOne 替换字符串。
ttachments是一个数组,url是attachments里对象的一个字段。
参考资料
在mongodb中的字符串数组中查找和替换
MongoDB通过forEach循环实现Replace
node.js中删除mongodb数组子文档元素
node.js中删除monogodb数组子文档使用$pull关键词
参考代码:
var filter = {_id: suggestID};
var update = {$pull: {replies: {rid:opts.doc.rid}}};
return opts.dbs.csdb.collection("suggests").findOneAndUpdateAsync(filter, update, {upsert: false})

更多文章:
androidapp源码免费下载(如何实现APK的反编译得到APK的源码)
2026年9月22日 18:00
service pack 3(操作系统版本升级(SP) Service Pack 3当中的“Service Pack 3”是什么意思)
2026年9月22日 10:20
html代码怎么写大佬教程(html网页的题来个大佬,写代码,题目在图上)
2026年9月22日 10:10
结构体内又一个struct(c++ 在结构体中再嵌入一个结构体如何调用)
2026年9月22日 09:40
cocos creator中文(cocoscreator和cocoscreator3d的区别)
2026年9月22日 02:30







