Appearance
Boolean类型
概述
Boolean(布尔)类型是MongoDB中最简单的数据类型,用于表示逻辑值:真(true)和假(false)。布尔类型在状态标识、条件判断、开关配置等场景中广泛应用,是构建逻辑控制的基础数据类型。
理解布尔类型的特性、存储机制和最佳实践,对于设计清晰的文档结构、优化查询性能和确保数据一致性至关重要。本章节将全面介绍MongoDB中布尔类型的使用方法和注意事项。
基本概念
Boolean类型特性
MongoDB的Boolean类型具有以下核心特性:
1. 二值逻辑
- 只有两个值:true 和 false
- 不支持 null 或 undefined 作为布尔值
- 明确的逻辑状态表示
2. 存储效率
- 占用1字节存储空间
- BSON类型标识符:0x08
- 高效的存储和查询性能
3. 类型转换
- 支持从其他类型转换为布尔值
- PHP驱动自动处理类型转换
- 查询时支持隐式类型转换
4. 查询优化
- 支持索引创建
- 高效的等值查询
- 常用于条件过滤
Boolean类型语法
php
<?php
// 场景说明:演示MongoDB Boolean类型的基本语法和使用方式
// 1. 连接MongoDB数据库
$client = new MongoDB\Client("mongodb://localhost:27017");
$database = $client->selectDatabase("testdb");
$collection = $database->selectCollection("boolean_examples");
// 2. 插入不同类型的布尔数据
$document = [
'is_active' => true, // 用户激活状态
'is_verified' => false, // 验证状态
'is_admin' => true, // 管理员标识
'has_permission' => false, // 权限标识
'is_published' => true, // 发布状态
'is_deleted' => false, // 删除标识
'is_featured' => true, // 推荐标识
'is_premium' => false // 高级会员标识
];
// 关键行注释:插入包含各种布尔值的文档
$result = $collection->insertOne($document);
echo "插入成功,文档ID: " . $result->getInsertedId() . "\n";
// 3. 布尔值查询操作
// 查询激活用户
$activeUsers = $collection->find(['is_active' => true])->toArray();
echo "激活用户数量: " . count($activeUsers) . "\n";
// 查询未验证用户
$unverifiedUsers = $collection->find(['is_verified' => false])->toArray();
echo "未验证用户数量: " . count($unverifiedUsers) . "\n";
// 查询管理员且已发布
$adminPublished = $collection->find([
'is_admin' => true,
'is_published' => true
])->toArray();
echo "管理员且已发布数量: " . count($adminPublished) . "\n";
// 4. 布尔值更新操作
// 激活用户
$collection->updateOne(
['is_active' => false],
['$set' => ['is_active' => true]]
);
echo "用户已激活\n";
// 运行结果展示:
// 插入成功,文档ID: 507f1f77bcf86cd799439011
// 激活用户数量: 1
// 未验证用户数量: 1
// 管理员且已发布数量: 1
// 用户已激活
?>常见改法对比:
php
<?php
// 错误示例:使用字符串表示布尔值
$collection->insertOne([
'is_active' => 'true', // 错误:字符串而非布尔值
'is_verified' => 'false' // 错误:字符串而非布尔值
]);
// 查询时会失败
$result = $collection->findOne(['is_active' => true]); // 查询不到
// 正确示例:使用真正的布尔值
$collection->insertOne([
'is_active' => true, // 正确:布尔值
'is_verified' => false // 正确:布尔值
]);
// 查询成功
$result = $collection->findOne(['is_active' => true]); // 查询成功
// 错误示例:使用整数表示布尔值
$collection->insertOne([
'is_active' => 1, // 错误:整数而非布尔值
'is_verified' => 0 // 错误:整数而非布尔值
]);
// 正确示例:类型转换后存储
$collection->insertOne([
'is_active' => (bool)1, // 正确:转换为布尔值
'is_verified' => (bool)0 // 正确:转换为布尔值
]);
?>Boolean类型规范
1. 命名规范
- 使用is_、has_、can_等前缀
- 名称应清晰表达布尔含义
- 避免使用否定词(如is_not_active)
2. 存储规范
- 统一使用true/false,不使用1/0
- 避免使用字符串"true"/"false"
- 保持字段类型一致性
3. 查询规范
- 直接使用布尔值查询
- 避免类型转换
- 为常用布尔字段创建索引
原理深度解析
Boolean存储机制
MongoDB使用BSON格式存储Boolean,存储结构简单高效:
存储结构:
[类型标识(1字节)] + [布尔值(1字节)]存储细节:
- 类型标识:0x08
- true值:0x01
- false值:0x00
- 总占用:2字节
php
<?php
// 场景说明:深入分析Boolean的存储机制和性能特性
class BooleanStorageAnalyzer {
private $database;
public function __construct($databaseName) {
$client = new MongoDB\Client("mongodb://localhost:27017");
$this->database = $client->selectDatabase($databaseName);
}
// 分析布尔值存储
public function analyzeBooleanStorage() {
$collection = $this->database->selectCollection('boolean_storage');
// 插入测试数据
$testCases = [
'true_value' => true,
'false_value' => false,
'multiple_true' => ['a' => true, 'b' => true, 'c' => true],
'multiple_false' => ['a' => false, 'b' => false, 'c' => false],
'mixed' => ['a' => true, 'b' => false, 'c' => true]
];
foreach ($testCases as $name => $value) {
$collection->insertOne([
'name' => $name,
'value' => $value,
'created_at' => new MongoDB\BSON\UTCDateTime()
]);
}
// 关键行注释:分析存储大小
$stats = $collection->stats();
return [
'document_count' => $collection->countDocuments(),
'storage_size' => $stats['size'],
'average_size' => $stats['size'] / $collection->countDocuments()
];
}
// 比较不同表示方式的存储效率
public function compareStorageEfficiency() {
$collection = $this->database->selectCollection('storage_comparison');
// 方法1:使用布尔值
$collection->insertOne([
'method' => 'boolean',
'value' => true,
'storage_bytes' => 2
]);
// 方法2:使用整数
$collection->insertOne([
'method' => 'integer',
'value' => 1,
'storage_bytes' => 4
]);
// 方法3:使用字符串
$collection->insertOne([
'method' => 'string',
'value' => 'true',
'storage_bytes' => 6
]);
return [
'boolean' => '2 bytes (最优)',
'integer' => '4 bytes',
'string' => '6+ bytes (最差)'
];
}
// 性能测试
public function performanceTest() {
$collection = $this->database->selectCollection('performance_test');
// 插入大量布尔数据
for ($i = 0; $i < 10000; $i++) {
$collection->insertOne([
'is_active' => (bool)($i % 2),
'is_verified' => (bool)($i % 3),
'index' => $i
]);
}
// 创建索引
$collection->createIndex(['is_active' => 1]);
// 测试查询性能
$startTime = microtime(true);
$results = $collection->find(['is_active' => true])->toArray();
$queryTime = microtime(true) - $startTime;
return [
'total_documents' => 10000,
'matching_documents' => count($results),
'query_time' => $queryTime,
'index_used' => true
];
}
}
// 使用示例
$analyzer = new BooleanStorageAnalyzer('testdb');
$storage = $analyzer->analyzeBooleanStorage();
print_r($storage);
$efficiency = $analyzer->compareStorageEfficiency();
print_r($efficiency);
$performance = $analyzer->performanceTest();
print_r($performance);
?>Boolean查询优化
php
<?php
// 场景说明:演示布尔值的查询优化技术
class BooleanQueryOptimizer {
private $database;
public function __construct($databaseName) {
$client = new MongoDB\Client("mongodb://localhost:27017");
$this->database = $client->selectDatabase($databaseName);
}
// 创建优化的索引
public function createOptimizedIndexes() {
$collection = $this->database->selectCollection('optimized_queries');
// 关键行注释:为布尔字段创建索引
$collection->createIndex(['is_active' => 1]);
$collection->createIndex(['is_verified' => 1, 'is_active' => 1]);
return ['indexes_created' => 2];
}
// 优化查询示例
public function optimizedQueries() {
$collection = $this->database->selectCollection('optimized_queries');
// 插入测试数据
for ($i = 0; $i < 1000; $i++) {
$collection->insertOne([
'user_id' => $i,
'is_active' => (bool)($i % 2),
'is_verified' => (bool)($i % 3),
'is_premium' => (bool)($i % 5)
]);
}
// 查询1:简单布尔查询
$query1Start = microtime(true);
$results1 = $collection->find(['is_active' => true])->toArray();
$query1Time = microtime(true) - $query1Start;
// 查询2:复合布尔查询
$query2Start = microtime(true);
$results2 = $collection->find([
'is_active' => true,
'is_verified' => true
])->toArray();
$query2Time = microtime(true) - $query2Start;
// 查询3:使用$or操作符
$query3Start = microtime(true);
$results3 = $collection->find([
'$or' => [
['is_active' => true],
['is_verified' => true]
]
])->toArray();
$query3Time = microtime(true) - $query3Start;
return [
'simple_query' => [
'count' => count($results1),
'time' => $query1Time
],
'compound_query' => [
'count' => count($results2),
'time' => $query2Time
],
'or_query' => [
'count' => count($results3),
'time' => $query3Time
]
];
}
// 聚合统计
public function booleanAggregation() {
$collection = $this->database->selectCollection('optimized_queries');
$pipeline = [
[
'$group' => [
'_id' => null,
'total_active' => [
'$sum' => ['$cond' => ['$is_active', 1, 0]]
],
'total_verified' => [
'$sum' => ['$cond' => ['$is_verified', 1, 0]]
],
'total_premium' => [
'$sum' => ['$cond' => ['$is_premium', 1, 0]]
]
]
]
];
return $collection->aggregate($pipeline)->toArray();
}
}
// 使用示例
$optimizer = new BooleanQueryOptimizer('testdb');
$optimizer->createOptimizedIndexes();
$results = $optimizer->optimizedQueries();
print_r($results);
$aggregation = $optimizer->booleanAggregation();
print_r($aggregation);
?>常见错误与踩坑点
错误1:类型混淆
错误表现:
- 使用字符串"true"/"false"代替布尔值
- 使用整数1/0代替布尔值
- 查询不到预期结果
产生原因:
- 未正确理解布尔类型
- 数据来源不一致
- 缺少类型验证
解决方案:
php
<?php
// 场景说明:演示布尔值类型混淆的正确处理
class BooleanTypeHandler {
private $database;
public function __construct($databaseName) {
$client = new MongoDB\Client("mongodb://localhost:27017");
$this->database = $client->selectDatabase($databaseName);
}
// 错误示例:类型混淆
public function wrongTypeExample() {
$collection = $this->database->selectCollection('wrong_type');
// 错误:使用字符串
$collection->insertOne([
'is_active' => 'true', // 字符串,不是布尔值
'is_verified' => 'false'
]);
// 查询失败
$result = $collection->findOne(['is_active' => true]);
if (!$result) {
echo "错误:类型不匹配导致查询失败\n";
}
// 错误:使用整数
$collection->insertOne([
'is_active' => 1, // 整数,不是布尔值
'is_verified' => 0
]);
// 查询失败
$result = $collection->findOne(['is_active' => true]);
if (!$result) {
echo "错误:整数与布尔值类型不匹配\n";
}
}
// 正确示例:统一使用布尔值
public function correctTypeExample() {
$collection = $this->database->selectCollection('correct_type');
// 正确:使用布尔值
$collection->insertOne([
'is_active' => true, // 布尔值
'is_verified' => false
]);
// 查询成功
$result = $collection->findOne(['is_active' => true]);
if ($result) {
echo "正确:类型匹配查询成功\n";
}
}
// 类型转换工具
public function ensureBoolean($value) {
if (is_bool($value)) {
return $value;
} elseif (is_string($value)) {
return filter_var($value, FILTER_VALIDATE_BOOLEAN);
} elseif (is_int($value)) {
return (bool)$value;
} elseif (is_null($value)) {
return false;
}
return (bool)$value;
}
// 批量转换
public function convertToBoolean($data, $fields) {
foreach ($fields as $field) {
if (isset($data[$field])) {
$data[$field] = $this->ensureBoolean($data[$field]);
}
}
return $data;
}
}
// 使用示例
$handler = new BooleanTypeHandler('testdb');
$handler->wrongTypeExample();
$handler->correctTypeExample();
// 类型转换
$boolValue = $handler->ensureBoolean('true');
echo "转换结果: " . ($boolValue ? 'true' : 'false') . "\n";
$data = [
'is_active' => 'yes',
'is_verified' => 1,
'is_premium' => 'false'
];
$converted = $handler->convertToBoolean($data, ['is_active', 'is_verified', 'is_premium']);
print_r($converted);
?>错误2:布尔字段命名不当
错误表现:
- 使用否定词命名(如is_not_active)
- 命名不清晰(如flag、status)
- 双重否定导致逻辑混乱
产生原因:
- 缺少命名规范
- 未考虑逻辑清晰性
- 历史遗留问题
解决方案:
php
<?php
// 场景说明:演示布尔字段命名的最佳实践
class BooleanNamingHandler {
private $database;
public function __construct($databaseName) {
$client = new MongoDB\Client("mongodb://localhost:27017");
$this->database = $client->selectDatabase($databaseName);
}
// 错误示例:命名不当
public function wrongNamingExample() {
$collection = $this->database->selectCollection('wrong_naming');
// 错误:使用否定词
$collection->insertOne([
'is_not_active' => false, // 双重否定,逻辑混乱
'is_not_deleted' => true, // 难以理解
'flag' => true, // 不清晰
'status' => false // 含义不明
]);
echo "错误:命名不当导致逻辑混乱\n";
}
// 正确示例:清晰的命名
public function correctNamingExample() {
$collection = $this->database->selectCollection('correct_naming');
// 正确:使用肯定词和清晰的前缀
$collection->insertOne([
'is_active' => true, // 清晰:是否激活
'is_deleted' => false, // 清晰:是否删除
'has_permission' => true, // 清晰:是否有权限
'can_edit' => true, // 清晰:是否能编辑
'should_notify' => false // 清晰:是否应通知
]);
echo "正确:命名清晰,逻辑明确\n";
}
// 命名建议
public function namingGuidelines() {
return [
'prefixes' => [
'is_' => '表示状态(如:is_active, is_published)',
'has_' => '表示拥有(如:has_permission, has_avatar)',
'can_' => '表示能力(如:can_edit, can_delete)',
'should_' => '表示建议(如:should_notify, should_archive)',
'was_' => '表示历史状态(如:was_processed, was_sent)'
],
'avoid' => [
'is_not_' => '避免否定词',
'flag' => '避免通用词',
'status' => '避免模糊词'
],
'examples' => [
'good' => ['is_active', 'has_permission', 'can_edit'],
'bad' => ['is_not_inactive', 'flag1', 'status_bool']
]
];
}
}
// 使用示例
$handler = new BooleanNamingHandler('testdb');
$handler->wrongNamingExample();
$handler->correctNamingExample();
$guidelines = $handler->namingGuidelines();
print_r($guidelines);
?>错误3:过度使用布尔字段
错误表现:
- 用多个布尔字段表示状态
- 布尔字段过多导致维护困难
- 状态逻辑复杂
产生原因:
- 设计不当
- 未考虑状态机
- 缺少重构
解决方案:
php
<?php
// 场景说明:演示布尔字段的合理使用
class BooleanDesignHandler {
private $database;
public function __construct($databaseName) {
$client = new MongoDB\Client("mongodb://localhost:27017");
$this->database = $client->selectDatabase($databaseName);
}
// 错误示例:过度使用布尔字段
public function wrongDesignExample() {
$collection = $this->database->selectCollection('wrong_design');
// 错误:用多个布尔字段表示状态
$collection->insertOne([
'is_draft' => false,
'is_published' => true,
'is_archived' => false,
'is_deleted' => false,
'is_pending' => false
]);
echo "错误:多个布尔字段表示状态,容易冲突\n";
}
// 正确示例:使用状态字段
public function correctDesignExample() {
$collection = $this->database->selectCollection('correct_design');
// 正确:使用单一状态字段
$collection->insertOne([
'status' => 'published', // draft, published, archived, deleted
'published_at' => new MongoDB\BSON\UTCDateTime()
]);
echo "正确:使用状态字段,逻辑清晰\n";
}
// 状态机设计
public function stateMachineDesign() {
$collection = $this->database->selectCollection('state_machine');
$states = [
'draft' => [
'can_transition_to' => ['published', 'deleted']
],
'published' => [
'can_transition_to' => ['archived', 'deleted']
],
'archived' => [
'can_transition_to' => ['published', 'deleted']
],
'deleted' => [
'can_transition_to' => []
]
];
return $states;
}
// 合理使用布尔字段的场景
public function appropriateUseCases() {
return [
'good_cases' => [
'is_active' => '用户激活状态',
'is_verified' => '邮箱验证状态',
'has_permission' => '权限标识',
'can_edit' => '编辑权限',
'is_featured' => '推荐标识'
],
'bad_cases' => [
'is_draft + is_published' => '应使用status字段',
'is_pending + is_approved' => '应使用workflow字段',
'is_active + is_inactive' => '冗余设计'
]
];
}
}
// 使用示例
$handler = new BooleanDesignHandler('testdb');
$handler->wrongDesignExample();
$handler->correctDesignExample();
$states = $handler->stateMachineDesign();
print_r($states);
$useCases = $handler->appropriateUseCases();
print_r($useCases);
?>常见应用场景
场景1:用户状态管理
场景描述:管理用户的激活、验证等状态。
使用方法:
- 使用布尔字段标识用户状态
- 创建索引提高查询性能
- 使用复合查询过滤用户
示例代码:
php
<?php
// 场景说明:用户状态管理系统
class UserStatusManager {
private $database;
public function __construct($databaseName) {
$client = new MongoDB\Client("mongodb://localhost:27017");
$this->database = $client->selectDatabase($databaseName);
}
// 初始化索引
public function initializeIndexes() {
$collection = $this->database->selectCollection('users');
// 关键行注释:为布尔字段创建索引
$collection->createIndex(['is_active' => 1]);
$collection->createIndex(['is_verified' => 1]);
$collection->createIndex(['is_active' => 1, 'is_verified' => 1]);
}
// 创建用户
public function createUser($userData) {
$collection = $this->database->selectCollection('users');
$user = [
'username' => $userData['username'],
'email' => $userData['email'],
'is_active' => false, // 默认未激活
'is_verified' => false, // 默认未验证
'is_admin' => false, // 默认非管理员
'is_premium' => false, // 默认非高级会员
'created_at' => new MongoDB\BSON\UTCDateTime()
];
$result = $collection->insertOne($user);
return (string)$result->getInsertedId();
}
// 激活用户
public function activateUser($userId) {
$collection = $this->database->selectCollection('users');
$result = $collection->updateOne(
['_id' => new MongoDB\BSON\ObjectId($userId)],
[
'$set' => [
'is_active' => true,
'activated_at' => new MongoDB\BSON\UTCDateTime()
]
]
);
return $result->getModifiedCount() > 0;
}
// 验证邮箱
public function verifyEmail($userId) {
$collection = $this->database->selectCollection('users');
$result = $collection->updateOne(
['_id' => new MongoDB\BSON\ObjectId($userId)],
[
'$set' => [
'is_verified' => true,
'verified_at' => new MongoDB\BSON\UTCDateTime()
]
]
);
return $result->getModifiedCount() > 0;
}
// 查询激活用户
public function getActiveUsers($limit = 10) {
$collection = $this->database->selectCollection('users');
return $collection->find(
['is_active' => true],
['limit' => $limit]
)->toArray();
}
// 查询激活且验证的用户
public function getActiveVerifiedUsers($limit = 10) {
$collection = $this->database->selectCollection('users');
return $collection->find(
[
'is_active' => true,
'is_verified' => true
],
['limit' => $limit]
)->toArray();
}
// 统计用户状态
public function getUserStats() {
$collection = $this->database->selectCollection('users');
$pipeline = [
[
'$group' => [
'_id' => null,
'total' => ['$sum' => 1],
'active' => ['$sum' => ['$cond' => ['$is_active', 1, 0]]],
'verified' => ['$sum' => ['$cond' => ['$is_verified', 1, 0]]],
'admin' => ['$sum' => ['$cond' => ['$is_admin', 1, 0]]]
]
]
];
return $collection->aggregate($pipeline)->toArray();
}
}
// 使用示例
$manager = new UserStatusManager('user_db');
$manager->initializeIndexes();
// 创建用户
$userId = $manager->createUser([
'username' => 'john_doe',
'email' => 'john@example.com'
]);
echo "用户ID: $userId\n";
// 激活用户
$manager->activateUser($userId);
echo "用户已激活\n";
// 验证邮箱
$manager->verifyEmail($userId);
echo "邮箱已验证\n";
// 查询用户
$activeUsers = $manager->getActiveUsers();
echo "激活用户数量: " . count($activeUsers) . "\n";
// 统计
$stats = $manager->getUserStats();
print_r($stats);
?>场景2:内容发布系统
场景描述:管理文章的发布、推荐等状态。
示例代码:
php
<?php
// 场景说明:内容发布系统
class ContentPublishingSystem {
private $database;
public function __construct($databaseName) {
$client = new MongoDB\Client("mongodb://localhost:27017");
$this->database = $client->selectDatabase($databaseName);
}
// 创建文章
public function createArticle($articleData) {
$collection = $this->database->selectCollection('articles');
$article = [
'title' => $articleData['title'],
'content' => $articleData['content'],
'author_id' => $articleData['author_id'],
'is_published' => false, // 默认未发布
'is_featured' => false, // 默认不推荐
'is_pinned' => false, // 默认不置顶
'is_commentable' => true, // 默认可评论
'created_at' => new MongoDB\BSON\UTCDateTime()
];
$result = $collection->insertOne($article);
return (string)$result->getInsertedId();
}
// 发布文章
public function publishArticle($articleId) {
$collection = $this->database->selectCollection('articles');
$result = $collection->updateOne(
['_id' => new MongoDB\BSON\ObjectId($articleId)],
[
'$set' => [
'is_published' => true,
'published_at' => new MongoDB\BSON\UTCDateTime()
]
]
);
return $result->getModifiedCount() > 0;
}
// 设置推荐
public function setFeatured($articleId, $featured = true) {
$collection = $this->database->selectCollection('articles');
$result = $collection->updateOne(
['_id' => new MongoDB\BSON\ObjectId($articleId)],
['$set' => ['is_featured' => $featured]]
);
return $result->getModifiedCount() > 0;
}
// 查询已发布文章
public function getPublishedArticles($limit = 10) {
$collection = $this->database->selectCollection('articles');
return $collection->find(
['is_published' => true],
[
'sort' => ['published_at' => -1],
'limit' => $limit
]
)->toArray();
}
// 查询推荐文章
public function getFeaturedArticles($limit = 5) {
$collection = $this->database->selectCollection('articles');
return $collection->find(
[
'is_published' => true,
'is_featured' => true
],
[
'sort' => ['published_at' => -1],
'limit' => $limit
]
)->toArray();
}
}
// 使用示例
$system = new ContentPublishingSystem('content_db');
// 创建文章
$articleId = $system->createArticle([
'title' => 'MongoDB Boolean Type Tutorial',
'content' => 'This is a tutorial about MongoDB boolean type...',
'author_id' => 'author_001'
]);
echo "文章ID: $articleId\n";
// 发布文章
$system->publishArticle($articleId);
echo "文章已发布\n";
// 设置推荐
$system->setFeatured($articleId, true);
echo "文章已推荐\n";
// 查询文章
$published = $system->getPublishedArticles();
echo "已发布文章数量: " . count($published) . "\n";
$featured = $system->getFeaturedArticles();
echo "推荐文章数量: " . count($featured) . "\n";
?>场景3:权限控制系统
场景描述:管理用户的权限和访问控制。
示例代码:
php
<?php
// 场景说明:权限控制系统
class PermissionControlSystem {
private $database;
public function __construct($databaseName) {
$client = new MongoDB\Client("mongodb://localhost:27017");
$this->database = $client->selectDatabase($databaseName);
}
// 创建用户权限
public function createUserPermissions($userId, $permissions) {
$collection = $this->database->selectCollection('user_permissions');
$doc = [
'user_id' => $userId,
'can_read' => $permissions['can_read'] ?? false,
'can_write' => $permissions['can_write'] ?? false,
'can_delete' => $permissions['can_delete'] ?? false,
'can_admin' => $permissions['can_admin'] ?? false,
'can_share' => $permissions['can_share'] ?? false,
'created_at' => new MongoDB\BSON\UTCDateTime()
];
$result = $collection->insertOne($doc);
return (string)$result->getInsertedId();
}
// 检查权限
public function hasPermission($userId, $permission) {
$collection = $this->database->selectCollection('user_permissions');
$result = $collection->findOne(['user_id' => $userId]);
if (!$result) {
return false;
}
return isset($result[$permission]) ? $result[$permission] : false;
}
// 授予权限
public function grantPermission($userId, $permission) {
$collection = $this->database->selectCollection('user_permissions');
$result = $collection->updateOne(
['user_id' => $userId],
['$set' => [$permission => true]]
);
return $result->getModifiedCount() > 0;
}
// 撤销权限
public function revokePermission($userId, $permission) {
$collection = $this->database->selectCollection('user_permissions');
$result = $collection->updateOne(
['user_id' => $userId],
['$set' => [$permission => false]]
);
return $result->getModifiedCount() > 0;
}
// 查询有特定权限的用户
public function getUsersWithPermission($permission) {
$collection = $this->database->selectCollection('user_permissions');
return $collection->find(
[$permission => true]
)->toArray();
}
}
// 使用示例
$system = new PermissionControlSystem('permission_db');
// 创建权限
$system->createUserPermissions('user_001', [
'can_read' => true,
'can_write' => true,
'can_delete' => false,
'can_admin' => false
]);
// 检查权限
$canWrite = $system->hasPermission('user_001', 'can_write');
echo "用户是否有写权限: " . ($canWrite ? '是' : '否') . "\n";
// 授予权限
$system->grantPermission('user_001', 'can_delete');
echo "已授予删除权限\n";
// 撤销权限
$system->revokePermission('user_001', 'can_write');
echo "已撤销写权限\n";
?>场景4:功能开关系统
场景描述:管理应用功能的开关状态。
示例代码:
php
<?php
// 场景说明:功能开关系统
class FeatureFlagSystem {
private $database;
public function __construct($databaseName) {
$client = new MongoDB\Client("mongodb://localhost:27017");
$this->database = $client->selectDatabase($databaseName);
}
// 创建功能开关
public function createFeatureFlag($name, $enabled = false) {
$collection = $this->database->selectCollection('feature_flags');
$flag = [
'name' => $name,
'is_enabled' => $enabled,
'created_at' => new MongoDB\BSON\UTCDateTime(),
'updated_at' => new MongoDB\BSON\UTCDateTime()
];
$result = $collection->insertOne($flag);
return (string)$result->getInsertedId();
}
// 检查功能是否启用
public function isFeatureEnabled($name) {
$collection = $this->database->selectCollection('feature_flags');
$result = $collection->findOne(['name' => $name]);
return $result ? $result['is_enabled'] : false;
}
// 启用功能
public function enableFeature($name) {
$collection = $this->database->selectCollection('feature_flags');
$result = $collection->updateOne(
['name' => $name],
[
'$set' => [
'is_enabled' => true,
'updated_at' => new MongoDB\BSON\UTCDateTime()
]
]
);
return $result->getModifiedCount() > 0;
}
// 禁用功能
public function disableFeature($name) {
$collection = $this->database->selectCollection('feature_flags');
$result = $collection->updateOne(
['name' => $name],
[
'$set' => [
'is_enabled' => false,
'updated_at' => new MongoDB\BSON\UTCDateTime()
]
]
);
return $result->getModifiedCount() > 0;
}
// 获取所有启用的功能
public function getEnabledFeatures() {
$collection = $this->database->selectCollection('feature_flags');
return $collection->find(
['is_enabled' => true]
)->toArray();
}
}
// 使用示例
$system = new FeatureFlagSystem('feature_db');
// 创建功能开关
$system->createFeatureFlag('new_dashboard', false);
$system->createFeatureFlag('dark_mode', true);
$system->createFeatureFlag('beta_features', false);
// 检查功能状态
$isEnabled = $system->isFeatureEnabled('dark_mode');
echo "暗黑模式是否启用: " . ($isEnabled ? '是' : '否') . "\n";
// 启用功能
$system->enableFeature('new_dashboard');
echo "新仪表板已启用\n";
// 禁用功能
$system->disableFeature('beta_features');
echo "测试功能已禁用\n";
// 获取所有启用的功能
$enabled = $system->getEnabledFeatures();
echo "启用的功能数量: " . count($enabled) . "\n";
?>场景5:通知设置系统
场景描述:管理用户的通知偏好设置。
示例代码:
php
<?php
// 场景说明:通知设置系统
class NotificationSettingsSystem {
private $database;
public function __construct($databaseName) {
$client = new MongoDB\Client("mongodb://localhost:27017");
$this->database = $client->selectDatabase($databaseName);
}
// 创建通知设置
public function createNotificationSettings($userId) {
$collection = $this->database->selectCollection('notification_settings');
$settings = [
'user_id' => $userId,
'email_enabled' => true,
'push_enabled' => true,
'sms_enabled' => false,
'marketing_enabled' => false,
'mentions_enabled' => true,
'comments_enabled' => true,
'created_at' => new MongoDB\BSON\UTCDateTime()
];
$result = $collection->insertOne($settings);
return (string)$result->getInsertedId();
}
// 更新通知设置
public function updateSettings($userId, $settings) {
$collection = $this->database->selectCollection('notification_settings');
$updateData = [];
foreach ($settings as $key => $value) {
if (in_array($key, ['email_enabled', 'push_enabled', 'sms_enabled',
'marketing_enabled', 'mentions_enabled', 'comments_enabled'])) {
$updateData[$key] = (bool)$value;
}
}
$result = $collection->updateOne(
['user_id' => $userId],
['$set' => $updateData]
);
return $result->getModifiedCount() > 0;
}
// 获取用户设置
public function getUserSettings($userId) {
$collection = $this->database->selectCollection('notification_settings');
return $collection->findOne(['user_id' => $userId]);
}
// 查询启用了特定通知的用户
public function getUsersWithNotificationEnabled($type) {
$collection = $this->database->selectCollection('notification_settings');
return $collection->find(
[$type . '_enabled' => true]
)->toArray();
}
}
// 使用示例
$system = new NotificationSettingsSystem('notification_db');
// 创建通知设置
$system->createNotificationSettings('user_001');
// 更新设置
$system->updateSettings('user_001', [
'email_enabled' => true,
'push_enabled' => false,
'marketing_enabled' => false
]);
// 获取设置
$settings = $system->getUserSettings('user_001');
print_r($settings);
// 查询启用了邮件通知的用户
$emailUsers = $system->getUsersWithNotificationEnabled('email');
echo "启用邮件通知的用户数量: " . count($emailUsers) . "\n";
?>企业级进阶应用场景
场景1:多维度权限系统
场景描述:实现复杂的多维度权限控制。
示例代码:
php
<?php
// 场景说明:多维度权限系统
class MultiDimensionalPermissionSystem {
private $database;
public function __construct($databaseName) {
$client = new MongoDB\Client("mongodb://localhost:27017");
$this->database = $client->selectDatabase($databaseName);
}
// 创建角色权限
public function createRolePermissions($roleName, $permissions) {
$collection = $this->database->selectCollection('role_permissions');
$doc = [
'role_name' => $roleName,
'permissions' => $permissions,
'created_at' => new MongoDB\BSON\UTCDateTime()
];
$result = $collection->insertOne($doc);
return (string)$result->getInsertedId();
}
// 检查权限
public function checkPermission($roleName, $resource, $action) {
$collection = $this->database->selectCollection('role_permissions');
$result = $collection->findOne(['role_name' => $roleName]);
if (!$result) {
return false;
}
$permissionKey = "can_{$action}_{$resource}";
return isset($result['permissions'][$permissionKey]) ?
$result['permissions'][$permissionKey] : false;
}
// 批量检查权限
public function checkMultiplePermissions($roleName, $permissionChecks) {
$results = [];
foreach ($permissionChecks as $check) {
$results[$check['resource'] . '_' . $check['action']] =
$this->checkPermission($roleName, $check['resource'], $check['action']);
}
return $results;
}
// 获取用户的所有权限
public function getUserPermissions($userId) {
$userCollection = $this->database->selectCollection('users');
$roleCollection = $this->database->selectCollection('role_permissions');
$user = $userCollection->findOne(['_id' => new MongoDB\BSON\ObjectId($userId)]);
if (!$user || !isset($user['roles'])) {
return [];
}
$allPermissions = [];
foreach ($user['roles'] as $roleName) {
$role = $roleCollection->findOne(['role_name' => $roleName]);
if ($role && isset($role['permissions'])) {
foreach ($role['permissions'] as $key => $value) {
if ($value) {
$allPermissions[$key] = true;
}
}
}
}
return $allPermissions;
}
}
// 使用示例
$system = new MultiDimensionalPermissionSystem('enterprise_db');
// 创建角色权限
$system->createRolePermissions('admin', [
'can_read_users' => true,
'can_write_users' => true,
'can_delete_users' => true,
'can_read_articles' => true,
'can_write_articles' => true,
'can_delete_articles' => true
]);
$system->createRolePermissions('editor', [
'can_read_users' => true,
'can_write_users' => false,
'can_delete_users' => false,
'can_read_articles' => true,
'can_write_articles' => true,
'can_delete_articles' => false
]);
// 检查权限
$canDelete = $system->checkPermission('admin', 'users', 'delete');
echo "管理员是否可以删除用户: " . ($canDelete ? '是' : '否') . "\n";
// 批量检查
$checks = $system->checkMultiplePermissions('editor', [
['resource' => 'users', 'action' => 'read'],
['resource' => 'users', 'action' => 'delete'],
['resource' => 'articles', 'action' => 'write']
]);
print_r($checks);
?>场景2:A/B测试系统
场景描述:实现功能开关和A/B测试。
示例代码:
php
<?php
// 场景说明:A/B测试系统
class ABTestingSystem {
private $database;
public function __construct($databaseName) {
$client = new MongoDB\Client("mongodb://localhost:27017");
$this->database = $client->selectDatabase($databaseName);
}
// 创建实验
public function createExperiment($name, $variants) {
$collection = $this->database->selectCollection('experiments');
$experiment = [
'name' => $name,
'is_active' => true,
'variants' => $variants,
'created_at' => new MongoDB\BSON\UTCDateTime()
];
$result = $collection->insertOne($experiment);
return (string)$result->getInsertedId();
}
// 分配用户到实验组
public function assignUserToVariant($experimentName, $userId) {
$collection = $this->database->selectCollection('experiments');
$assignmentCollection = $this->database->selectCollection('experiment_assignments');
$experiment = $collection->findOne([
'name' => $experimentName,
'is_active' => true
]);
if (!$experiment) {
return null;
}
// 检查是否已分配
$existing = $assignmentCollection->findOne([
'experiment_name' => $experimentName,
'user_id' => $userId
]);
if ($existing) {
return $existing['variant'];
}
// 随机分配
$variants = $experiment['variants'];
$variant = $variants[array_rand($variants)];
$assignmentCollection->insertOne([
'experiment_name' => $experimentName,
'user_id' => $userId,
'variant' => $variant,
'assigned_at' => new MongoDB\BSON\UTCDateTime()
]);
return $variant;
}
// 检查用户是否在实验组
public function isInExperiment($experimentName, $userId, $variant = null) {
$collection = $this->database->selectCollection('experiment_assignments');
$query = [
'experiment_name' => $experimentName,
'user_id' => $userId
];
if ($variant) {
$query['variant'] = $variant;
}
$result = $collection->findOne($query);
return $result !== null;
}
// 获取实验统计
public function getExperimentStats($experimentName) {
$collection = $this->database->selectCollection('experiment_assignments');
$pipeline = [
[
'$match' => ['experiment_name' => $experimentName]
],
[
'$group' => [
'_id' => '$variant',
'count' => ['$sum' => 1]
]
]
];
return $collection->aggregate($pipeline)->toArray();
}
// 启用/禁用实验
public function toggleExperiment($experimentName, $active) {
$collection = $this->database->selectCollection('experiments');
$result = $collection->updateOne(
['name' => $experimentName],
['$set' => ['is_active' => $active]]
);
return $result->getModifiedCount() > 0;
}
}
// 使用示例
$system = new ABTestingSystem('abtest_db');
// 创建实验
$system->createExperiment('new_ui_design', ['control', 'variant_a', 'variant_b']);
// 分配用户
$variant = $system->assignUserToVariant('new_ui_design', 'user_001');
echo "用户分配到: $variant\n";
// 检查用户是否在实验组
$inExperiment = $system->isInExperiment('new_ui_design', 'user_001');
echo "用户是否在实验中: " . ($inExperiment ? '是' : '否') . "\n";
// 获取统计
$stats = $system->getExperimentStats('new_ui_design');
print_r($stats);
?>行业最佳实践
实践1:使用清晰的命名
实践内容:
- 使用is_、has_、can_等前缀
- 避免否定词
- 名称应清晰表达含义
推荐理由:
- 提高代码可读性
- 避免逻辑混乱
- 便于维护
php
<?php
// 好的实践:清晰的命名
$goodExamples = [
'is_active' => '用户是否激活',
'has_permission' => '是否有权限',
'can_edit' => '是否能编辑',
'should_notify' => '是否应通知'
];
// 不好的实践:不清晰的命名
$badExamples = [
'is_not_inactive' => '双重否定,难以理解',
'flag' => '含义不明',
'status_bool' => '冗余命名'
];
?>实践2:创建合适的索引
实践内容:
- 为常用布尔字段创建索引
- 使用复合索引优化查询
- 定期监控索引使用情况
推荐理由:
- 提高查询性能
- 减少资源消耗
- 优化用户体验
php
<?php
// 好的实践:创建索引
$collection->createIndex(['is_active' => 1]);
$collection->createIndex(['is_active' => 1, 'is_verified' => 1]);
?>实践3:避免过度使用布尔字段
实践内容:
- 用状态字段代替多个布尔字段
- 设计合理的状态机
- 保持逻辑清晰
推荐理由:
- 避免状态冲突
- 提高可维护性
- 减少错误
php
<?php
// 好的实践:使用状态字段
$document = [
'status' => 'published', // draft, published, archived, deleted
'published_at' => new MongoDB\BSON\UTCDateTime()
];
// 不好的实践:多个布尔字段
$badDocument = [
'is_draft' => false,
'is_published' => true,
'is_archived' => false,
'is_deleted' => false
];
?>常见问题答疑(FAQ)
问题1:布尔值应该使用true/false还是1/0?
问题描述:在MongoDB中应该使用true/false还是1/0表示布尔值?
回答内容:
应该使用true/false,原因如下:
php
<?php
// 场景说明:布尔值表示方法对比
class BooleanRepresentationComparison {
private $database;
public function __construct($databaseName) {
$client = new MongoDB\Client("mongodb://localhost:27017");
$this->database = $client->selectDatabase($databaseName);
}
public function compareRepresentations() {
$collection = $this->database->selectCollection('representation_comparison');
// 方法1:使用布尔值(推荐)
$collection->insertOne([
'method' => 'boolean',
'value' => true,
'storage_bytes' => 2,
'query_type' => 'is_active: true',
'pros' => ['类型明确', '存储高效', '查询直观'],
'cons' => []
]);
// 方法2:使用整数
$collection->insertOne([
'method' => 'integer',
'value' => 1,
'storage_bytes' => 4,
'query_type' => 'is_active: 1',
'pros' => ['兼容性好'],
'cons' => ['类型不明确', '存储较大', '查询易混淆']
]);
// 方法3:使用字符串
$collection->insertOne([
'method' => 'string',
'value' => 'true',
'storage_bytes' => 6,
'query_type' => 'is_active: "true"',
'pros' => [],
'cons' => ['类型错误', '存储最大', '查询复杂', '易出错']
]);
return [
'recommendation' => '使用true/false布尔值',
'reasons' => [
'类型安全' => '明确的布尔类型',
'存储高效' => '仅占用2字节',
'查询直观' => '语义清晰',
'索引优化' => '索引效率高'
]
];
}
}
// 使用示例
$comparison = new BooleanRepresentationComparison('testdb');
$result = $comparison->compareRepresentations();
print_r($result);
?>问题2:如何处理布尔字段的默认值?
问题描述:布尔字段应该设置什么默认值?
回答内容:
根据业务场景选择合适的默认值:
php
<?php
// 场景说明:布尔字段默认值设置
class BooleanDefaultValueHandler {
private $database;
public function __construct($databaseName) {
$client = new MongoDB\Client("mongodb://localhost:27017");
$this->database = $client->selectDatabase($databaseName);
}
public function demonstrateDefaultValues() {
$collection = $this->database->selectCollection('default_values');
// 场景1:用户状态(默认false,需要激活)
$user = [
'is_active' => false, // 默认未激活
'is_verified' => false, // 默认未验证
'is_admin' => false // 默认非管理员
];
// 场景2:内容设置(默认true,允许操作)
$article = [
'is_commentable' => true, // 默认可评论
'is_shareable' => true, // 默认可分享
'is_visible' => true // 默认可见
];
// 场景3:功能开关(默认false,谨慎启用)
$feature = [
'is_enabled' => false, // 默认禁用
'is_beta' => false // 默认非测试版
];
return [
'user_defaults' => [
'is_active' => false,
'reason' => '安全考虑,需要用户主动激活'
],
'content_defaults' => [
'is_commentable' => true,
'reason' => '用户体验,默认允许交互'
],
'feature_defaults' => [
'is_enabled' => false,
'reason' => '风险控制,需要手动启用'
]
];
}
public function getDefaultValueGuidelines() {
return [
'security_first' => [
'principle' => '安全优先',
'examples' => [
'is_active' => false,
'is_verified' => false,
'is_admin' => false
]
],
'user_experience' => [
'principle' => '用户体验优先',
'examples' => [
'is_commentable' => true,
'is_shareable' => true,
'is_visible' => true
]
],
'risk_control' => [
'principle' => '风险控制优先',
'examples' => [
'is_enabled' => false,
'is_beta' => false,
'is_experimental' => false
]
]
];
}
}
// 使用示例
$handler = new BooleanDefaultValueHandler('testdb');
$defaults = $handler->demonstrateDefaultValues();
print_r($defaults);
$guidelines = $handler->getDefaultValueGuidelines();
print_r($guidelines);
?>问题3:如何优化布尔字段的查询性能?
问题描述:如何提高布尔字段的查询效率?
回答内容:
通过索引和查询优化提高性能:
php
<?php
// 场景说明:布尔字段查询优化
class BooleanQueryOptimization {
private $database;
public function __construct($databaseName) {
$client = new MongoDB\Client("mongodb://localhost:27017");
$this->database = $client->selectDatabase($databaseName);
}
public function optimizeBooleanQueries() {
$collection = $this->database->selectCollection('optimized_boolean');
// 创建索引
$collection->createIndex(['is_active' => 1]);
$collection->createIndex(['is_active' => 1, 'created_at' => -1]);
// 插入测试数据
for ($i = 0; $i < 10000; $i++) {
$collection->insertOne([
'is_active' => (bool)($i % 2),
'is_verified' => (bool)($i % 3),
'created_at' => new MongoDB\BSON\UTCDateTime()
]);
}
// 优化查询1:使用索引
$startTime = microtime(true);
$results = $collection->find(['is_active' => true])->toArray();
$indexedTime = microtime(true) - $startTime;
// 优化查询2:复合索引
$startTime = microtime(true);
$results = $collection->find([
'is_active' => true
], [
'sort' => ['created_at' => -1],
'limit' => 100
])->toArray();
$compoundTime = microtime(true) - $startTime;
return [
'indexed_query' => [
'time' => $indexedTime,
'count' => count($results)
],
'compound_query' => [
'time' => $compoundTime,
'count' => count($results)
],
'optimization_tips' => [
'1. 为常用布尔字段创建索引',
'2. 使用复合索引优化排序',
'3. 避免全表扫描',
'4. 使用explain分析查询计划'
]
];
}
}
// 使用示例
$optimization = new BooleanQueryOptimization('testdb');
$result = $optimization->optimizeBooleanQueries();
print_r($result);
?>问题4:如何处理布尔字段的缺失值?
问题描述:文档中布尔字段缺失时如何处理?
回答内容:
使用$exists操作符或设置默认值:
php
<?php
// 场景说明:处理布尔字段缺失值
class MissingBooleanHandler {
private $database;
public function __construct($databaseName) {
$client = new MongoDB\Client("mongodb://localhost:27017");
$this->database = $client->selectDatabase($databaseName);
}
public function handleMissingValues() {
$collection = $this->database->selectCollection('missing_boolean');
// 插入缺失布尔字段的文档
$collection->insertOne([
'name' => 'Document without boolean field'
]);
// 插入包含布尔字段的文档
$collection->insertOne([
'name' => 'Document with boolean field',
'is_active' => true
]);
// 方法1:使用$exists检查字段是否存在
$withField = $collection->find([
'is_active' => ['$exists' => true]
])->toArray();
// 方法2:使用$ifnull设置默认值
$pipeline = [
[
'$project' => [
'name' => 1,
'is_active' => ['$ifNull' => ['$is_active', false]]
]
]
];
$withDefault = $collection->aggregate($pipeline)->toArray();
return [
'documents_with_field' => count($withField),
'documents_with_default' => count($withDefault),
'best_practice' => '在插入文档时设置默认值,避免字段缺失'
];
}
public function ensureDefaultValue($document, $field, $default = false) {
if (!isset($document[$field])) {
$document[$field] = $default;
}
return $document;
}
}
// 使用示例
$handler = new MissingBooleanHandler('testdb');
$result = $handler->handleMissingValues();
print_r($result);
?>问题5:如何在聚合中使用布尔字段?
问题描述:如何在聚合管道中使用布尔字段进行统计?
回答内容:
使用$cond和$sum操作符:
php
<?php
// 场景说明:聚合中使用布尔字段
class BooleanAggregation {
private $database;
public function __construct($databaseName) {
$client = new MongoDB\Client("mongodb://localhost:27017");
$this->database = $client->selectDatabase($databaseName);
}
public function aggregateWithBoolean() {
$collection = $this->database->selectCollection('boolean_aggregation');
// 插入测试数据
for ($i = 0; $i < 100; $i++) {
$collection->insertOne([
'user_id' => $i,
'is_active' => (bool)($i % 2),
'is_verified' => (bool)($i % 3),
'is_premium' => (bool)($i % 5)
]);
}
// 聚合统计
$pipeline = [
[
'$group' => [
'_id' => null,
'total' => ['$sum' => 1],
'active_count' => [
'$sum' => ['$cond' => ['$is_active', 1, 0]]
],
'verified_count' => [
'$sum' => ['$cond' => ['$is_verified', 1, 0]]
],
'premium_count' => [
'$sum' => ['$cond' => ['$is_premium', 1, 0]]
]
]
],
[
'$project' => [
'total' => 1,
'active_count' => 1,
'verified_count' => 1,
'premium_count' => 1,
'active_percentage' => [
'$multiply' => [
['$divide' => ['$active_count', '$total']],
100
]
]
]
]
];
return $collection->aggregate($pipeline)->toArray();
}
public function groupByBoolean() {
$collection = $this->database->selectCollection('boolean_aggregation');
// 按布尔字段分组
$pipeline = [
[
'$group' => [
'_id' => '$is_active',
'count' => ['$sum' => 1]
]
],
[
'$sort' => ['_id' => 1]
]
];
return $collection->aggregate($pipeline)->toArray();
}
}
// 使用示例
$aggregation = new BooleanAggregation('testdb');
$stats = $aggregation->aggregateWithBoolean();
print_r($stats);
$grouped = $aggregation->groupByBoolean();
print_r($grouped);
?>问题6:如何批量更新布尔字段?
问题描述:如何高效地批量更新布尔字段?
回答内容:
使用updateMany或bulkWrite:
php
<?php
// 场景说明:批量更新布尔字段
class BooleanBatchUpdate {
private $database;
public function __construct($databaseName) {
$client = new MongoDB\Client("mongodb://localhost:27017");
$this->database = $client->selectDatabase($databaseName);
}
public function batchUpdateBooleans() {
$collection = $this->database->selectCollection('batch_boolean');
// 插入测试数据
for ($i = 0; $i < 1000; $i++) {
$collection->insertOne([
'user_id' => $i,
'is_active' => false,
'is_verified' => false
]);
}
// 方法1:使用updateMany
$startTime = microtime(true);
$result1 = $collection->updateMany(
['user_id' => ['$lt' => 500]],
['$set' => ['is_active' => true]]
);
$updateManyTime = microtime(true) - $startTime;
// 方法2:使用bulkWrite
$startTime = microtime(true);
$bulkOps = [];
for ($i = 500; $i < 1000; $i++) {
$bulkOps[] = [
'updateOne' => [
['user_id' => $i],
['$set' => ['is_verified' => true]]
]
];
}
$result2 = $collection->bulkWrite($bulkOps);
$bulkWriteTime = microtime(true) - $startTime;
return [
'updateMany' => [
'matched' => $result1->getMatchedCount(),
'modified' => $result1->getModifiedCount(),
'time' => $updateManyTime
],
'bulkWrite' => [
'matched' => $result2->getMatchedCount(),
'modified' => $result2->getModifiedCount(),
'time' => $bulkWriteTime
],
'recommendation' => '对于条件更新使用updateMany,对于复杂批量操作使用bulkWrite'
];
}
}
// 使用示例
$batch = new BooleanBatchUpdate('testdb');
$result = $batch->batchUpdateBooleans();
print_r($result);
?>实战练习
练习1:基础练习 - 用户激活系统
解题思路:
- 创建用户文档
- 实现激活功能
- 查询激活状态
常见误区:
- 未设置默认值
- 未创建索引
- 未处理并发
参考代码:
php
<?php
// 练习1:用户激活系统
class UserActivationExercise {
private $database;
public function __construct($databaseName) {
$client = new MongoDB\Client("mongodb://localhost:27017");
$this->database = $client->selectDatabase($databaseName);
}
public function run() {
$collection = $this->database->selectCollection('exercise_users');
$collection->drop();
// 创建索引
$collection->createIndex(['is_active' => 1]);
// 步骤1:创建用户
$result = $collection->insertOne([
'username' => 'john_doe',
'email' => 'john@example.com',
'is_active' => false,
'created_at' => new MongoDB\BSON\UTCDateTime()
]);
$userId = $result->getInsertedId();
echo "用户创建成功,ID: $userId\n";
// 步骤2:激活用户
$collection->updateOne(
['_id' => $userId],
[
'$set' => [
'is_active' => true,
'activated_at' => new MongoDB\BSON\UTCDateTime()
]
]
);
echo "用户已激活\n";
// 步骤3:查询激活用户
$activeUsers = $collection->find(['is_active' => true])->toArray();
echo "激活用户数量: " . count($activeUsers) . "\n";
}
}
// 运行练习
$exercise = new UserActivationExercise('exercise_db');
$exercise->run();
?>练习2:进阶练习 - 权限管理系统
解题思路:
- 设计权限结构
- 实现权限检查
- 批量权限管理
参考代码:
php
<?php
// 练习2:权限管理系统
class PermissionManagementExercise {
private $database;
public function __construct($databaseName) {
$client = new MongoDB\Client("mongodb://localhost:27017");
$this->database = $client->selectDatabase($databaseName);
}
public function run() {
$collection = $this->database->selectCollection('exercise_permissions');
$collection->drop();
// 步骤1:创建权限文档
$collection->insertOne([
'user_id' => 'user_001',
'can_read' => true,
'can_write' => false,
'can_delete' => false,
'can_admin' => false
]);
echo "权限文档创建成功\n";
// 步骤2:检查权限
$permissions = $collection->findOne(['user_id' => 'user_001']);
if ($permissions['can_read']) {
echo "用户有读权限\n";
}
if (!$permissions['can_write']) {
echo "用户没有写权限\n";
}
// 步骤3:授予权限
$collection->updateOne(
['user_id' => 'user_001'],
['$set' => ['can_write' => true]]
);
echo "已授予写权限\n";
// 步骤4:查询有写权限的用户
$writers = $collection->find(['can_write' => true])->toArray();
echo "有写权限的用户数量: " . count($writers) . "\n";
}
}
// 运行练习
$exercise = new PermissionManagementExercise('exercise_db');
$exercise->run();
?>练习3:挑战练习 - 功能开关系统
解题思路:
- 设计功能开关结构
- 实现动态开关
- 支持灰度发布
参考代码:
php
<?php
// 练习3:功能开关系统
class FeatureFlagExercise {
private $database;
public function __construct($databaseName) {
$client = new MongoDB\Client("mongodb://localhost:27017");
$this->database = $client->selectDatabase($databaseName);
}
public function run() {
$collection = $this->database->selectCollection('exercise_features');
$collection->drop();
// 步骤1:创建功能开关
$features = [
['name' => 'new_dashboard', 'is_enabled' => false],
['name' => 'dark_mode', 'is_enabled' => true],
['name' => 'beta_features', 'is_enabled' => false]
];
$collection->insertMany($features);
echo "功能开关创建成功\n";
// 步骤2:检查功能状态
$darkMode = $collection->findOne(['name' => 'dark_mode']);
if ($darkMode['is_enabled']) {
echo "暗黑模式已启用\n";
}
// 步骤3:启用功能
$collection->updateOne(
['name' => 'new_dashboard'],
['$set' => ['is_enabled' => true]]
);
echo "新仪表板已启用\n";
// 步骤4:查询启用的功能
$enabledFeatures = $collection->find(['is_enabled' => true])->toArray();
echo "启用的功能数量: " . count($enabledFeatures) . "\n";
// 步骤5:批量切换
$collection->updateMany(
[],
['$set' => ['is_enabled' => false]]
);
echo "所有功能已禁用\n";
}
}
// 运行练习
$exercise = new FeatureFlagExercise('exercise_db');
$exercise->run();
?>知识点总结
核心要点
Boolean类型特性
- 只有两个值:true 和 false
- 占用2字节存储空间
- BSON类型标识符:0x08
存储机制
- 类型标识 + 布尔值
- 高效的存储和查询
- 支持索引优化
命名规范
- 使用is_、has_、can_等前缀
- 避免否定词
- 名称应清晰表达含义
查询优化
- 创建索引提高性能
- 使用复合索引优化排序
- 避免全表扫描
易错点回顾
类型混淆
- 使用字符串代替布尔值
- 使用整数代替布尔值
- 查询类型不匹配
命名不当
- 使用否定词
- 命名不清晰
- 双重否定
过度使用
- 多个布尔字段表示状态
- 未考虑状态机
- 维护困难
拓展参考资料
官方文档链接
- MongoDB Boolean类型: https://docs.mongodb.com/manual/reference/bson-types/#boolean
- 查询操作符: https://docs.mongodb.com/manual/reference/operator/query/
- 聚合操作符: https://docs.mongodb.com/manual/reference/operator/aggregation/
进阶学习路径建议
本知识点承接:《Double类型》→《基本数据类型概述》
后续延伸至:《Null类型》→《ObjectId类型》→《Date类型》
建议学习顺序:
- Double类型
- Boolean类型(本章节)
- Array类型
- Object类型
- Null类型
