mongodb
# 1.MongoDB 常用查询
# 比较运算符
- $eq(等于)
- $ne(不等于)
- $gt(大于)
- $gte(大于等于)
- $lt(小于)
- $lte(小于等于)
# 示例
// $eq: 查找 age 等于 25 的文档
db.collection.find({ "age": { "$eq": 25 } })
// $ne: 查找 age 不等于 25 的文档
db.collection.find({ "age": { "$ne": 25 } })
// $gt: 查找 age 大于 25 的文档
db.collection.find({ "age": { "$gt": 25 } })
// $gte: 查找 age 大于等于 25 的文档
db.collection.find({ "age": { "$gte": 25 } })
// $lt: 查找 age 小于 25 的文档
db.collection.find({ "age": { "$lt": 25 } })
// $lte: 查找 age 小于等于 25 的文档
db.collection.find({ "age": { "$lte": 25 } })
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 逻辑运算符
- $and(与)
- $or(或)
- $not(非)
- $nor(或非)
# 示例
// $and: 查找 age 大于 25 且 name 为 "John" 的文档
db.collection.find({
"$and": [
{ "age": { "$gt": 25 } },
{ "name": "John" }
]
})
// $or: 查找 age 大于 25 或 name 为 "John" 的文档
db.collection.find({
"$or": [
{ "age": { "$gt": 25 } },
{ "name": "John" }
]
})
// $not: 查找 age 不大于 25 的文档
db.collection.find({ "age": { "$not": { "$gt": 25 } } })
// $nor: 查找 age 不大于 25 且 name 不是 "John" 的文档
db.collection.find({
"$nor": [
{ "age": { "$gt": 25 } },
{ "name": "John" }
]
})
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
# 元素运算符
- $exists(存在)
- $type(类型)
# 示例
// $exists: 查找包含 age 字段的文档
db.collection.find({ "age": { "$exists": true } })
// $type: 查找 age 字段类型为整型的文档
db.collection.find({ "age": { "$type": "int" } })
2
3
4
5
# 数组运算符
- $all(全部匹配)
- $elemMatch(元素匹配)
- $size(数组长度)
# 示例
// $all: 查找 tags 数组包含 "red" 和 "blue" 的文档
db.collection.find({ "tags": { "$all": ["red", "blue"] } })
// $elemMatch: 查找 ratings 数组中至少有一个元素满足 score 大于 8 且 votes 大于 100 的文档
db.collection.find({
"ratings": { "$elemMatch": { "score": { "$gt": 8 }, "votes": { "$gt": 100 } } }
})
// $size: 查找 tags 数组长度为 3 的文档
db.collection.find({ "tags": { "$size": 3 } })
2
3
4
5
6
7
8
9
10
# 评估运算符
- $regex(正则表达式)
- $mod(取模运算)
- $text(文本搜索)
- $where(JavaScript 表达式)
# 示例
// $regex: 查找 name 包含 "John" 的文档
db.collection.find({ "name": { "$regex": "John", "$options": "i" } })
// $mod: 查找 age 对 5 取模结果为 0 的文档
db.collection.find({ "age": { "$mod": [5, 0] } })
// $text: 查找包含 "coffee" 词的文档(需要在 name 字段上创建文本索引)
db.collection.createIndex({ "name": "text" })
db.collection.find({ "$text": { "$search": "coffee" } })
// $where: 查找 age 大于 25 的文档(使用 JavaScript 表达式)
db.collection.find({ "$where": "this.age > 25" })
2
3
4
5
6
7
8
9
10
11
12
# 聚合查询
# $match
- 作用:过滤文档,以匹配指定的条件。
- 参数:条件对象。
- 示例:
db.collection.aggregate([ { $match: { status: "shipped" } } ]);
1
2
3status: "shipped"
:只保留status
字段值为"shipped"
的文档。
# $group
- 作用:将文档分组,以便对每个分组执行聚合操作。
- 参数:分组条件和聚合操作。
- 示例:
db.collection.aggregate([ { $group: { _id: "$customerId", totalAmount: { $sum: "$amount" } } } ]);
1
2
3_id: "$customerId"
:按customerId
字段进行分组。totalAmount: { $sum: "$amount" }
:计算每个分组内amount
字段的总和。
# $project
- 作用:修改文档的结构,可以包含、排除、重命名、创建计算字段等。
- 参数:字段操作对象。
- 示例:
db.collection.aggregate([ { $project: { customerId: 1, orderAmount: "$amount" } } ]);
1
2
3customerId: 1
:保留customerId
字段。orderAmount: "$amount"
:将amount
字段重命名为orderAmount
。
# $sort
- 作用:对文档进行排序。
- 参数:排序条件对象。
- 示例:
db.collection.aggregate([ { $sort: { orderDate: -1 } } ]);
1
2
3orderDate: -1
:按orderDate
字段降序排序。
# $limit
- 作用:限制结果集的数量。
- 参数:数量。
- 示例:
db.collection.aggregate([ { $limit: 10 } ]);
1
2
310
:只返回前 10 条文档。
# $unwind
- 作用:将数组字段拆分为多条文档,每个文档包含数组中的一个元素。
- 参数:数组字段。
- 示例:
db.collection.aggregate([ { $unwind: "$items" } ]);
1
2
3"$items"
:将items
数组中的每个元素作为单独的文档。
# 统计查询
# 计数(countDocuments)
- 作用:统计符合条件的文档数量。
- 参数:条件对象。
- 示例:
db.collection.countDocuments({ status: "shipped" });
1{ status: "shipped" }
:统计status
字段值为"shipped"
的文档数量。
# 求和($sum)
- 作用:计算数值字段的总和。
- 参数:要计算和的字段。
- 示例:
db.collection.aggregate([ { $group: { _id: null, totalAmount: { $sum: "$amount" } } } ]);
1
2
3_id: null
:不分组,聚合所有文档。totalAmount: { $sum: "$amount" }
:计算所有文档中amount
字段的总和。
# 平均值($avg)
- 作用:计算数值字段的平均值。
- 参数:要计算平均值的字段。
- 示例:
db.collection.aggregate([ { $group: { _id: null, averageAmount: { $avg: "$amount" } } } ]);
1
2
3_id: null
:不分组,聚合所有文档。averageAmount: { $avg: "$amount" }
:计算所有文档中amount
字段的平均值。
# 最大值($max)和最小值($min)
- 作用:找到数值字段的最大值和最小值。
- 参数:要计算最大值或最小值的字段。
- 示例:
db.collection.aggregate([ { $group: { _id: null, maxAmount: { $max: "$amount" }, minAmount: { $min: "$amount" } } } ]);
1
2
3_id: null
:不分组,聚合所有文档。maxAmount: { $max: "$amount" }
:找到所有文档中amount
字段的最大值。minAmount: { $min: "$amount" }
:找到所有文档中amount
字段的最小值。
# 标准差($stdDevPop 和 $stdDevSamp)
- 作用:计算数值字段的标准差。
- 参数:要计算标准差的字段。
- 示例:
db.collection.aggregate([ { $group: { _id: null, stdDev: { $stdDevPop: "$amount" } } } ]);
1
2
3_id: null
:不分组,聚合所有文档。stdDev: { $stdDevPop: "$amount" }
:计算所有文档中amount
字段的总体标准差。
# 综合示例解析
以下是一个综合示例的详细解析:
db.collection.aggregate([
{ $match: { status: "shipped" } }, // 过滤已发货的订单
{ $group: {
_id: "$customerId",
totalAmount: { $sum: "$amount" }, // 计算每个客户的订单总金额
averageAmount: { $avg: "$amount" }, // 计算每个客户的订单平均金额
maxAmount: { $max: "$amount" }, // 找出每个客户的最大订单金额
minAmount: { $min: "$amount" } // 找出每个客户的最小订单金额
} },
{ $sort: { totalAmount: -1 } }, // 按总金额降序排序
{ $limit: 10 } // 只返回前10名客户
]);
2
3
4
5
6
7
8
9
10
11
12
$match:
{ status: "shipped" }
:过滤条件,只保留status
为"shipped"
的订单。
$group:
_id: "$customerId"
:按customerId
字段分组。totalAmount: { $sum: "$amount" }
:计算每个客户订单的总金额。averageAmount: { $avg: "$amount" }
:计算每个客户订单的平均金额。maxAmount: { $max: "$amount" }
:找到每个客户的最大订单金额。minAmount: { $min: "$amount" }
:找到每个客户的最小订单金额。
$sort:
{ totalAmount: -1 }
:按totalAmount
降序排序。
$limit:
10
:只返回前 10 名客户。
# 2.MongoDB和Mysql进行查询操作的等效实现
# 数据准备
假设我们有以下表和集合:
MySQL 表:users
CREATE TABLE users ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50), age INT, city VARCHAR(50) );
1
2
3
4
5
6MongoDB 集合:users
db.users.insertMany([ { name: "Alice", age: 25, city: "New York" }, { name: "Bob", age: 30, city: "Los Angeles" }, { name: "Charlie", age: 35, city: "Chicago" } ]);
1
2
3
4
5
# 查询操作对比
# 1. 查询所有数据
MySQL
SELECT * FROM users;
1MongoDB
db.users.find({});
1
# 2. 条件查询
MySQL:查询年龄大于 25 的用户
SELECT * FROM users WHERE age > 25;
1MongoDB
db.users.find({ age: { $gt: 25 } });
1
# 3. 多条件查询
MySQL:查询年龄大于 25 且城市为 "New York" 的用户
SELECT * FROM users WHERE age > 25 AND city = 'New York';
1MongoDB
db.users.find({ age: { $gt: 25 }, city: "New York" });
1
# 4. IN 查询
MySQL:查询年龄为 25 或 30 的用户
SELECT * FROM users WHERE age IN (25, 30);
1MongoDB
db.users.find({ age: { $in: [25, 30] } });
1
# 5. OR 查询
MySQL:查询年龄小于 25 或城市为 "Los Angeles" 的用户
SELECT * FROM users WHERE age < 25 OR city = 'Los Angeles';
1MongoDB
db.users.find({ $or: [{ age: { $lt: 25 } }, { city: "Los Angeles" }] });
1
# 6. 计数查询
MySQL:统计用户数量
SELECT COUNT(*) FROM users;
1MongoDB
db.users.countDocuments({});
1
# 7. 排序查询
MySQL:按年龄降序排序
SELECT * FROM users ORDER BY age DESC;
1MongoDB
db.users.find({}).sort({ age: -1 });
1
# 8. 分页查询
MySQL:查询第 2 页,每页 10 条记录
SELECT * FROM users LIMIT 10 OFFSET 10;
1MongoDB
db.users.find({}).skip(10).limit(10);
1
# 9. 聚合查询
MySQL:按城市分组,计算每个城市的用户数量
SELECT city, COUNT(*) FROM users GROUP BY city;
1MongoDB
db.users.aggregate([ { $group: { _id: "$city", count: { $sum: 1 } } } ]);
1
2
3
# 10. 文本搜索
MySQL:查询名称包含 "Al" 的用户
SELECT * FROM users WHERE name LIKE '%Al%';
1MongoDB
db.users.find({ name: { $regex: /Al/ } });
1
# 11.指定字段查询
db.member_download.find({
"$and": [{
"member_id": 2
}, {
"deleted_at": 0
}]
},{mid:"$member_id"})
# 综合示例
假设我们需要一个综合查询操作,以下是一个示例对比:
# MySQL 综合查询
- 查询年龄大于 25 且城市为 "New York" 的用户。
- 按年龄降序排序。
- 取前 5 条记录。
SELECT * FROM users WHERE age > 25 AND city = 'New York' ORDER BY age DESC LIMIT 5;
# MongoDB 综合查询
- 查询年龄大于 25 且城市为 "New York" 的用户。
- 按年龄降序排序。
- 取前 5 条记录。
db.users.find({ age: { $gt: 25 }, city: "New York" }).sort({ age: -1 }).limit(5);
# 总结
通过上述对比,可以看到 MySQL 和 MongoDB 在常见查询操作上的相似之处和不同点。MongoDB 提供了灵活的文档型数据模型和丰富的查询运算符,适合处理各种复杂查询和聚合操作。而 MySQL 则以其标准化的 SQL 语言和关系型数据模型广泛应用于各种传统业务系统中。选择哪种数据库取决于具体的业务需求和数据结构。
# 3.mongo查询中什么时候需要加上$符号
# 1. 运算符(Operators)
MongoDB 使用 $
符号来表示各种查询运算符,例如比较运算符、逻辑运算符、元素运算符等。
# 比较运算符
- 示例:查询
age
大于 30 的文档db.collection.find({ age: { $gt: 30 } });
1$gt
:大于- 其他比较运算符包括
$lt
(小于)、$gte
(大于等于)、$lte
(小于等于)、$ne
(不等于)、$eq
(等于)
# 逻辑运算符
- 示例:查询
status
为 "A" 或age
大于 30 的文档db.collection.find({ $or: [ { status: "A" }, { age: { $gt: 30 } } ] });
1$or
:或- 其他逻辑运算符包括
$and
(与)、$not
(非)、$nor
(非或)
# 元素运算符
- 示例:查询存在
email
字段的文档db.collection.find({ email: { $exists: true } });
1$exists
:字段存在- 其他元素运算符包括
$type
(字段类型)
# 2. 数组运算符
MongoDB 提供了一些数组运算符,用于查询和操作数组字段。
# 查询数组中包含特定值的文档
- 示例:查询
tags
数组中包含 "fruit" 的文档db.collection.find({ tags: "fruit" });
1
# 查询数组中包含所有指定值的文档
- 示例:查询
tags
数组中同时包含 "fruit" 和 "food" 的文档db.collection.find({ tags: { $all: ["fruit", "food"] } });
1$all
:数组包含所有指定值
# 查询数组中满足指定条件的文档
- 示例:查询
grades
数组中包含grade
大于 90 的文档db.collection.find({ grades: { $elemMatch: { grade: { $gt: 90 } } } });
1$elemMatch
:数组中至少有一个元素满足条件
# 3. 聚合操作符
在聚合管道中,MongoDB 使用 $
符号表示各种聚合操作符,例如 $match
、$group
、$project
等。
# 示例:使用 $match
过滤文档
db.collection.aggregate([
{ $match: { status: "A" } }
]);
2
3
$match
:过滤文档- 其他聚合操作符包括
$group
(分组)、$project
(投影)、$sort
(排序)
# 4. 字段更新操作符
在更新操作中,使用 $
符号表示各种更新操作符,例如 $set
、$unset
、$inc
等。
# 示例:使用 $set
更新字段
db.collection.updateOne(
{ _id: 1 },
{ $set: { status: "B" } }
);
2
3
4
$set
:更新字段- 其他更新操作符包括
$unset
(删除字段)、$inc
(递增)
# 5. 数组更新操作符
在更新数组中的特定元素时,使用 $
符号来表示各种数组更新操作符,例如 $push
、$pull
、$addToSet
等。
# 示例:使用 $push
添加元素到数组
db.collection.updateOne(
{ _id: 1 },
{ $push: { tags: "new_tag" } }
);
2
3
4
$push
:添加元素到数组- 其他数组更新操作符包括
$pull
(从数组中删除元素)、$addToSet
(添加唯一元素到数组)
# 6. 更新嵌套数组中的元素
当你需要更新数组中的特定元素时,必须使用 $
操作符来指定哪个元素要更新。
# 示例:更新数组中第一个匹配条件的元素
- 文档结构:
{ "_id": 1, "grades": [ { "grade": 80, "score": 1 }, { "grade": 90, "score": 2 } ] }
1
2
3
4
5
6
7 - 更新
grades
数组中grade
为 80 的元素:db.collection.updateOne( { _id: 1, "grades.grade": 80 }, { $set: { "grades.$.score": 10 } } );
1
2
3
4grades.$.score
:使用$
符号表示更新匹配的数组元素
# 总结
在 MongoDB 查询和更新操作中,$
符号被广泛用于表示各种运算符、数组操作、聚合操作以及字段更新操作。了解这些运算符和它们的使用场景,可以有效地提高查询和更新操作的效率和灵活性。
在 MongoDB 中,更新数据的方法非常灵活和多样,适用于各种不同的更新需求。以下是几种常用的更新数据的方式,以及每种方式的示例。
# 4.更新数据
# updateOne
updateOne
用于更新集合中匹配查询条件的第一条文档。
示例:
db.collection.updateOne(
{ "age": { $lt: 25 } }, // 查询条件
{ $set: { "status": 10 } } // 更新操作
)
2
3
4
# updateMany
updateMany
用于更新集合中所有匹配查询条件的文档。
示例:
db.collection.updateMany(
{ "age": { $lt: 25 } }, // 查询条件
{ $set: { "status": 10 } } // 更新操作
)
2
3
4
# 2. 使用 replaceOne
replaceOne
用于替换集合中匹配查询条件的第一条文档,替换整个文档而不是部分更新。
示例:
db.collection.replaceOne(
{ "name": "Alice" }, // 查询条件
{ "name": "Alice", "age": 30, "status": 1 } // 新文档
)
2
3
4
# 3. 使用 $set
$set
用于将指定字段设置为指定值。如果字段不存在,它会被添加到文档中。
示例:
db.collection.updateOne(
{ "name": "Bob" }, // 查询条件
{ $set: { "age": 27, "status": 1 } } // 更新操作
)
2
3
4
# 4. 使用 $unset
$unset
用于删除指定字段,
tips:即使要删除的字段不存在也不会报错
示例:
db.collection.updateMany(
{
age: {
$lt: 25
}
},
{
$set: {
status: 1001,
},
$unset: {
age:
}
}
)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 5. 使用 $inc
$inc
用于增加或减少指定字段的值。
示例:
db.collection.updateOne(
{ "name": "David" }, // 查询条件
{ $inc: { "age": 1 } } // 增加 age 字段的值
)
2
3
4
# 6. 使用 $push
$push
用于向数组字段中添加一个或多个元素。
示例:
db.collection.updateOne(
{ "name": "Alice" }, // 查询条件
{ $push: { "hobbies": "cooking" } } // 向 hobbies 数组中添加一个元素
)
2
3
4
# 7. 使用 $addToSet
$addToSet
用于向数组字段中添加一个元素,只有在该元素不存在时才添加。
示例:
db.collection.updateOne(
{ "name": "Bob" }, // 查询条件
{ $addToSet: { "hobbies": "traveling" } } // 向 hobbies 数组中添加一个元素
)
2
3
4
# 8. 使用 $pull
$pull
用于从数组字段中删除匹配条件的所有元素。
示例:
db.collection.updateOne(
{ "name": "Charlie" }, // 查询条件
{ $pull: { "hobbies": "reading" } } // 从 hobbies 数组中删除匹配的元素
)
2
3
4
# 9. 使用 $pop
$pop
用于从数组字段中删除第一个或最后一个元素。
示例:
- 删除第一个元素:
db.collection.updateOne(
{ "name": "David" }, // 查询条件
{ $pop: { "hobbies": -1 } } // 删除第一个元素
)
2
3
4
- 删除最后一个元素:
db.collection.updateOne(
{ "name": "David" }, // 查询条件
{ $pop: { "hobbies": 1 } } // 删除最后一个元素
)
2
3
4
# 10. 使用 $rename
$rename
用于重命名字段。
tips:只有集合中的所有数据全部可以改时候才可以
示例:
db.collection.updateOne(
{ "name": "Alice" }, // 查询条件
{ $rename: { "status": "state" } } // 将 status 字段重命名为 state
)
2
3
4
# 总结
MongoDB 提供了丰富的更新操作符和方法,可以满足各种不同的更新需求。通过组合使用这些操作符和方法,可以高效地对文档进行部分或整体更新。了解和熟练掌握这些更新操作符和方法,可以帮助你更好地管理和操作 MongoDB 数据库。
# 删除数据
MongoDB 中删除数据可以使用 deleteOne()
、deleteMany()
和 findOneAndDelete()
方法。
# 1. deleteOne()
用于删除符合条件的第一个文档。
- 示例:删除
name
字段为 "John" 的文档。db.collection.deleteOne({ name: "John" });
1
# 2. deleteMany()
用于删除所有符合条件的文档。
- 示例:删除
age
大于 30 的所有文档。db.collection.deleteMany({ age: { $gt: 30 } });
1
# 3. findOneAndDelete()
用于查找符合条件的第一个文档并进行删除,返回删除前的文档或删除后的文档。
- 示例:查找并删除
name
字段为 "Alice" 的文档。db.collection.findOneAndDelete({ name: "Alice" });
1
# 注意事项:
- 删除操作会永久移除数据,务必谨慎操作,特别是在生产环境中。
findOneAndDelete()
返回的文档可以根据需求选择是否返回删除后的文档。
# 总结
MongoDB 提供了丰富的方法来更新和删除数据,可以根据具体需求选择合适的方法。使用适当的查询条件和更新/删除操作符可以高效地管理和维护数据。
# 500万条数据快速生成脚本
// 连接到数据库
use cms
// 获取集合
var collection = db.user;
// 定义生成随机数据的函数
function generateRandomData() {
return {
name: "User" + Math.floor(Math.random() * 1000000),
age: Math.floor(Math.random() * 53) + 18, // 年龄在 18 到 70 之间
createdAt: new Date(Date.now() - Math.floor(Math.random() * 365 * 24 * 60 * 60 * 1000)), // 随机日期在过去一年内
tags: Array.from({length: Math.floor(Math.random() * 5) + 1}, () => "tag" + Math.floor(Math.random() * 10) + 1)
};
}
// 批量插入数据
var bulk = collection.initializeUnorderedBulkOp();
var batchSize = 10000; // 每批插入的文档数
var totalRecords = 5000000;
for (var i = 0; i < totalRecords; i++) {
bulk.insert(generateRandomData());
if (i > 0 && i % batchSize === 0) {
bulk.execute();
bulk = collection.initializeUnorderedBulkOp();
print("Inserted " + i + " records");
}
}
// 插入最后一批数据
if (i % batchSize !== 0) {
bulk.execute();
print("Inserted " + i + " records");
}
print("Data generation complete");
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
29
30
31
32
33
34
35
36
37
38
39