mongodb语法与spring实现

本文深入解析MongoDB的BSON类型、查询与投影操作符、聚合管道阶段及表达式,涵盖文档结构、查询、聚合与修改操作的关键知识。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

mongodb语法

参考文档:https://docs.mongodb.com/manual/reference/

BSON Types

BSON Type有2种标识符,整形和字符串

类型数值字符串说明
Double1“double”
String2“string”
Object3“object”
Array4“array”
Binary data5“binData”
Undefined6“undefined”Deprecated.
ObjectId7“objectId”
Boolean8“bool”
Date9“date”
Null10“null”
Regular Expression11“regex”
DBPointer12“dbPointer”Deprecated.
JavaScript13“javascript”
Symbol14“symbol”Deprecated.
JavaScript (with scope)15“javascriptWithScope”
32-bit integer16“int”
Timestamp17“timestamp”
64-bit integer18“long”
Decimal12819“decimal”New in version 3.4.
Min key-1“minKey”
Max key127“maxKey”

可以使用***$type***操作符使用这些类型。

BSON特定类型

ObjectId

近似唯一,快速生成,已排序的类型,12byte**。**

String

UTF-8格式,

Timestamps

Date

64位整形,从1970.01.01开始的毫秒数。

查询和投影操作符

Name意义
比较操作符
$eq相等
$gt大于
$gte大于等于
$in包含在集合中
$lt小于
$lte小于等于
$ne不等于
$nin不在集合中
逻辑操作符
$andAND
$notNOT
$nor同时满足2个条件的,则为false
$orOR
元素操作符
$exists字段存在
$type字段类型为指定类型
表达式计算
$expr
$jsonSchema
$mod
$regex正则表达式
$text
$where
地理空间
$geoIntersects
$geoWithin
$near
$nearSphere
数组操作符
$all包含所有指定的元素
$elemMatch存在元素匹配所有指定条件
$size指定数组大小
二进制操作
$bitsAllClear
$bitsAllSet
$bitsAnyClear
$bitsAnySet
注释
$comment
投影
$投影第一个数组元素
$elemMatch投影第一个匹配条件的元素
$meta
$slice

Update操作

操作符说明语法
字段操作
$currentDate设置字段值为当前日期
$inc字段值加上指定值
$min仅当指定值小于字段值时更新
$max仅当指定值大于字段值时更新
$mul字段值乘以指定值
$rename字段重命名
$set设置字段值为指定值
$setOnInsert当文档新增时设置值。
$unset移除字段值
数组操作
$代指匹配查询条件的第一个元素
$[]代指匹配查询条件的所有元素
$[]代指匹配arrayFilters的所有元素
$addToSet如果元素不存在则加入数组
$pop移除第一或最后的元素
$pull移除匹配条件的所有元素
$push增加一个元素到数组
$pullAll移除匹配一个集合的所有元素
修饰
$each修饰push,push,push,addToSet,循环数组中的每个元素当做一个对象,而不是整个数组作为一个对象
$position修饰$push,指定插入位置
$slice修饰$push,限制修改数组的大小
$sort修饰$push,排序数组
位运算
$bitPerforms bitwise AND, OR, and XOR updates of integer values.

聚合管道阶段

MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。
表达式:处理输入文档并输出。表达式是无状态的,只能用于计算当前聚合管道的文档,不能处理其它的文档。

集合聚合

db.collection.aggregate()

除了$out, $merge, and $geoNear,所有阶段都可以出现多次。

