Mongodb操作与Java(二)查询语句汇总

MongoDB概念

MongoDB 基本概念指的是学习 MongoDB 最先应该了解的词汇,比如 MongoDB 中的"数据库"、"集合"、"文档"这三个名词:

文档(Document): 文档是 MongoDB 中最基本的数据单元,由键值对组成,类似于 JSON 格式,可以存储不同字段,字段的值可以包括其他文档,数组和文档数组。(相当于mysql每一行就是一个文档)

集合(Collection): 集合指的是文档组(类似于 Mysql 中的表的概念),里面可以存储许多文档。

数据库(Database): MongoDB 中可以存在多个数据库,每个数据库中中用有不同的集合与用户权限,这样可以供不同的项目组使用不同的数据库。

常用查询语句

查找所有文档

查询集合(比如 users 集合)中的所有文档:这个查询不带任何条件,返回集合中的所有文档。

db.users.find()

分页查询

查询并限制返回10条

db.users.find().limit(10)

查询用户,跳过前 20 个结果,并限制返回的结果数量为 10:.skip(20) 用于跳过前 20 个文档,.limit(10) 用于限制查询结果数量。

db.users.find().skip(20).limit(10)

排序查询结果

查询所有用户并按年龄升序排序:

db.users.find().sort({ age: 1 })

查找匹配特定条件的文档

查询所有年龄等于 25 的用户:

db.users.find({ age: 25 })

这里,{ age: 25 } 是一个查询条件,表示筛选出所有 age 字段值为 25 的文档。

模糊查询

假设您有一个名为users的表,其中包含名为name的字段,您想要对这个字段进行模糊搜索。您可以使用正则表达式来匹配包含特定字符串的文档。

db.users.find({ name: { $regex: /your_pattern_here/ } })

如果您想要不区分大小写地进行搜索,可以在正则表达式中末尾添加i标志:

db.users.find({ name: { $regex: /your_pattern_here/i } })

指定字段返回

假设有一个名为 users 的集合,文档结构包含 nameemailage 字段。如果你只想检索 nameemail 字段,可以使用 .projection 方法来实现

限定返回结果字段

db.users.find({}, { projection: { name: 1, email: 1, _id: 0 } })

这里 { name: 1, email: 1, _id: 0 } 指明返回的文档中应包含 nameemail 字段,并排除 MongoDB 默认的 _id 字段

包含查询

如果你使用的是 MongoDB Shell 或者类似的接口,并且想要查询 department 等于 "Sales" 且 job_title 包含在某个列表中(如 'Manager' 或 'Associate')的文档,你可以这样写:

db.employees.find({

department: "Sales",

job_title: { $in: ["Manager", "Associate"] }

});

这里的 **in** 操作符类似于 SQL 中的 **IN**,用于匹配字段值是否存在于指定数组中。不包含是nin

大小查询

如果你需要构造一个 MongoDB 查询,以满足字段同时大于等于(gte**)和小于等于(**lte)一个特定值的条件,同时另一个字段等于($eq)特定的值,你可以使用组合查询。以下是一个具体示例,假设我们需要查询一个集合中,年龄在20岁到30岁之间(包含20岁和30岁),并且名字等于"John"的文档。

