mongodb学习总结

137 阅读2分钟
  • 与MySQL这种关系型不同在于MongoDB的数据可能存在多个副本,写数据需要同步给副本,性能考虑,存在写入master成功,即通知客户端写入成功,而读数据时可能从副本集读,导致数据不一致现象,因此与MySQL这种插入和读取的操作不同,MongoDB需要通过设置concerned_write=1的方式保证写入成功后,并返回写入后的内容。
  • MongoDB是分布式文档型数据库
  • MongoDB自带连接池能力,pymongo.MongoClient(url, maxPoolSize=maxPoolSize),通过maxPoolSize设置最大连接数,与MySQL不同在于client.get_database().get_collection()无需手动关闭,并且client最好是单例,并且慎用client.close()因为client为单例,close会关闭所有连接。
  • db.createIndex({field1:1,field2:0},{unique:true})
  • db.aggregate([])
  • 备份数据
db.source(复制源表).find().forEach(function(x){

  db.target(目的表).insert(x);

})
  • 集合重命名
db.oldName.renameCollection("newName")
  • findAndModify
https://docs.mongodb.com/v3.4/reference/method/db.collection.findAndModify/#upsert-and-unique-index
upsert标识如果不存在,则创建
new标识返回最新或者创建的结果
  • mongodb shell insert时需要用NumberInt处理 int类型变量,否则默认是浮点
db.test.insert({"uid":NumberInt(1212)})

mongodb添加了倒排索引,query指定命中该索引,查询结果并不会倒排,仍然需要sort进行排序

class BetRecord(CommonCache):
    basename = TableDef.bet_record
    id = "_id"
    uid = "uid"
    team = "team"
    num = "num"  # 投注预测签数量
    bet_ts = "bet_ts"  # 投注时间
    earnings = "earnings"  # 投注收益(真实收益)

    indexes = [[("uid", 1), ("bet_ts", -1)]]   # 此处添加了倒排索引

    def get_bet_records(self, uid):
        query = {self.uid: uid}
        hint = "uid_1_bet_ts_-1"
        sort = [(self.bet_ts, -1),(self.earnings, -1)] # 仍然要用bet_ts做排序
        return self.get_list(query, ttl=Const.minute, sort=sort, hint=hint)

mongodb的嵌套对象如何操作,如下,pymongodb直接操作day_watch_time这个dict的key为1的item,将其值新增

mdb[tb].find_and_modify({"name":"lialong"},{"$inc":{"day_watch_time.1":1}}, {"new": True, "upsert": True})

  • mdb[tb].remove({"name":"lialong"}) pymongodb通过remove方式删除
  • mongodb的disctinct用法,distinct后面加一个字段,如果字段在索引上,则使用索引,如果不在索引,则collectionscan,后面可加query,query可以命中索引,然后在distinct字段上命中distinct_scan
db.actgameminidiary21_user_diary.distinct("day",{"user_uid":21361944})
db.actgameminidiary21_user_diary.explain().distinct("day",{"user_uid":21361944})
  • projection用法:
{"_id":0,"name":1}
  • 多键索引,在mongodb数组字段上创建索引,查询方法如下:
数组内容是dict结构的:
db.getCollection("qiantao2").find({"anchor_uid":1, "member":{"$elemMatch":{"uid":1}}})
数组内容是基础结构:
db.getCollection("gameteamblqx_team_info").explain().find({"captain_uid":21303960, "member":{"$elemMatch": {"$eq": 21313212}})