mongodb JavaScript Function

mongo shell methods(mongo 的方法/函数)

虽然这些方法是用的JavaScript,但大多数的mongo操作不是使用JavaScript,而是使用各自语言提供的驱动程序。使用JavaScript执行Shell脚本操作mongo将是非常有趣的事情,非常灵活。对数据维护是一种必备利器。

但为什么我要写这篇文章呢?
因为在mongodb中提供了一个Stored JavaScript功能(类似于关系型数据库的存储过程),它完全采用JavaScript进行数据库的相关操作,我们可以通过Shell调用它们,而且可以通过Mongo驱动调用它们并返回数据。

在某些情况下Stored JavaScript的效率要远远超过其他语言驱动调用,但如果你对mongodb提供的JavaScript API不清楚,那么必然会遇到很多问题,这篇文章就帮助你学习他的API,并且会给出一些代码例子。

Collection (集合)


db.collection.aggregate()

数据的聚合操作通过$match \ $project \ $group \ $count 等操作命令来完成类似SQL的聚合操作。

来个例子:

// 统计年龄大于18岁的用户,并输出name和age属性
db.users.aggregate([
    {$project:{name:1, age:1}}
    , {$match:{age:{$gt:18}}}
   ]);


db.collection.count()

统计集合的数据量


db.collection.distinct(field, query)

去除重复查询

// 查询订单中价格大于10的,并且排除ord_dt的重复
db.orders.distinct( 'ord_dt', { price: { $gt: 10 } } )

db.collection.createIndex(keys, options)

创建索引,
”Deprecated since version 1.8.“,也就是说在1.8版本已经被废弃了,而新用的是db.collection.ensureIndex(keys, options)

// 创建age降序排序的索引,如果索引存在,它不会被执行的哦!
db.collection.ensureIndex({age:-1}).

db.collection.dataSize()

// 获取集合的数据大小
db.system.js.dataSize()

db.collection.find(<criteria>, <projection>)

查询数据方法

// 查询qty大于25的产品
db.products.find( { qty: { $gt: 25 } } )

db.collection.group({ key, reduce, initial, [keyf,] [cond,] finalize })

分组查询

db.orders.group(
   {
     key: { ord_dt: 1, 'item.sku': 1 },
     cond: { ord_dt: { $gt: new Date( '01/01/2012' ) } },
     reduce: function ( curr, result ) { },
     initial: { }
   }
)

db.collection.findOne(<criteria>, <projection>)

查询一条数据


db.collection.save()

保存数据

// 保存一个产品信息
db.products.save( { item: "book", qty: 40 } )

在2.6版本中更新了save方法哦

db.products.save(
    { item: "envelopes", qty : 100, type: "Clasp" },
    { writeConcern: { w: "majority", wtimeout: 5000 } }
)
// 5000 milliseconds 后执行哈

说说mongo cursor(游标)

因为使用Store JavaScript 来做查询数据非常棒的。

cursor.next() 查询下一条数据

cursor.hasNext() 是否还有记录

cursor.count() 查询的总数据量

cursor.toArray() 全部数据转数组,查询数据量大,性能就很低

cursor.forEach() 遍历游标数据

cursor.map() 遍历数据,但操作不同(将某个字段放入数组)

cursor.sort() 排序

来个例子吧,这个比较复杂,但是基本的游标操作都在里面。

功能是查询前5名用户,和当前用户排名的前后2位,也就是总共查询10名用户。
totalDuration属性的排名

/*

   获取用户10位排名信息
   getUserRank(userId )
   @author marker
   @date 2014-09-25
 */

function (userId) {
    // 因为mongo的数据类型,需要做这样的转换,js不支持long哦
    var userIdStr = "NumberLong("+userId+")";

    var args = [
        {$project:{ userId : 1 , totalDuration : 1 } },
        {$match:{}},
        {$group:{_id:"$userId",value:{$sum:"$totalDuration"}}},
        {$sort:{value:-1}}
    ];


    var arr = new Array();

    var rank = 0;//用户的排名

    /*
        计算用户的排名
     */
    var c = db.package_user_rank.aggregate(args);
    while(c.hasNext()){
        rank++;
        var user = c.next();
        // mongo对象格式:NumberLong(1000000698)
        if(user._id.toString() == userIdStr){
            break;
        }
    }

    /*
       查询排名用户信息
     */
    var up2   = rank - 2;
    var down2 = rank + 2;
    var curr = 0;
    var c2 = db.package_user_rank.aggregate(args);
    var urank = 0;
    while(c2.hasNext()){
        curr++;
        var user = c2.next();
        user.userId =user._id;// 添加字段,方便formatjson
        if(rank < 11){// 用户排名在10名以内,简单查询
            user.rank = ++urank;
            arr.push(user);
        }else{// 10以外
            if(curr < 6){
                user.rank = ++urank;
                arr.push(user);
            }
            // 用户附近的排名
            if(curr >= up2 && curr <= down2){
                user.rank = ++urank;
                arr.push(user);
            }
        }
        // 如果查询10个用户完毕,结束循环
        if(arr.length == 10){
            break;
        }
    }
    return arr;
}

响应数据:

[
    {
        "_id": 209035,
        "value": 1146879807,
        "userId": 209035,
        "rank": 1
    },
    {
        "_id": 189169,
        "value": 38481381,
        "userId": 189169,
        "rank": 2
    },
    {
        "_id": 230622,
        "value": 35247413,
        "userId": 230622,
        "rank": 3
    },
    {
        "_id": 290064,
        "value": 21340000,
        "userId": 290064,
        "rank": 4
    },
    {
        "_id": 261845,
        "value": 19600309,
        "userId": 261845,
        "rank": 5
    },
    {
        "_id": 260913,
        "value": 156566,
        "userId": 260913,
        "rank": 6
    },
    {
        "_id": 283491,
        "value": 149836,
        "userId": 283491,
        "rank": 7
    },
    {
        "_id": 256548,
        "value": 148374,
        "userId": 256548,
        "rank": 8
    },
    {
        "_id": 284387,
        "value": 146625,
        "userId": 284387,
        "rank": 9
    },
    {
        "_id": 294194,
        "value": 130965,
        "userId": 294194,
        "rank": 10
    }
]

参考资料

http://docs.mongodb.org/manual/reference/method/

mongodb调试程序

大家想着既然是javaScript支持的,那么输出应该写为

console.log("this is debug info");

alert('this is debug info');

但事实上,这个事浏览器提供的方法,在mongodb中没有的哦,那怎么办呢?来看看正确的方法

var debug = true;

if(debug){
    print("this is debug info!");
}

也就是说,在mongo的shell中我们是使用print方法来做调试与测试的。在mongo中还提供了一个方法tojson(obj) 直接将对象转为json数据格式。

来源: 雨林博客(www.yl-blog.com)