一、前提

对于需要远程连接 MongoDB 的情况,需要对服务器做一定的配置(未安装 MongoDB 的可以参考 CentOS 部署 MongoDB):

# 修改 MongoDB 配置
$ vi /etc/mongod.conf

# 在文件中找到下面这段配置
...
net:
  port: 27017
  bindIp: 127.0.0.1   # Listen to local interface only, comment to listen on all interfaces.

# 修改 bindIp(注意:腾讯云需要填内网 IP 而非外网 IP)
# 在 bindIp 后面填写需要开放访问数据库接口的 IP 地址,如果有多个可以用逗号分隔。如果你不清楚你应该开放那个 IP 的接口,你可以直接注释掉 bindIp,这样就相当于默认开放所有的Ip地址的接口了。

# 配置好后重启 MongoDB:
$ sudo service mongod restart

# 如果你设置了防火墙,那么还需要开放27017端口 
$ iptables -A INPUT -p tcp --dport 27017 -j ACCEPT

# 本地命令行中输入远程连接命令 
mongo --host 服务器外网IP地址 


二、Python 部分

1、使用 pymongo 库:

# 安装 pymongo
$ pip install pymongo

# 在 Python 中引用
from pymongo import MongoClient 


2、常规操作:

# 创建 MongoClient (3种方式)
client = MongoClient()
client = MongoClient('mongodb://localhost:27017/')
client = MongoClient('localhost', 27017)


# 选择数据库(3种方式,test 是数据库名)
db = client['test']
db = client('test')
db = client.test


# 获取集合(2种方式,collection 集合就是 MySQL 中的 table)
posts = db["posts"]
posts = db.posts


# 插入文档(document 文档就是 MySQL 中的 row)
post_data = {
    'title': 'Python and MongoDB',
    'content': 'PyMongo is fun, you guys',
    'author': 'Scott'
}
result = posts.insert_one(post_data)
print('One post: {0}'.format(result.inserted_id))

# 插入多个
post_1 = {
    'title': 'Python and MongoDB',
    'content': 'PyMongo is fun, you guys',
    'author': 'Scott1'
}
post_2 = {
    'title': 'Virtual Environments',
    'content': 'Use virtual environments, you guys',
    'author': 'Scott2'
}
post_3 = {
    'title': 'Learning Python',
    'content': 'Learn Python, it is easy',
    'author': 'Bill'
}
new_result = posts.insert_many([post_1, post_2, post_3])
print('Multiple posts: {0}'.format(new_result.inserted_ids))

# 插入时去重(需要循环插入)
posts.update_one({'title': 'Learning Python'}, {"$set": post_1}, True)


# 查找文档
bills_post = posts.find_one({'author': 'Scott'})
print(bills_post)


# 查询多条
scotts_posts = posts.find({'author': 'Scott'})
print(scotts_posts)

for post in scotts_posts:
    print(post)


# 更新文档
posts.update_one({'author': 'Scott'}, {'$set': {'author': 'Scott2'}})
posts.update_many({'author': 'Scott'}, {'$set': {'author': 'Scott2'}})


# 删除
posts.delete_one({'author': 'Scott2'})
posts.delete_many({'author': 'Scott2'})


# 计算数据数
print(posts.count())


# 查看全部
for post in posts.find():
    print(post)


三、PHP 部分

1、首先需要安装 PHP 驱动,但目前存在两种新旧版驱动:PHP 扩展 Mongo 与 MongoDB。这里选择了旧版的 mongo driver,文档在这里:PHP: Mongo - Manual

$ yum -y update

# 安装编译器,php 扩展和应用源,php 开发工具
$ yum -y install gcc php-pear php-devel

# 通过 PECL 安装 php mongo driver,过程有个选择,填 no
$ pecl install mongo

# 编辑 php 配置文件
$ vim /etc/php.ini

# 找到 Dynamic Extensions 区域然后插入数据:extension=mongo.so

# 重启服务器
$ systemctl restart nginx
$ systemctl restart php-fpm

# 验证是否安装成功(若返回 mongo 则表示成功)
$ php -m | grep -i mongo
phpinfo() 查看是否成功安装驱动


2、如果想在电脑上(Mac)开发,可以通过 pecl 安装(首先安装好 Pecl:Install PEAR and PECL on Mac OS X):

$ sudo pecl install mongo

# 然后在 php.ini 里增加 extension=mongo.so,若不生效则用绝对地址如:/usr/local/Cellar/php56/5.6.32_8/lib/php/extensions/no-debug-non-zts-20131226/mongo.so

# 重启服务器
$ systemctl restart nginx
$ systemctl restart php-fpm


3、常规操作——连接数据库:

