当前位置: 首页 > news >正文

MongoDB及spring集成

MongoDB 是一个基于 分布式文件存储 的开源 NoSQL 数据库系统

用文档存数据,每个文档可以看作是一个键值对集合,类似于 JSON 对象

MongoDB 支持索引以提高查询性能,并且可以在任何属性上创建索引

文档(Document)
  • MongoDB 中的基本数据单元是文档(BSON格式),它是一个由键值对组成的数据结构,类似于 JSON 对象。
  • {"name": "Alice","age": 25,"hobbies": ["reading", "swimming"]
    }
  • 文档存储在集合中,支持嵌套和数组等复杂数据结构。
集合(Collection)
  • 集合是一组文档的容器,类似于关系数据库中的表。
  • 集合中的文档不需要有相同的字段或结构,这提供了很大的灵活性。
数据库(Database)
  • 数据库是多个集合的容器。
  • 每个数据库都有自己的文件集,并且每个数据库可以包含多个集合

文档操作:

插入文档:

db.users.insertOne({ name: "Bob", age: 30, hobbies: ["cycling"] });
db.users.insertMany([{ name: "Charlie", age: 35, hobbies: ["cooking"] },{ name: "Diana",     age: 40 }
]);

查询文档:

db.users.find();//查询所有文档
db.users.find({ age: { $gt: 30 } }); // 查找年龄大于30的所有用户

更新操作:

在 MongoDB 中,更新操作针对的是单个集合。MongoDB 中的所有写入操作在单个文档级别都具有原子性

db.users.updateOne({ name: "Alice" }, { $set: { age: 26 } });
db.users.updateMany({ age: { $lt: 30 } }, { $inc: { age: 1 } }); // 将所有年龄小于30的用户年龄加1

删除文档:

db.users.deleteOne({ name: "Bob" });
db.users.deleteMany({ age: { $gte: 40 } }); // 删除所有年龄大于等于40的用户

聚合操作:

可以使用聚合操作来:

  • 将来自多个文档的值组合在一起。
  • 对集合中的数据进行的一系列运算。
  • 分析数据随时间的变化。

MongoDB 提供了两种执行聚合的方法:

聚合管道(Aggregation Pipeline)

执行聚合操作的首选方法。

MongoDB 聚合管道由多个阶段组成,每个阶段在文档通过管道时转换文档。每个阶段接收前一个阶段的输出,进一步处理数据,并将其作为输入数据发送到下一个阶段

每个管道的工作流程是:

  1. 接受一系列原始数据文档
  2. 对这些文档进行一系列运算
  3. 结果文档输出给下一个阶段

使用 db.collection.aggregate() 方法运行的聚合管道不会修改集合中的文档,除非管道包含 $merge或 $out 阶段。

阶段操作符用于 db.collection.aggregate 方法里面

db.collection.aggregate( [ { 阶段操作符:表述 }, { 阶段操作符:表述 }, ... ] )
例子:
db.orders.aggregate([# 第一阶段:$match阶段按status字段过滤文档,并将status等于"A"的文档传递到下一阶段。{ $match: { status: "A" } },# 第二阶段:$group阶段按cust_id字段将文档分组,以计算每个cust_id唯一值的金额总和存储在聚合管道返回的total中。{ $group: { _id: "$cust_id", total: { $sum: "$amount" } } }
])
//$match相当于where
单一目的聚合方法(Single purpose aggregation methods)

也就是单一作用的聚合函数比如 count()distinct()estimatedDocumentCount()

spring集成:

在 Spring 框架中,Spring Data MongoDB 提供了MongoTemplate 类, 它提供了执行数据库操作的方法,并且支持强类型的查询和结果映射

对于操作的集合名称

  • 默认情况下,Spring Data MongoDB 使用实体类的小写类名作为集合名称。
  • 可以通过在实体类上使用 @Document(collection = "yourCollectionName") 来指定自定义的集合名称。
  • 或者,在调用 MongoTemplate 的方法时,直接通过方法参数指定集合名称,如 template.insert(Object object, String collectionName)