db.users.find({

db.users.find({

age: { gte: 20, lte: 30 }, // 年龄大于等于20且小于等于30

name: { $eq: "John" } // 名字等于John

});

计数查询结果

计算年龄等于 25 的用户数量:countDocuments 函数统计匹配查询条件的文档数量

db.users.countDocuments({ age: 25 })

或者

查询名字是 "John" 或者 "Jane" 的用户:$or 是逻辑操作符,允许多个查询条件中的任意一个成立时,文档就会被选中。

db.users.find({ $or: [{ name: "John" }, { name: "Jane" }] })

高级查询

分组

MongoDB 提供了一个强大的聚合框架,类似于 SQL 中的 GROUP BY 功能。这个聚合框架可以用来执行包括数据分组、计算汇总统计等复杂的数据处理任务。在 MongoDB 中,这通常是通过 aggregate 方法来实现的,其中可以使用多种聚合阶段(比如 $group$match$sort 等)来构建复杂的查询和数据处理流程。

使用 $group 进行分组统计

假设你有一个名为 orders 的集合,每个文档包含 customeramount 字段,分别代表客户名和订单金额。如果你想计算每个客户的总订单金额,可以使用以下的聚合查询:

db.orders.aggregate([

{

$group: {

_id: "$customer",

totalAmount: { sum: "amount" }

}

}

]);

在这个聚合查询中:

  • $group: 是用来将文档分组的阶段。
    • _id: "$customer":指定分组的键,这里使用 $customer 字段,意味着所有具有相同 customer 字段值的文档会被分到同一组。
    • totalAmount: { $sum: "$amount" }:为每个组计算总金额,$sum 操作符会加总每个组中的 amount 字段值。

结果:只显示_id和totalAmount字段

如果你想先过滤某些文档,再进行分组,可以这样做:

db.orders.aggregate([

{ $match: { status: "shipped" } },

{

$group: {

_id: "$customer",

totalAmount: { sum: "amount" }

}

},

{ $sort: { totalAmount: -1 } }

]);

这里:

  • $match: 过滤阶段,只有 status 字段为 "shipped" 的文档才会被处理。
  • $group: 同上,按客户分组并计算总金额。
  • $sort: 排序阶段,按 totalAmount 字段降序排序结果。
注意事项

MongoDB 的聚合操作非常强大,但也需要考虑性能问题,特别是在处理大数据集时。确保你的文档结构和索引策略适合你的聚合查询,以优化查询性能。

连表

在 MongoDB 中,连表查询通常是通过 $lookup 聚合管道操作符来实现的。这个操作符可以让你在一个聚合查询中从另一个集合中查询和合并数据,类似于 SQL 中的 JOIN 操作。

基本使用方法:

假设你有两个集合:ordersproductsorders 集合中的每个文档包含一个 productId 字段,你想将 orders 集合中的每个订单与 products 集合中相应的产品详情进行关联。以下是如何使用 $lookup 来实现这种关联:

db.orders.aggregate([

{

$lookup: {

from: "products", // 要联接的集合名称

localField: "productId", // 本地集合(orders)用于联接的字段

foreignField: "_id", // 外部集合(products)用于联接的字段

as: "productDetails" // 将联接查询结果添加到该字段

}

}

]);

解释:

  • from: 指定要联接的另一个集合的名称。
  • localField: 当前集合(发起 $lookup 的集合)中用于联接的字段。
  • foreignField: 被联接集合中用于匹配 localField 的字段。
  • as: 将外部集合的查询结果存储在每个输出文档的哪个字段下。
高级用法

从 MongoDB 3.6 开始,$lookup 支持使用管道,这让你可以在 $lookup 内部执行更复杂的查询,包括过滤、添加字段、限制返回字段等操作。

db.orders.aggregate([

{

$lookup: {

from: "products",

let: { orderProduct: "$productId" }, // 定义变量 orderProduct

pipeline: [ // 使用 pipeline 对 products 进行操作

{ $match:

{ $expr:

{ eq: \["_id", "$$orderProduct"] } // 使用变量进行匹配

}

},

{ $project: { name: 1, price: 1 } } // 限制返回的字段

],

as: "productDetails"

}

}

]);

相关推荐
Albert Edison4 小时前
【最新版】IntelliJ IDEA 2025 创建 SpringBoot 项目
java·spring boot·intellij-idea
Piper蛋窝5 小时前
深入 Go 语言垃圾回收:从原理到内建类型 Slice、Map 的陷阱以及为何需要 strings.Builder
后端·go
六毛的毛7 小时前
Springboot开发常见注解一览
java·spring boot·后端
AntBlack7 小时前
拖了五个月 ,不当韭菜体验版算是正式发布了
前端·后端·python
31535669137 小时前
一个简单的脚本,让pdf开启夜间模式
前端·后端
uzong8 小时前
curl案例讲解
后端
开开心心就好9 小时前
免费PDF处理软件,支持多种操作
运维·服务器·前端·spring boot·智能手机·pdf·电脑
一只叫煤球的猫9 小时前
真实事故复盘:Redis分布式锁居然失效了?公司十年老程序员踩的坑
java·redis·后端
猴哥源码9 小时前
基于Java+SpringBoot的农事管理系统
java·spring boot
大鸡腿同学9 小时前
身弱武修法:玄之又玄,奇妙之门
后端