高级查询,聚合分析
$and
$or
人口大于15336,州是MA或者城市是CHICOPEE的数据
db.getCollection('zips').find({
pop: {$gt:15336},
$or:[
{state:'MA'},
{city:'CHICOPEE'}
]
})
Y坐标是42.070206的数据
db.getCollection('zips').find({
loc: 42.070206
});
先组内嵌文档装一个数据
db.user.insert(
{
name: 'kit',
family: {
mather: 'Joan',
father: 'Fred'
},
age: 22,
city: "CHESTER",
sex: 'boy'
}
)
下面来进入范例,查询name是kit的爸爸名字叫Fred的人(这个例子有些太跑偏)
db.user.find(
{
name: 'kit',
'family.father': 'Fred'
}
)
对于内嵌文档的查询一定要加入引号
查找含有AGG的城市数据
db.getCollection('zips').find({
city: /AGG/
})
查找结尾是AGG的城市数据
db.getCollection('zips').find({
city: /AGG$/
})
这个也是正则表达式通用手法。查找结尾是AGG或者是agg的城市数据
db.getCollection('zips').find({
city: /agg$/,
$option: "$i"
})
查找城市为CHESTER的用户信息,首先将城市为CHESTER的信息查询出来
use zips;
zip=db.user.findOne({city:'CHESTER'})
通过地区对象zip来获取用户数据
use user;
for (var user=db.user.find({city:zip.city}); user.hasNext();) {
printjson(user.next());
}
两个Collection之间定义一个关联关系,我们来实现以上操作。
use zips;
zip=db.zips.findOne({city:'CHESTER'});
use user;
db.user.insert(
{
name: 'lucy',
family: {
mather: 'Joan',
father: 'Fred'
},
age: 29,
city: zip,
sex: 'girl'
}
)
db.user.find({name:'lucy'})[0].city
MongoDB中find()函数返回一个游标,客户端通过对游标进行一些设置就能对查询结果进行有效地控制,如可以限制查询得到的结果数量、跳过部分结果、或对结果集按任意键进行排序等。
var cursor = db.user.find();
while(cursor.hasNext()) {
var doc = cursor.next();
printjson(doc);
}
Mongodb聚合分析分析框架,旨在替代MapReduce的慢和抽象,group的不方便开发而成。在启业云平台中单应用分析就是运用它实现而成。
db.collection.aggregate(pipeline, options)
名称 | 介绍 |
---|---|
$project | 重新塑造每个文档流,例如改变字段名称、增加字段名称、删除字段名称 |
$match | 过滤每个文档流(相当于sql中where) |
$redact | 根据字段所处的document结构的级别,对文档进行“修剪”(记住修建,它的特性$project同样可以实现) |
$limit、$skip、$sort | 同Query中的limit、skip、$sort限定符。 |
$unwind | 将指定的数组结构拆解成多条document |
$out | 将聚合分析的结果写入指定的collection中(做不实时的应用很棒!) |
$group | 设定分组字段。_id是必须的,其值是group操作的key |
名称 | 介绍 |
---|---|
$sum | 对每个group指定字段进行累加计算 |
$avg | 对每个group进行“平均值”,忽略非数字的值。 |
$first | 返回每个group的第一条数据,顺序有$sort决定,如果没有排序,默认为文档的自然存储顺序。 |
$last | 返回每个group的最后一条数据,顺序有$sort决定,如果没有排序,默认为文档的自然存储顺序。 |
$max、$min | 获取每个group中最大、最小值。 |
$push | 将指定的表达式的值添加到一个数组中,注意最终返回的document尺寸不要超过16M。 |
$addToSet | 将表达式的值添加到一个集合中(无重复值),注意最终分那会的document尺寸不要超过16M。 |
$geoNear | 用于地理位置数据分析,附近的XXX。 |
db.zips.aggregate([
{$match: { pop : { $gt : 7000, $lte : 90000 } }},
{$group: { _id: null, count: { $sum: 1 } }}
]);
[
{
"$match": {
"$and": [
{
"$or": [
{
"current_handlers": "chenchong"
},
{
"history_handlers": "chenchong"
},
{
"monitor_handlers": "chenchong"
},
{
"cc_handlers": "chenchong"
}
]
},
{
"gongzuojihuazhubiao_gongzuoguikou": {
"$exists": true
}
}
]
}
},
{
"$project": {
"gongzuojihuazhubiao_id": "$gongzuojihuazhubiao_id",
"0_date_year_kaishishijian": {
"$year": "$gongzuojihuazhubiao_kaishishijian"
},
"0_date_quarter_kaishishijian": {
"$cond": [
{
"$lte": [
{
"$month": "$gongzuojihuazhubiao_kaishishijian"
},
3
]
},
"1",
{
"$cond": [
{
"$lte": [
{
"$month": "$gongzuojihuazhubiao_kaishishijian"
},
6
]
},
"2",
{
"$cond": [
{
"$lte": [
{
"$month": "$gongzuojihuazhubiao_kaishishijian"
},
9
]
},
"3",
"4"
]
}
]
}
]
},
"1_gongzuojihuazhubiao_gongzuoguikou": "$gongzuojihuazhubiao_gongzuoguikou"
}
},
{
"$group": {
"count_gongzuojihuazhubiao_id": {
"$sum": 1
},
"_id": {
"0_date_quarter_kaishishijian": "$0_date_quarter_kaishishijian",
"0_date_year_kaishishijian": "$0_date_year_kaishishijian",
"1_basic_gongzuojihuazhubiao_gongzuoguikou": "$1_gongzuojihuazhubiao_gongzuoguikou"
}
}
}
]
db.collection.mapReduce(
<map>,
<reduce>,
{
out: <collection>,
query: <document>,
sort: <document>,
limit: <number>,
finalize: <function>,
scope: <document>,
jsMode: <boolean>,
verbose: <boolean>
}
)
db.getCollection('zips').mapReduce(
function() {
return this;
},
function(pop, city) {
return Array.sum(pop);
},
{
out: "zip_demo"
}
)
Mongodb PHP扩展提供了Mongodb最常用的API操作。如果安装可以参照Mongodb-安装篇。 从这里你可以得到扩展文档的详尽信息http://php.net/manual/zh/book.mongo.php
<?php
//连接到mongodb
$m = MongoClient();
//选择一个数据库
$db = $m->user;
?>
贴上平台的核心类方法
<?php
class Connection
{
public static $db = [];
public static function connect($config = [])
{
if (empty($config)) {
$database = static::getDefaultConfig();
$dsn = "mongodb://{$database['user']}:{$database['password']}@{$database['host']}/{$database['dbname']}";
$dbname = $database['dbname'];
} else {
$dsn = $config['dsn'];
$dbname = $config['dbname'];
}
if (!isset(static::$db[$dsn])) {
$m = new \MongoClient(
$dsn
);
static::$db[$dsn] = $m->$dbname;
return static::$db[$dsn];
} else {
return static::$db[$dsn];
}
}
}
<?php
// 连接到mongodb
$m = new MongoClient();
// 选择一个数据库
$db = $m->user;
$collection = $db->createCollection("company");
?>
使用find() 方法来读取集合中的文档。
// 连接到mongodb
$m = new MongoClient();
// 选择一个数据库
$db = $m->user;
$collection = $db->user;
$cursor = $collection->find();
// 迭代显示文档标题
foreach ($cursor as $document) {
echo $document["name"] . "\n";
}
使用update来更新文档
// 连接到mongodb
$m = new MongoClient();
// 选择一个数据库
$db = $m->user;
$collection = $db->user;
// 更新文档
$collection->update(array("name"=>"mtao"), array('$set'=>array("age"=>"44")));
// 显示更新后的文档
$cursor = $collection->find();
foreach ($cursor as $document) {
print_r($document);
}
<?php
// 连接到mongodb
$m = new MongoClient();
// 选择一个数据库
$db = $m->user;
$collection = $db->user;
// 移除文档
$collection->remove(array("name"=>"kit"), array("justOne" => true));
// 显示可用文档数据
$cursor = $collection->find();
foreach ($cursor as $document) {
echo $document["name"] . "\n";
}
?>
<?php
// 连接到mongodb
$m = new MongoClient();
// 选择一个数据库
$db = $m->zips;
$collection = $db->zips;
$data = $collection->aggregate(
[
[
'$match'=>[
'pop'=> [
'$gt'=> 7000,
'$lte' => 90000
]
]
],
[
'$group'=> [
'_id'=> null,
'count'=> [
'$sum'=>1
]
]
]
]
);
print_r($data['result']);
?>
从上可以看出PHP扩展所提供操作Mongodb的API与其内部实现基本相似。你只需要注意的是JSON对象如何转变为PHP数组即可。
关于是否使用ORM以及一些封装库,我的想法是先把最简单的东西用起来,之后再是引入。