SPL:访问 MongoDB
MongoDB是非关系数据库,以类似JSON的BSON格式存储数据,它提供了一整套命令操作数据,轻量计算引擎语言SPL支持嵌套的数据结构,很容易加载JSON数据,可以用SPL扩展MongoDB的计算能力。SPL提供了mongo_shell函数,通过它执行Mongo命令读写Mongo数据。
创建/关闭Mongo连接
使用方式类似关系数据库的JDBC连接,SPL也用成对的“创建/关闭”方式连接MongoDB。
mongo_open(connectionString),参数细节参考其官网Connection String。
mongo_close(mongoConn),mongoConn是要关闭的Mongo连接。
示例:A1创建连接,中间做一些读写、计算操作后,A3关闭A1创建的连接
A |
|
1 |
=mongo_open("mongodb://127.0.0.1:27017/mymongo") |
2 |
…… |
3 |
=mongo_close(A1) |
执行Mongo命令
Mongo定义了查询、更新数据、管理数据库用户等百余命令,所有命令的输入、输出都是特定格式的JSON。
mongo_shell(inputJson),inputJson是命令的输入。
示例:
A |
|
1 |
=mongo_open("mongodb://127.0.0.1:27017/mymongo") |
2 |
=mongo_shell(A1,"{'find':'orders',filter:{OrderID: { $gte: 50}},batchSize:10}") |
3 |
=A2.cursor.firstBatch |
4 |
=mongo_shell(A1,"{'getMore':"+string(A2.cursor.id)+",batchSize:20}") |
5 |
=create(OrderID,Client,SellerId,Amount,OrderDate) |
6 |
>A5.insert(0,26,"TAS",1,2142.4,"2009-08-05") |
7 |
>A5.insert(0,28,"DSGC",21,2125.4,"2009-09-05") |
8 |
=mongo_shell(A1,"{'insert':'orders',documents:"+json(A5)+"}") |
9 |
=mongo_close(A1) |
A2从orders表查询OrdersID>50的数据,返回前10行数据,得到的结果是和find命令输出JSON一致的嵌套SPL序表,下面对比下find命令返回的JSON格式及SPL序表结构:
{
"cursor": {
"firstBatch": [{
"_id": 61 adf78694c8ba530702472e,
"OrderID": 84,
"Client": "GC",
"SellerId": 1,
"Amount": 88.5,
"OrderDate": "2009-10-16"
}
,......other 9 rows data ……
],
"id": 8676451393605378424,
"ns": "mymongo.orders"
},
"ok": 1
}
A3是A2第三层的数据序表firstBatch;
A4使用A2结果序表中的游标ID(A2.cursor.id)执行getMore命令,再取20行数据。
A5创建一个和orders表结构相同的SPL序表,A6、A7向A5序表中初始化两条数据;
A8用insert命令把A5序表更新到mongo的orders表中,其中的SPL函数json(A5),把A5序表转换成json字符串,从而拼成完整的insert命令JSON串。insert命令执行后返回{"n":2,"ok":1},表明向Mongo的orders表成功的增加了两行数据。
看到A8的值仍然是与结果JSON等效的序表:
一次返回全部查询结果
一次完整的查询,往往由find命令和之后的多次getMore命令组合获得全部数据,mongo_shell函数用@d选项直接返回全部数据:
A |
|
1 |
=mongo_open("mongodb://127.0.0.1:27017/mymongo") |
2 |
=mongo_shell@d(A1,"{'find':'orders',filter:{OrderID: { $gte: 50}},batchSize:10}") |
3 |
=mongo_close(A1) |
A2直接得到“首次find + N次getMore”的数据,执行N次getMore命令封装到了mongo_shell函数内部,自动循环执行,直到取得全部数据:
用SPL游标返回查询结果
对于大结果集,整体返回可能导致内存溢出,这时mongo_shell在@d的基础上,再加上@c选项,就返回SPL游标了,之后可以用fetch函数逐步取出数据:
A |
|
1 |
=mongo_open("mongodb://127.0.0.1:27017/mymongo") |
2 |
=mongo_shell@dc(A1,"{'find':'orders',filter:{OrderID: { $gte: 50}},batchSize:10}") |
3 |
=if(A2==null, null, A2.fetch(5)) |
4 |
=if(A3==null, null, A2.fetch(10)) |
5 |
=mongo_close(A1) |
A2执行后得到SPL游标,A3取出第1~5条,A4取出第6~15条。
注意,如果A2不是查询数据的mongo命令,@dc无法返回SPL游标,A3、A4取数时,要判断A2是否为null。
英文版