mongodb备忘录

2017-03-05 2443 0

mongo shell中的整数问题

mongodb的shell相当于一个Javascript解释器,可以在其中执行Javascript命令。而在js里面,整数和小数都是number类型,并不区分。mongodb数据采用BSON(Binary JSON)文档型存储,BSON有两种整型数据类型:32位有符号整型(INT)和64位无符号整型(LONG)。如果手动在mongo的shell中插入或更新整数,这个整数会被替换为浮点数。对于已存在的记录,如果更新整数(比如id),这个整数会被替换为浮点数,但是对该记录的其他项更新不会影响已存在的整数项。

一个常用的场景是,使用一个自增的id。用一个集合ids来记录所有其他集合的自增id,在pymogo中用如下命令来获取一个id:

  1. db.ids.find_and_modify(query={'name': 'user'}, update={'$inc': {'id': 1}}, new=True, upsert=True)['id']

pymongo插入整数是可以的,插入时会使用INT或LONG来插入,正常情况下使用这种id是没有问题的。但是,如果有时候id有变化了,为了方便直接在mongo shell中更新,更新之后id变成了浮点数,于是pymongo读出来的也是浮点数了,在使用时就可能会出错。

郁闷的是,直接用python来更新id,只有当id和原来的不一样时才会更新成功,比如数据库中id是10.0,用python直接更新成整数10并不会更改数据库,只有更改成别的整数才会更改数据库。我一般使用下面的方法来更改

  1. db.ids.update({'name': 'user'}, {'$unset': {'id': 1}})
  2. db.ids.update({'name': 'user', {'$set': {'id': 10}}})

mongo shell中的返回值

在mongo shell中使用find查询时,返回值是一个cursor游标,但是赋值给的变量如果没有var标识,则游标会一次走完,打印全部结果。

  1. cursor = db.user.find()
  2. var cursor = db.user.find()

当有var时,并不会打印出来,如果直接输入cursor,会将全部结果打印出来,游标走到底。
可以用cursor.hasNext()来判断后面是否还有结果,用cursor.next()将游标往后移一位,打印一个值。

mongodb的异步

mongodb使用了操作系统底层提供的mmap内存映射机制,插入时会先写到内存中,然后同步到磁盘。为mongodb提供足够的内存空间可以减少磁盘读写次数。mongodb的写操作默认是异步的,为了保持一致性,可以加上选项:

  1. {
  2. safe: {
  3. fsync: true
  4. }
  5. }

pymongo的写操作默认也是异步的,不管写没写成功,insert操作都会返回一个bson.objectid.ObjectId对象,在数据库中的_id值会增加。如果数据库有唯一索引,要通过插入操作的返回值来判断是否插入成功,要将参数safe设置为True

  1. db.user.insert(doc, safe=True)

参考:
mongodb使用小结