template.insert(p);
p = template.findById(p.getId(), Person.class);
template.updateFirst(query(where("name").is("Joe")), update("age", 35), Person.class);
template.remove(p);
//其中p是一个Person类的实例
查询文档:

可以使用Query、Criteria、Aggregation类来表达查询

其中Criteria只是定义查询条件的一部分,类似于SQL语句中的where,Criteria是不能单独执行的

Query、Aggregation一个完整的查询对象,包含了查询条件、排序、分页等信息

  • Query 适用于简单的查找操作,如根据条件筛选文档、排序、分页等。
  • Aggregation 则用于执行更复杂的数据处理任务,如分组、聚合、数据变换等。
  • Aggregation 可以看作是 Query 的高级形式,提供了更多的数据处理能力
//空条件(empty criteria)。这个条件相当于 MongoDB 查询中的 {},也就是匹配所有文档
Criteria criteria = new Criteria();
//Spring Data MongoDB 特有的链式 API 设计方式,方便构建动态查询条件。
criteria.and("name").is("Tom");
//criteria.and("field") 表示:对 "field" 字段添加一个新的条件。
//它内部会自动将这个字段作为新的 where 条件加入到当前的 Criteria 中。
//如果当前 Criteria 还是空的,就相当于从 where("field") 开始。
//完整的查询信息,简单查询
Query query = new Query();
query.addCriteria(Criteria.where("quantity").gt(2));
List<Order> orders = mongoTemplate.find(query, Order.class);
Aggregation aggregation = Aggregation.newAggregation(// 第一阶段: 筛选购买数量大于2的订单Aggregation.match(Criteria.where("quantity").gt(2)),// 第二阶段: 根据商品名称分组,计算总销售额Aggregation.group("item").sum(AggregationExpression.multiply("price", "quantity")).as("totalSales"),// 第三阶段: 按总销售额降序排列Aggregation.sort(Sort.by(Sort.Direction.DESC, "totalSales"))
);
//通过match来匹配构建好的criteria查询条件
//然后分阶段进行分组、排序等//需要通过mongoTemplate.aggregate来执行这个查询语句
//三个参数分别是构建的agg,查询的表,结果的class
AggregationResults<ItemSales> results = mongoTemplate.aggregate(aggregation, "orders", ItemSales.class);
//通过结果getMappedResults提取中目标class的集合
List<ItemSales> mappedResults = results.getMappedResults();

学习资料:MongoDB常见面试题总结(上) | JavaGuide

                    官方文档

相关文章:

  • SGLang和vllm比有什么优势?
  • 本案例介绍ABB电机保护单元如何走profibus总线通讯
  • stm32week16
  • MIME类型详解及应用案例
  • 【QT】一个界面中嵌入其它界面(二)
  • 数据库存储空间告急?磁盘清理与归档策略全解析
  • docker介绍与常用命令汇总
  • 火山 RTC 引擎9 ----集成 appkey
  • BM25(Best Matching 25)介绍与使用
  • 基于Zynq SDK的LWIP UDP组播开发实战指南
  • 对抗性机器学习:AI模型安全防护新挑战
  • 在linux平台下利用mingw64编译windows程序
  • 码蹄集——N是什么、棋盘
  • 冒泡排序详解
  • thinkphp6实现统一监听并记录所有执行的sql语句除查询外
  • Unity使用sherpa-onnx实现说话人识别
  • DS1302实时时钟模块
  • Java-List集合类全面解析
  • CSS- 4.5 css + div 布局 简易网易云音乐 官网布置实例
  • 「NameCraft · 幻想命名器」开发记:我和 CodeBuddy 的一次奇幻共创之旅
  • 连续两个交易日涨停,华夏幸福:生产经营活动正常,不存在影响股价波动的重大事宜
  • 国家外汇管理局:4月货物贸易项下跨境资金净流入649亿美元
  • 两名游客刻划八达岭长城,被拘5日罚200元
  • 大学2025丨专访西湖大学副校长邓力:如何才能培养“不惧未知”的创新者
  • 上海明天短暂恢复晴热最高32℃,一大波雨水在候场
  • 关税影响下沃尔玛想涨价,特朗普施压:自行承担,别转嫁给顾客