PHP操作MongoDB(Legacy Driver)核心用法详解

夏知夏
夏知夏
发布时间:2026-10-14 | 4人浏览过
原创

本文深入解析利用PHP旧版驱动(mongo扩展)操作MongoDB数据库的技术细节。内容涵盖从建立连接、选择集合,到执行插入、更新、删除和查询等核心数据的完整流程,重点讲解$set、$inc等操作符的使用场景及数据结构的差异对比。

连接与基础配置

MongoDB的连接字符串遵循 mongodb://用户名:密码@地址:端口/数据库名 的标准格式。在初始化 Mongo 类时,可根据需要传递主机地址或完整的URI。

  • 本地默认连接: $conn = new Mongo(); 默认连接本机127.0.0.1及标准端口27017。
  • 指定主机或端口: 例如 $conn = new Mongo("xiaocai.loc:10086");。
  • 带认证连接: $conn = new Mongo("mongodb://sa:123@localhost/test");。
  • 高级选项: 可传入数组参数配置负载均衡 ("replicaSet" => true)、持久连接 ("persist" => "p") 或超时设置。

选择数据库与集合

MongoDB具有惰性创建特性:如果指定的数据库或集合(Collection)不存在,在执行写入操作时会自动创建。这要求开发者在编写代码时注意名称拼写,以免意外生成新的命名空间。

$db = $conn->mydb; // 选择数据库
$collection = $db->column; // 选择集合(相当于关系型数据库中的表)
// 也可以直接链式调用:$collection = $conn->mydb->column;

文档插入操作 (Insert)

向集合中插入数据使用 insert() 方法。MongoDB会自动为每条记录分配一个唯一的 _id 字段(ObjectId),无需手动指定主键。

第1步:普通插入

适用于大多数非关键业务场景,返回布尔值指示是否成功。

$array = ['column_name' => 'col123', 'column_exp' => 'xiaocai'];
$result = $collection->insert($array);
// 插入成功后,原数组会自动追加 '_id' 字段
$collection->insert(['test' => 'data']); 

第2步:安全写入模式

当需要将返回结果作为后续判断依据时,建议启用安全模式(第二个参数设为 true)。这会等待服务端确认写入完成,并返回包含状态信息的数组。

// insert(数组, array('safe' => true))
// 返回值示例: 
// ['err' => NULL, 'n' => 1, 'ok' => 1.0]
$result = $collection->insert($array, true); 

并发冲突处理: 插入具有唯一约束的数据(如自定义ID或业务主键)时,若重复提交会触发异常。应配合 try...catch(MongoCursorException) 捕获错误,防止程序崩溃。

文档更新与修改器 (Update)

更新是MongoDB操作中最常用的动作之一。需区分替换整个文档和使用修改器部分更新两种策略。

第3步:使用修改器 ($set, $inc, $unset)

这是推荐的更新方式,只修改符合条件的特定字段,保留其他原有数据。

  • $set: 将指定字段设置为给定值。若字段不存在则新建,存在则覆盖。
    $collection->update(
        ['column_name' => 'col123'], // 条件
        ['$set' => ['column_fid' => 444, 'new_field' => 'value']] // 新数据
    );
  • $inc: 数值自增或自减。用于计数器场景。
    // 将 age 字段减少 5
    $collection->update([], ['$inc' => ['age' => -5]]);
  • $unset: 彻底删除某个字段节点。
    $collection->update([], ['$unset' => ['old_field' => '']]);
  • 数组修改器: 包含 $push (追加), $pull (移除匹配元素), $addToSet (确保数组元素唯一) 等,详见下文聚合操作详解。

第4步:全量替换与批量更新

如果省略了修改器符号,直接将新数组作为第二个参数传入,服务器会将匹配的文档完全覆写掉(除了 _id 保持不变)。

// 注意:这里没有 $set 标记,旧数据被清空
$collection->update(['name' => 'test'], ['status' => 'active']); 

默认情况下,update() 仅影响第一条匹配的记录。若需批量更新所有符合条件项,需传入第三个参数:'multiple' => true。

文档删除 (Remove)

删除操作同样分为清除单条和清空集合:


// 1. 删除符合特定条件的文档
$collection->remove(['_id' => new MongoId('4d63...')]);

// 2. 清空当前集合中的所有数据(谨慎操作!
$collection->remove([]); 
// 或者不传参
$collection->remove();
风险提醒: 执行无条件的 remove() 前,请务必再次确认集合名称与数据备份情况,该操作不可逆且无回收站机制。

查询与游标控制 (Query & Cursor)

查询操作返回的是一个 MongoCursor 对象。游标具备动态性,如果在遍历期间底层数据发生变化,结果集可能随之改变。为确保一致性,可使用 snapshot() 锁定时刻。

第5步:构建查询条件

MongoDB支持丰富的比较操作符:

  • $gt, $gte: 大于 / 大于等于
  • $lt, $lte: 小于 / 小于等于
  • $ne: 不等于
  • $exists: 是否存在某字段 (true/false)
  • $in, $nin: 包含于 / 不包含于

// 查找 age > 50 且 <= 74 的记录
$where = [
    'age' => ['$gt' => 50, '$lte' => 74],
    'type' => ['$exists' => true] // 必须存在 type 字段
];
$cursor = $collection->find($where);

第6步:投影与排序过滤

  • 指定返回字段 (fields): 显式指定 1 显示,0 隐藏(注:旧版驱动逻辑,新版API有所变化)。
    // 不返回 age 和 type 字段
    $cursor = $collection->find()->fields(['age' => false, 'type' => false]);
  • 排序 (sort): 1 表示升序,-1 表示降序。顺序影响多级排序优先级。
    $collection->find()->sort(['age' => -1, 'created_at' => 1]);
  • 分页 (limit / skip):
    // 跳过前10条,取接下来5条
    $collection->find()->skip(10)->limit(5);

高级聚合操作指令参考

除了基础的CRUD,以下操作符常用于更新嵌套结构或数组:

指令作用示例说明
$push向数组末尾追加元素$push: { tags: 'new-tag' }
$addToSet向数组添加元素(去重)$addToSet: { tags: 'unique-tag' }
$pop移除数组首尾元素$pop: { items: 1 } (尾部), -1 (头部)
$pull按值删除数组内的元素$pull: { items: 'target-value' }

性能优化与索引管理

随着数据量增长,合理的索引设计至关重要。ensureIndex() 方法用于创建或获取现有索引。它可以在后台异步运行,以避免阻塞前台读写请求。


// 创建复合索引:按年龄升序,类型降序
$collection->ensureIndex(
    ['age' => 1, 'type' => -1],
    ['background' => true, 'unique' => false]
);
// 唯一索引可用于强制业务层面的唯一性约束
$collection->ensureIndex(['email' => 1], ['unique' => true]);
以上就是PHP操作MongoDB技术的详细内容,更多关于PHP MySQL数据库迁移或NoSQL应用实践的资料请关注本站其它相关文章!
相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表