前言
该文章主要介绍本人对mongodb的配置使用以及在php方面的运用。
参考文档:
MongoDB文档说明
MongoDB第三方类库
(1)MongoDB的配置安装
-
Windows系统 :
windows环境安装教程 -
Linux系统 :
linux环境安装教程
(2)配置文件信息说明

参数说明:
systemLog.destination:MongoDB 将所有日志输出发送到的目的地。指定 file或syslog。如果指定file,则还必须指定 systemLog.path。
systemLog.logAppend:当或 实例重新启动时true,将新条目附加到现有日志文件的末尾。如果没有此选项,将备份现有日志并创建一个新文件。
systemLog.path:MongoDB日志文件
storage.dbPath:MongoDB数据存储路径
storage.journal.enabled:启用或禁用持久性日志以确保数据文件保持有效和可恢复。此选项仅在指定 storage.dbPath设置时适用。mongod默认启用日记功能。
processManagement.fork:启用在后台运行或进程的守护程序模式。默认情况下或不作为守护程序运行:通常您将运行或作为守护程序,通过使用 或使用处理守护进程的控制进程
net.port:端口号
net.bindIp:绑定的ip地址,默认为本机;可通过设置值为0.0.0.0允许所有ip连接;
以上为MongoDB配置文件的简单配置,更多配置信息详情请查看:
MongoDB配置文件相关参数说明
(3)MongoDB相关概念解析
| MongDB术语 | 说明 |
|---|---|
| database | 数据库 |
| collection | 数据表 |
| document | 数据记录行/文档 |
| field | 数据字段/域 |
| index | 索引 |
(4)MongoDB类型
| 类型 | 说明 |
|---|---|
| Object ID | Documents 自生成的 _id |
| String | 字符串,必须是utf-8 |
| Boolean | 布尔值,true 或者false |
| Integer | 整型,Int32 Int64 |
| Double | 浮点数 (没有float类型,所有小数都是Double) |
| Arrays | 数组或者列表 |
| Object | 对象 |
| Null | 空数据类型 |
| Timestamp | 时间戳 |
| Decimal128 | BSON十进制128类型 |
(5)MongoDB的CRUD操作实例
1、写入数据
(1)写入单个文档
shell:
db.inventory.insertOne(
{ item: "canvas", qty: 100, tags: ["cotton"], size: { h: 28, w: 35.5, uom: "cm" } }
)
php:
$insertOneResult = $db->inventory->insertOne([
'item' => 'canvas',
'qty' => 100,
'tags' => ['cotton'],
'size' => ['h' => 28, 'w' => 35.5, 'uom' => 'cm'],
]);
(2)写入多个文档
shell:
db.inventory.insertMany([
{ item: "journal", qty: 25, tags: ["blank", "red"], size: { h: 14, w: 21, uom: "cm" } },
{ item: "mat", qty: 85, tags: ["gray"], size: { h: 27.9, w: 35.5, uom: "cm" } },
{ item: "mousepad", qty: 25, tags: ["gel", "blue"], size: { h: 19, w: 22.85, uom: "cm" } }
])
php:
$insertManyResult = $db->inventory->insertMany([
[
'item' => 'journal',
'qty' => 25,
'tags' => ['blank', 'red'],
'size' => ['h' => 14, 'w' => 21, 'uom' => 'cm'],
],
[
'item' => 'mat',
'qty' => 85,
'tags' => ['gray'],
'size' => ['h' => 27.9, 'w' => 35.5, 'uom' => 'cm'],
],
[
'item' => 'mousepad',
'qty' => 25,
'tags' => ['gel', 'blue'],
'size' => ['h' => 19, 'w' => 22.85, 'uom' => 'cm'],
],
]);
注意:
(1)当集合不存在时,写入操作会创建该集合;
(2)在 MongoDB 中,存储在集合中的每个文档都需要一个唯一的 _id字段作为主键。如果插入的文档省略了该_id字段,MongoDB 驱动程序会自动为该字段生成一个ObjectId_id。
2、查询
集合inventory中有如下数据
db.inventory.insertMany([
{ item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
{ item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A" },
{ item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
{ item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
{ item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" }
]);
| 方法 | 说明 |
|---|---|
| find() | 查询匹配的所有文档 |
| findOne() | 查询匹配的第一条文档 |
1)查询所有数据
shell:
db.inventory.find({})
php:
$cursor = $db->inventory->find([]);
2)指定相等条件
示例:从inventory集合中选择statusequals为"D"的所有文档。
shell:
db.inventory.find( { status: "D" } )
php:
$cursor = $db->inventory->find(['status' => 'D']);
3)使用查询运算符指定条件
示例:从inventory 集合中检索status等于"A"or"D"的所有文档
shell:
db.inventory.find( { status: { $in: [ "A", "D" ] } } )
php:
$cursor = $db->inventory->find(['status' => ['$in' => ['A', 'D']]]);
有关 MongoDB 查询运算符的完整列表,请参阅查询和投影运算符文档
4)指定AND条件
示例:检索inventory 集合中status等于"A" 和 qty小于30的所有文档
shell:
db.inventory.find( { status: "A", qty: { $lt: 30 } } )
php:
$cursor = $db->inventory->find([
'status' => 'A',
'qty' => ['$lt' => 30],
]);
有关其他 MongoDB 比较运算符,请参阅比较运算符
5)指定OR条件
示例:检索集合中status等于"A" 或 qty小于30的所有文档
shell:
db.inventory.find( { $or: [ { status: "A" }, { qty: { $lt: 30 } } ] } )
php:
$cursor = $db->inventory->find([
'$or' => [
['status' => 'A'],
['qty' => ['$lt' => 30]],
],
]);
6)指定AND以及OR条件
示例:复合查询文档选择集合中status等于"A" 且qty小于30或 item以字符p开头的所有文档
shell:
db.inventory.find( {
status: "A",
$or: [ { qty: { $lt: 30 } }, { item: /^p/ } ]
} )
php:
$cursor = $db->inventory->find([
'status' => 'A',
'$or' => [
['qty' => ['$lt' => 30]],
// Alternatively: ['item' => new \MongoDB\BSON\Regex('^p')]
['item' => ['$regex' => '^p']],
],
]);
7)查询嵌入/嵌套文档
集合inventory中有以下数据
db.inventory.insertMany( [
{ item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
{ item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A" },
{ item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
{ item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
{ item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" }
]);
示例1:
查询选择字段 size等于{ h: 14, w: 21, uom: “cm” } 的所有文档
shell:
db.inventory.find( { size: { h: 14, w: 21, uom: "cm" } } )
php:
$cursor = $db->inventory->find(['size' => ['h' => 14, 'w' => 21, 'uom' => 'cm']]);
示例2:查询size的uom字段为’in’的所有文档
shell:
db.inventory.find( { "size.uom": "in" } )
php:
$cursor = $db->inventory->find(['size.uom' => 'in']);
示例3:查询size的h字段小于15的所有文档
shell:
db.inventory.find( { "size.h": { $lt: 15 } } )
php:
$cursor = $db->inventory->find(['size.h' => ['$lt' => 15]]);
示例4:查询选择嵌套字段h小于15、嵌套字段uom等于"in"和status字段等于’D’的所有文档:
shell:
db.inventory.find( { "size.h": { $lt: 15 }, "size.uom": "in", status: "D" } )
php:
$cursor = $db->inventory->find([
'size.h' => ['$lt' => 15],
'size.uom' => 'in',
'status' => 'D',
]);
8)查询数组
集合inventory有如下数据
db.inventory.insertMany([
{ item: "journal", qty: 25, tags: ["blank", "red"], dim_cm: [ 14, 21 ] },
{ item: "notebook", qty: 50, tags: ["red", "blank"], dim_cm: [ 14, 21 ] },
{ item: "paper", qty: 100, tags: ["red", "blank", "plain"], dim_cm: [ 14, 21 ] },
{ item: "planner", qty: 75, tags: ["blank", "red"], dim_cm: [ 22.85, 30 ] },
{ item: "postcard", qty: 45, tags: ["blue"], dim_cm: [ 10, 15.25 ] }
]);
示例1:查询字段tags数组中,元素值顺序为"red"和"blank"的所有文档数。
shell:
db.inventory.find( { tags: ["red", "blank"] } )
php:
$cursor = $db->inventory->find(['tags' => ['red', 'blank']]);
示例2:查询数组tags中,包含了元素"red"和"blank"的文档(不考虑顺序和其他元素)
shell:
db.inventory.find( { tags: { $all: ["red", "blank"] } } )
php:
$cursor = $db->inventory->find(['tags' => ['$all' => ['red', 'blank']]]);
示例3:查询包含字符串"red"作为其元素之一tags的数组的所有文档
shell:
db.inventory.find( { tags: "red" } )
php:
$cursor = $db->inventory->find(['tags' => 'red']);
示例4:以下操作查询数组 dim_cm中至少包含一个元素值大于25的所有文档
shell:
db.inventory.find( { dim_cm: { $gt: 25 } } )
php:
$cursor = $db->inventory->find(['dim_cm' => ['$gt' => 25]]);
示例5:查询dim_cm数组包含以某种组合满足查询条件的元素的文档;例如,一个元素可以满足大于15 条件,另一个元素可以满足小于20 条件,或者单个元素可以同时满足这两个条件:
shell:
db.inventory.find( { dim_cm: { $gt: 15, $lt: 20 } } )
php:
$cursor = $db->inventory->find([
'dim_cm' => [
'$gt' => 15,
'$lt' => 20,
],
]);
示例6:查询dim_cm数组包含至少一个大于 ( $gt) 22和小于 ( $lt)30的元素的文档
shell:
db.inventory.find( { "dim_cm.1": { $gt: 25 } } )
php:
$cursor = $db->inventory->find([
'dim_cm' => [
'$elemMatch' => [
'$gt' => 22,
'$lt' => 30,
],
],
]);
示例7:查询数组中第二个元素dim_cm大于25的所有文档
shell:
db.inventory.find( { "dim_cm.1": { $gt: 25 } } )
php:
$cursor = $db->inventory->find(['dim_cm.1' => ['$gt' => 25]]);
示例8:查询数组 tags包含 3 个元素的文档
shell:
db.inventory.find( { "tags": { $size: 3 } } )
php:
$cursor = $db->inventory->find(['tags' => ['$size' => 3]]);
9)从查询返回想要的项目字段
集合inventory中有以下数据
db.inventory.insertMany( [
{ item: "journal", status: "A", size: { h: 14, w: 21, uom: "cm" }, instock: [ { warehouse: "A", qty: 5 } ] },
{ item: "notebook", status: "A", size: { h: 8.5, w: 11, uom: "in" }, instock: [ { warehouse: "C", qty: 5 } ] },
{ item: "paper", status: "D", size: { h: 8.5, w: 11, uom: "in" }, instock: [ { warehouse: "A", qty: 60 } ] },
{ item: "planner", status: "D", size: { h: 22.85, w: 30, uom: "cm" }, instock: [ { warehouse: "A", qty: 40 } ] },
{ item: "postcard", status: "A", size: { h: 10, w: 15.25, uom: "cm" }, instock: [ { warehouse: "B", qty: 15 }, { warehouse: "C", qty: 35 } ] }
]);
示例1:返回 inventory集合中其中status为 "A"的所有文档的所有字段
shell:
db.inventory.find( { status: "A" } )
php:
$cursor = $db->inventory->find(['status' => 'A']);
示例2:查询status等于"A"的所有文档的item和status字段
shell:
b.inventory.find( { status: "A" }, { item: 1, status: 1 } )
php:
$cursor = $db->inventory->find(
['status' => 'A'],
['projection' => ['item' => 1, 'status' => 1]]
);
示例3:抑制_id(查询结果不返回_id字段)
shell:
db.inventory.find( { status: "A" }, { item: 1, status: 1, _id: 0 } )
php:
$cursor = $db->inventory->find(
['status' => 'A'],
['projection' => ['item' => 1, 'status' => 1, '_id' => 0]]
);
示例4:返回匹配文档中除status和instock之外的所有字段
shell:
db.inventory.find( { status: "A" }, { status: 0, instock: 0 } )
php:
$cursor = $db->inventory->find(
['status' => 'A'],
['projection' => ['status' => 0, 'instock' => 0]]
);
10)查询空字符串或缺失字段
示例1:查询item值为null或者不包含item字段的文档。
shell:
db.inventory.find( { item: null } )
php:
$cursor = $db->inventory->find(['item' => null]);
示例2:查询仅匹配包含值为[ item => [ $type => 10 ] ]的字段的文档。
shell:
db.inventory.find( { item : { $type: 10 } } )
php:
$cursor = $db->inventory->find(['item' => ['$type' => 10]]);
注意:’$type’ => 10,10表示空类型null,详情请参考MongoDB $type 操作符
示例3:查询匹配不包含该item字段的文档
shell:
db.inventory.find( { item : { $exists: false } } )
php:
$cursor = $db->inventory->find(['item' => ['$exists' => false]]);
3、更新数据
更新方法有以下三种:
| 方法 | 说明 |
|---|---|
| updateOne() | 即使多个文档可能与指定的过滤器匹配,也最多更新与指定过滤器匹配的单个文档。详情 |
| updateMany() | 更新与指定过滤器匹配的所有文档。详情 |
| replaceOne() | 最多替换与指定过滤器匹配的单个文档,即使多个文档可能与指定过滤器匹配。详情 |
集合students中有以下数据
db.students.insertMany( [
{ _id: 1, test1: 95, test2: 92, test3: 90, modified: new Date("01/05/2020") },
{ _id: 2, test1: 98, test2: 100, test3: 102, modified: new Date("01/05/2020") },
{ _id: 3, test1: 95, test2: 110, modified: new Date("01/04/2020") }
] )
(1)$inc将某个字段加上一个数值
示例1:将_id=1文档的test1的值加1
db.students.updateOne({"_id":1}, {$inc:{"test1":1}})
示例2:将_id=1文档的test1的值减20
db.students.updateOne({"_id":1}, {$inc:{"test1":-20}})
(2)$set将某个字段更新为某个值,该字段不存在时增加字段
示例1:将_id=1的文档test3的值修改为20(test3不存在)
db.students.updateOne({"_id":1}, {$set:{"test3":20}})
(3)$unset删除某个字段
示例1:删除_id=1的文档的test1字段
db.students.updateOne({'_id':1}, {$unset:{'test1':1}})
(4)$push: 它是用来对Array (list)数据类型进行增加新元素的
(5)$pull:删除Array (list)数据类型的元素
(6)$pop : 指定删除Array中的第一个或最后一个元素
示例1:删除test_list的第一个元素
db.students.updateOne({'_id':1},{$pop:{'test_list':-1}})
删除test_list的最后一个元素
db.students.updateOne({'_id':1},{$pop:{'test_list':1}})
4、删除数据
MongoDB删除数据主要有两种方法:deleteMany()和deleteOne()
| 方法 | 说明 |
|---|---|
| deleteMany() | 删除匹配到的所有数据 |
| deleteOne() | 删除匹配到的第一条数据 |
有以下数据:
db.inventory.insertMany( [
{ item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
{ item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "P" },
{ item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
{ item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
{ item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" },
] );
示例1:删除集合中的所有文档
shell:
db.inventory.deleteMany({})
php:
$deleteResult = $db->inventory->deleteMany([]);
示例2:从inventory 集合中删除status字段等于"A"的所有文档
shell:
db.inventory.deleteMany({ status : "A" })
php:
$deleteResult = $db->inventory->deleteMany(['status' => 'A']);
示例3:删除匹配到的第一个文档
shell:
db.inventory.deleteOne( { status: "D" } )
php:
$deleteResult = $db->inventory->deleteOne(['status' => 'D']);
注意:如果集合中存在索引,则删除所有数据也不会删除存在的索引。
5、聚合查询(aggregate)
| 阶段 | 说明 |
|---|---|
| $match | 筛选 |
| $group | 分组 |
| $limit | 查询条数 |
| $skip | 从符合条件的文档的第几条开始获取数据 |
| $sort | 按照哪个字段排序 |
示例:查询status=0,并按uid分组统计num字段值的和。
shell:
db.user.aggregate( [
{
$match: { status: 0 }
},
{
$group: { _id: "$uid", totalQuantity: { $sum: "$num" } }
}
] )
php:
$data = $mongoModel->aggregate([
['$match' => ['status'=>0]],
['$group' => ['_id' => '$uid', 'totalQuantity' => ['$sum' => '$num']]],
])
说明:
(1)aggregate()为聚合方法;
(2)$match表示在聚合之前筛选出符合条件的文档;
(3)group表示按照什么条件分组;
(4)sum表示统计某个字段的和;
示例2:统计文档数
| 方法 | 说明 |
|---|---|
| estimatedDocumentCount() | 返回集合或视图中文档的近似计数。详情 |
| count() | 返回集合或视图中文档数的计数。 详情 |
| distinct() | 返回具有指定字段的不同值的文档数组。详情 |
注意:以上单一用途的聚合方法虽然很简单,但缺乏聚合管道的功能。
(6)索引
1)创建单一索引
示例1:给字段name创建索引,且为降序的顺序
db.collection.createIndex( { name: -1 } )
说明:-1表示降序,1表示升序。
2)创建复合索引
示例2:给字段name,age创建复合索引,其中name为降序,age为升序
db.collection.createIndex({name:-1,age:1})
3)查看集合col中所有的索引:
db.col.getIndexes();
4)删除集合col中某个索引
db.col.dropIndex("索引名称")
5)删除集合col所有的索引
db.col.dropIndexes()
6)查看索引的大小
db.col.totalIndexSize();
Till:hint()方法可指定查询的时候使用哪个索引去检索数据。
索引详细文档
本文档详述了MongoDB的配置安装、配置文件参数、基本概念,以及使用PHP进行CRUD操作的实例,包括查询、更新、删除数据,同时探讨了聚合查询和索引的创建与管理。
451

被折叠的 条评论
为什么被折叠?