StageDescription示例
$addFields增加新字段到文档中,类似project。project。projectset is an alias for $addFields.
$bucket
$bucketAuto
$collStats
$count文档总数
$facet
$geoNear输出接近某一地理位置的有序文档
$graphLookup
$group分组{ $group: { _id: null, count: { $sum: 1 } } }
$indexStats
$limit取n条记录{ $limit : 5 }
$listSessions
$lookup从另外一个文档引入字段
$match用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。{ $match : { score : { $gt : 70, $lte : 90 } } }
$merge把结果输出到指定collection
$out把结果输出到指定collection{ $out: “” }
$planCacheStats
$project修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。$project : { title : 1,author : 1 ,}
$redact
$replaceRoot用replacementDocument代替当前文档{ $replaceWith: }
$replaceWith同$replaceRoot
$sample随机取样{ $sample: { size: 3 } }
$set增加字段{ $set: { : , … } }
$skip跳过n条记录{ $skip : 5 }
$sort排序{ $sort : { age : -1, posts: 1 } }
$sortByCount分组count,再倒序{ sortByCount:"sortByCount: "sortByCount:"tags" } 等价于: { $group: { _id: , count: { $sum: 1 } } }, { $sort: { count: -1 } }
$unset排除字段{ $unset: [ “”, “”, … ] }
$unwind把数组属性平铺,1条记录会平铺成n条记录{$unwind: { path: , includeArrayIndex: , //保存元素索引的新字段 preserveNullAndEmptyArrays: //true:path为null, missing,empty array,输出文档。false:不输出 } }

数据库聚合

db.aggregate( [ { <stage> }, ... ] )

since 3.6

聚合管道操作(标量函数)

NameDescription示例
数学计算
$abs求绝对值
$add加法
$ceil大于等于指定值的最小整数
$divide除法
$exp指数
$floor小于等于指定值的最大整数
$ln自然对数
$log对数
$log1010为底对数
$mod求模
$multiply乘法
$pow求幂
$roundround
$sqrt求二次根
$subtract减法
$trunc截断
数组操作
$arrayElemAt求index
$arrayToObject数组转document
$concatArrays连接数组
$filter过滤
$in在集合中
$indexOfArray第一个匹配的index
$isArray是否数组
$mapmap
$objectToArray对象转数组
$range
$reduce
$reverseArray
$size数组大小
$slice数组切片
$zip合并2个数组
逻辑表达式
$andand
$notnot
$oror
比较操作符
$cmp*比较**2**个操作数*
$eq相等
$gt大于
$gte大于等于
$lt小于
$lte小于等于指定值的最大整数
$ne不等
条件操作符
NameDescription
$cond
$ifNull
$switch
日期操作
$dateFromParts
$dateFromString
$dateToParts
$dateToString
$dayOfMonth
$dayOfWeek
$dayOfYear
$hour
$isoDayOfWeek
$isoWeek
$isoWeekYear
$millisecond
$minute
$month
$second
$toDate
$week
$year
$add
$subtract
字面表达式
$literal
对象表达式
$mergeObjects
$objectToArray
集合操作
$allElementsTrue
$anyElementTrue
$setDifference
$setEquals
$setIntersection
$setIsSubset
$setUnion
字符串操作
$concat
$dateFromString
$dateToString
$indexOfBytes
$indexOfCP
$ltrim
$regexFind
$regexFindAll
$regexMatch
$rtrim
$split
$strLenBytes
$strLenCP
$strcasecmp
$substr
$substrBytes
$substrCP
$toLower
$toString
$trim
$toUpper
文本操作
$meta
三角 函数
$sin
$cos
$tan
$asin
$acos
$atan
$atan2
$asinh
$acosh
$atanh
$degreesToRadians
$radiansToDegrees
类型操作
$convertConverts a value to a specified type.(since4.0)
$toBoolConverts value to a boolean.(since4.0)
$toDateConverts value to a Date.(since4.0)
$toDecimalConverts value to a Decimal128.(since4.0)
$toDoubleConverts value to a double.(since4.0)
$toIntConverts value to an integer.(since4.0)
$toLongConverts value to a long.(since4.0)
$toObjectIdConverts value to an ObjectId.(since4.0)
$toStringConverts value to a string.(since4.0)
$typeReturn the BSON data type of the field.
聚合操作
$addToSet
$avg
$first
$last
$max
$mergeObjects
$min
$push
$stdDevPop
$stdDevSamp
$sum
Accumulators (in Other Stages)
$avg
$max
$min
$stdDevPop
$stdDevSamp
$sum
变量操作
$let

spring实现

文档结构

{
_id: ObjectId(“5dbbe8ce79829800070b2374”),
SMD: {
source: {
DSN: “XXXX”,
KEY: “5da31fa07c2a5e497e8ded8c844e38bd”
},
infofragment: [
{
storagetype: “inner”,
format: “origin”,
filestore: {
fsname: “爬虫”,
filename: “XXXXX基本数据表”,
fileid: “5dbbe8ce79829800070b2373”
},
adapter: { }
}
],
services: [
{
name: “DataImport”,
handledtime: ISODate(“2019-11-01T08:11:58.369Z”),
version: “1.0”
},
{
name: “TagIdentify”,
handledtime: ISODate(“2020-03-01T13:30:41.006Z”)
}
],
quality: {
status: NumberInt(“1”),
checktime: ISODate(“2020-03-01T13:47:38.289Z”),
version: “EPModel:1”
},
timestamp: ISODate(“2020-03-01T13:30:41.007Z”),
tenantid: “XXXX”
},
UMD: {
creator: null,
bd: “XXXXXX”,
ru: null,
pt: “XXXXX基本数据表”,
bw: “XXXXXX”,
bot: “井”,
root: null,
createdate: null,
publisher: null,
title: “XXXXX基本数据表”,
bo: “”,
bp: “XXXX”,
ds: “XXXXX”
},
version: NumberInt(“42702”)
}

说明:

UMD下属性是不固定的。

查询

1、通过json字符串构造查询对象

Document filter = Document.parse(filter.toJSONString(0));
String collectionName = mongoTemplate.getCollectionName(AppData.class);
MongoCollection collection = mongoTemplate.getCollection(collectionName);

long count = collection.countDocuments(filter);

FindIterable<Document> found = collection.find(filter);

2、正则表达式

            Document doc = new Document();
            doc.put("$regex", request.getTitle());
            doc.put("$options", "i");

            filter.put(PATH_UMD_TITLE, doc);

或者

criteriaAll.and(AppData.PATH_UMD_PT).regex(request.getPt(), "i");

聚合

1、根据Services.name作为分组条件,统计数据,services元素展开

// { "$unwind" : "$SMD.services"}
UnwindOperation unwindOperation = Aggregation.unwind("SMD.services");

Criteria criteria = Criteria.where(AppData.PATH_SMD_TENANT).is(tenantId);
MatchOperation matchOperation = Aggregation.match(criteria);

//{ "$project" : { "servicename" : "$SMD.services.name" }}
ProjectionOperation projectionOperation = Aggregation.project().and("SMD.services.name").as("servicename");
//{ "$group" : { "_id" : { "servicename" : "$servicename"} , "total" : { "$sum" : 1}}}
GroupOperation groupOperation = Aggregation.group("servicename"
).count().as("total");

//========统计所有记录
Aggregation aggregationAll = Aggregation.newAggregation(
        matchOperation
        , unwindOperation
        , projectionOperation
        , groupOperation

        , Aggregation.project("servicename", "total")

                .and("servicename").previousOperation()
);

AggregationResults resultAll = mongoTemplate.aggregate(aggregationAll, AppData.class, ServiceCountEntity.class);

List<ServiceCountEntity> valuesAll = resultAll.getMappedResults();

return valuesAll.stream().collect(Collectors.toMap(
        ServiceCountEntity::getServiceName
        , ServiceCountEntity::getTotal

));

2、根据UMD指定的字段统计

Criteria criteria = Criteria.where(AppData.PATH_SMD_TENANT).is(tenantId);

String path = StrUtil.format("UMD.{}", tag);

GroupBy groupBy = GroupBy.key(path).initialDocument("{}").reduceFunction("function(doc, prev){}");

GroupByResults r = mongoTemplate.group(criteria, mongoTemplate.getCollectionName(AppData.class), groupBy, BasicDBObject.class);
List<Document> valuesAll = (List<Document>) r.getRawResults().get("retval");

return valuesAll.size();

修改

1、通过id查询文档,并修改UMD属性

Criteria criteriaId = Criteria.where("_id").is(new ObjectId(id));
Query query = new Query(criteriaId);

Update update = new Update();

//更新UMD
for (Map.Entry<String, Object> entry : umd.entrySet()) {
    update.set(StrUtil.format("UMD.{}", entry.getKey()), entry.getValue());
}


mongoTemplate.updateFirst(query, update, AppData.class);

2、修改Services下元素,通过name匹配,如果不存在则插入元素

Criteria criteriaId = Criteria.where("_id").is(new ObjectId(id));
Query query = new Query(criteriaId);

Document service = new Document();
service.put("name", "TagIdentify");


Update update = new Update();
//删除一个匹配的数组元素
update.pull("SMD.services",service);

//先更新一次,如果service存在(name相同),则删除。
mongoTemplate.updateFirst(query, update, AppData.class);

service.put("handledtime", new Date());
service.put("version", "1.0");

Update updateAdd = new Update();
//新增服service
updateAdd.addToSet("SMD.services", service);

mongoTemplate.updateFirst(query, updateAdd, AppData.class);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值