mongodb备忘录
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:
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并不会更改数据库,只有更改成别的整数才会更改数据库。我一般使用下面的方法来更改
db.ids.update({'name': 'user'}, {'$unset': {'id': 1}})
db.ids.update({'name': 'user', {'$set': {'id': 10}}})
mongo shell中的返回值
在mongo shell中使用find查询时,返回值是一个cursor游标,但是赋值给的变量如果没有var标识,则游标会一次走完,打印全部结果。
cursor = db.user.find()
var cursor = db.user.find()
当有var时,并不会打印出来,如果直接输入cursor,会将全部结果打印出来,游标走到底。
可以用cursor.hasNext()来判断后面是否还有结果,用cursor.next()将游标往后移一位,打印一个值。
mongodb的异步
mongodb使用了操作系统底层提供的mmap内存映射机制,插入时会先写到内存中,然后同步到磁盘。为mongodb提供足够的内存空间可以减少磁盘读写次数。mongodb的写操作默认是异步的,为了保持一致性,可以加上选项:
{
safe: {
fsync: true
}
}
pymongo的写操作默认也是异步的,不管写没写成功,insert操作都会返回一个bson.objectid.ObjectId对象,在数据库中的_id值会增加。如果数据库有唯一索引,要通过插入操作的返回值来判断是否插入成功,要将参数safe设置为True
db.user.insert(doc, safe=True)
参考:
mongodb使用小结