# 数据库连接
$m = new MongoClient();
$m = new MongoClient("mongodb://${username}:${password}@localhost");

# 选择数据库
$db = $m->dbname;
$db = $m->selectDB("dbname");


查询数据:

# 查看所有 collections
$collections = $db->listCollections();
foreach ($collections as $collection) {
    echo "表名:".$collection.", ";
    echo "表内行数:".$collection->count()."<br>";
}

# 查看指定 collection
$collection = new MongoCollection($db, 'tablename');
$cursor = $collection->find();
foreach ($cursor as $doc) {
    echo $doc['title'];
}

# 条件查询——根据字段查询(传入 find() 函数中)
$fruitQuery = array('Type' => 'Fruit');
$sweetQuery = array('Details.Taste' => 'Sweet');

# 条件查询——根据范围查询
$where = array('x' => array('$gt'=>5, '$lt'=>20)); // 5 < x < 20
$where = array('class'=>5);                        // Find where class=5
$where = array('class' => array('$ne'=>5));        // Find where class != 5
$where = array('title' => array('$not'=>$regex));  // not match regex
$where = array('age' => array('$gte'=>20));        // Find where age >= 20
$where = array('$or' => array( array('class'=>10), array('marks'=>80))); // Find where class=10 or marks=80
$where = array('$and' => array( array('class'=>12), array('marks'=>70))); // Find where class=12 AND marks=70

# 条件查询——根据 JS 函数查询
$js = "function() {
    return this.name == 'Joe' || this.age == 50;
}";
$cursor = $collection->find(array('$where' => $js));

# 将游标转为数组(使用 iterator_to_array() 会让驱动将强制载入所有搜索结果集到内存,所以对超过内存大小的结果集不要这么做!)
$cursor = $collection->find();
$array = iterator_to_array($cursor);


查询限制条件:

// 只显示十条数据
$cursor = $collection->find()->limit(10);

// 显示最后十条数据(1和2/3的显示顺序还是不一样的)
$cursor = $collection->find()->skip($collection->count()-10);
$cursor = $collection->find()->sort(array('_id'=>-1))->limit(10);
$cursor = $collection->find()->sort(array('$natural'=>-1))->limit(10);


插入数据:

$collection = new MongoCollection('dbname', 'tablename'); 

// 如果使用的是 array 字面语法,将无法成功生成 _id
$collection->insert(array('x' => 1));

// 通过传 array 的变量可以生成 _id
$a = array('x' => 2);
$collection->insert($a);

// 通过传引用的 array 无法生成 _id
$b = array('x' => 3);
$ref = &$b;
$collection->insert($ref);

// 没有在包裹的函数中触发 copy-on-write 时 _id 有效
function insert_no_cow($collection, $document) {
    $collection->insert($document);
}
$c = array('x' => 4);
insert_no_cow($collection, $c);

// 在包裹的函数中触发 copy-on-write 时 _id 无效
function insert_cow($collection, $document) {
    $document['y'] = 1;
    $collection->insert($document);
}
$d = array('x' => 5);
insert_cow($collection, $d);


// 现在 $person 具有一个 _id 字段,所以我们再次 
$person = array("name" => "Joe", "age" => 20);
$collection->insert($person);

// 再次保存它的时候,将会得到一个异常
try {
    $collection->insert($person, array("w" => 1));
} catch(MongoCursorException $e) {
    echo "Can't save the same person twice!\n";
}

// 一次性插入多个数据
$users = array();
for ($i = 0; $i<100; $i++) {
  $users[] = array('username' => 'user'.$i, 'i' => $i);
}
$collection->batchInsert($users);



// save 的用法:如果对象来自数据库,则更新现有的数据库对象,否则插入对象。
$obj = array('x' => 1);

// 插入 $obj 到 db
$collection->save($obj);

// 增加额外的字段
$obj['foo'] = 'bar';

// $obj 不能被再次插入,导致 duplicate _id 错误
$collection->insert($obj);

// 保存、更新附带新字段的 $obj
$collection->save($obj);


更新数据:

// 更新单条数据
$c->insert(array("firstname" => "Bob", "lastname" => "Jones" ));
$newdata = array('$set' => array("address" => "1 Smith Lane"));
$c->update(array("firstname" => "Bob"), $newdata);

// 更新多条数据
$today = array('$gt' => new MongoDate(), '$lt' => new MongoDate(strtotime("+1 day")));
$people->update(
    array("birthday" => $today),
    array('$set' => array('gift' => $surprise)),
    array("multiple" => true)
);


删除数据:

// 删除集合内的文档
$radioactive->remove(array('type' => 94), array("justOne" => true));

// 删除集合
$response = $collection->drop();



相关链接:

man mask