SPL:访问 MongoDB

MongoDB是非关系数据库,以类似JSONBSON格式存储数据,它提供了一整套命令操作数据,轻量计算引擎语言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)

 

A2orders表查询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

}

 

..

A3A2第三层的数据序表firstBatch

A4使用A2结果序表中的游标ID(A2.cursor.id)执行getMore命令,再取20行数据。

A5创建一个和orders表结构相同的SPL序表,A6A7A5序表中初始化两条数据;

..

A8insert命令把A5序表更新到mongoorders表中,其中的SPL函数json(A5),把A5序表转换成json字符串,从而拼成完整的insert命令JSON串。insert命令执行后返回{"n":2,"ok":1},表明向Mongoorders表成功的增加了两行数据。

看到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 NgetMore”的数据,执行NgetMore命令封装到了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游标,A3A4取数时,要判断A2是否为null