赞
踩
本文所有的操作示例,都以集合“HistoryTaskBase”为例。
查询“通知时间”介于2019-09-01到2019-10-01之间的数据。
db.getCollection('HistoryTaskBase').find({notifyTime:{$gte:ISODate('2019-09-01T00:00:00.000Z'),$lte:ISODate('2019-10-01T00:00:00.000Z')}})
db.getCollection('HistoryTaskBase').find({notifyTime:{$lte:ISODate('2023-11-10T00:00:00.000Z')}}).count()
// 总记录数
39465
假设每页查询10条记录,分页查询第二页,语句见下:
db.getCollection('HistoryTaskBase').find({notifyTime:{$lte:ISODate('2023-11-10T00:00:00.000Z')}}).skip(10).limit(10)
db.getCollection('HistoryTaskBase').find({notifyTime:{$gte:ISODate('2019-09-01T00:00:00.000Z'),$lte:ISODate('2023-12-01T00:00:00.000Z')}}).sort({notifyTime:-1})
db.getCollection('HistoryTaskBase').find({notifyTime:{$gte:ISODate('2019-09-01T00:00:00.000Z'),$lte:ISODate('2023-12-01T00:00:00.000Z')}}).sort({notifyTime:-1})
先按schoolId升序,再是createdOn倒序
db.getCollection('xxx').find({}).sort({schoolId: 1, createdOn:-1});
totalIds 是一个数组类型,在查询包含关系的时候,使用In集合。
db.getCollection('xxx').find({"totalIds":{$in:[152290]}});
是in的相反操作,不存在于集合里。
db.getCollection('xxx').find({"classroomId":{$eq:"067JOE"}});
db.getCollection('xxx').find({"classroomId":{$ne:"067JOE"}});
像前文说的时间区间查询,就是使用大于小于的比较操作实现。因为都比较简单,就不一一举例了。
检查字段是否存在
db.getCollection('xxx').find({"classroomId":{$exists: true}})
不存在就是在上面语句的基础上取反。
// 查询记录中不存在字段classroomForm的文档
db.getCollection('ClassroomBase').find({"classroomForm":{$not: {$exists: true} }})
db.getCollection('xxx').find({"totalIds":{$size: 1}});
要查询数组desktopList下的数组taskList的taskId=“2ASS229CMY”
数据结构示例:
{ "_id":"5c6cfc303daedd4e40fe91f5", "userId":150908, "classroomId":"ZN41B3", "taskTotalNumber":5, "desktopList":[ { "desktopId":"IQZ5SN2R", "classId":0, "classMemNumber":0, "desktopType":0, "taskList":[ { "taskId":"2ASS229CMY", "taskType":1, "materialId":"ZQ9T1JCA2U" } ] } ] }
mongodb查询语句写法见下:
db.getCollection('xxx').find({
"desktopList": {
"$elemMatch": {
"taskList": {
"$elemMatch": {
"taskId": "2ASS229CMY"
}
}
}
}
});
示例:
查询userId=152408且schoolId=684的记录
db.getCollection('ClassroomBase').find(
{ $and: [ { "userId" : 152408 }, { "schoolId": 684 } ] }
);
// 等同于下面的语句
db.getCollection('ClassroomBase').find(
{ "userId" : 152408 , "schoolId": 684 }
);
查询userId=152408或schoolId=684的记录
db.getCollection('ClassroomBase').find(
{ $or: [ { "userId" : 152408 }, { "schoolId": 684 } ] }
);
db.getCollection('ClassroomBase').find(
{ $nor: [ { "userId" : 152408 }, { "schoolId": 684 } ] }
);
需要注意的是,它会查询出不包含该字段的文档。
语法各是:{ field: { $not: { } } },逻辑运算中,简单的取反。一般是针对单条件而言。
比如,查询语句见下:
db.getCollection('xxx').find(
{ schoolId: { $not: { $gt: 1000 } } }
);
它将查询出schoolId 不大于1000的记录,也会把schoolId为空的记录查询出来。
推荐使用这个,匹配到多少就删除多少条记录。
db.getCollection('HistoryTaskBase').deleteMany({notifyTime:{$gte:ISODate('2019-09-01T00:00:00.000Z'),$lte:ISODate('2019-10-01T00:00:00.000Z')}})
// 返回
{
"acknowledged" : true,
"deletedCount" : 3693.0
}
db.getCollection('xxx').deleteOne({"_id":"5c6cfc303daedd4e40fe91f4", "isDelete": true});
// 返回
{
"acknowledged" : true,
"deletedCount" : 0.0
}
与上一个操作语句不同,会返回删除前的文档。相同的是:都会删除该记录。
db.getCollection('xxx').findOneAndDelete({"classroomId":"ZN41B3"});
再次查询,则返回0条记录:
这意味着对于每个分组(每天的文档),都会创建一个包含唯一 totalIds 值的集合。
db.getCollection('xxx').aggregate([
{ $match : { createdOn:{$gte:ISODate('2023-11-20T00:00:00.000Z'),$lte:ISODate('2023-11-24T00:00:00.000Z')},isDelete:false } },
{
$group: {
_id: { day: { $dayOfYear: "$createdOn" } },
userIds : {$addToSet : "$totalIds"}
}
}
])
返回值
db.getCollection('xxx').aggregate([
{ $match : { createdOn:{$gte:ISODate('2023-11-20T00:00:00.000Z'),$lte:ISODate('2023-11-24T00:00:00.000Z')},isDelete:false } },
{
$group: {
_id: { day: { $dayOfYear: "$createdOn" } },
total: { $sum: 1 }
}
}
])
// 聚合结果
除了$sum外,还有最大、最小和平均等常用的函数。
{
$group: {
_id: "$field",
total: { $sum: 1 },
average: { $avg: "$numericField" },
max: { $max: "$numericField" },
min: { $min: "$numericField" }
}
}
本示例是查询订单,然后外关联商品表,主外键是productId。
db.orders.aggregate([
{
$lookup: {
from: "products",
localField: "productId",
foreignField: "_id",
as: "product"
}
},
{
$unwind: "$product" // 展开 product 数组
}
]);
{
"_id": 1,
"orderNumber": "NO123",
"productId": 101,
"quantity": 2
}
{
"_id": 101,
"productName": "商品名称",
"price": 1000
}
{
"_id": 1,
"orderNumber": "NO123",
"productId": 101,
"quantity": 2,
"product": {
"_id": 101,
"productName": "商品名称",
"price": 1000
}
}
在 MongoDB 的 shell 环境中,你可以使用 JavaScript 来编写条件语句。这里只列举几个作为示例。
多个集合的嵌套循环查询
// 查询各个课堂的人数和任务数
db.xxx.find({"isDelete": false}).forEach(function (doc) {
// 任务数
var taskSize = 0;
// 嵌套查询
db.Desktop.find({"classroomId": doc.classroomId}, {"desktopList": 1}).forEach(function(doc){
doc.desktopList.forEach(function(task) {
taskSize += task.taskList.length
})
}
);
print("老师ID:" + doc.userId + " 课堂ID:" + doc.classroomId + " 人数:" + doc.totalIds.length + " 任务数: " + taskSize)
输出查询结果
查询2022-12-25这一天上课的课堂ID列表
var classroomIds = new Array();
db.xxx.find({startTime:{$gte:ISODate('2022-12-25T00:00:00.000Z'),$lte:ISODate('2022-12-26T00:00:00.000Z')},isDelete:false}).forEach(function (doc) {
classroomIds.push(doc.classroomId);
})
// 输出课堂ID数组
print(classroomIds.length);
var x = 10;
if (x > 5) {
print("x 大于 5");
} else if (x === 5) {
print("x 等于 5");
} else {
print("x 小于 5");
}
var day = "Monday";
switch (day) {
case "Monday":
print("星期一");
break;
case "Tuesday":
print("星期二");
break;
// 其他 case 语句
default:
print("其他天");
}
var age = 20;
var message = (age >= 18) ? "成年人" : "未成年人";
print(message);
mongodb还有一些运维,比如定期备份、集群管理等,有空再整理。
mongodb的修改操作,也未在本文涉及。
本文侧重于mongodb的查询,说实话,查询才是最复杂的。
希望可以帮助到你,有空我再更新~~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。