mongodb及其索引的使用例子

1.获取某个属性最大的value值并自增范例
因为mongo不支持类似select max操作,也不支持递增int的操作,所以采用目前的方案
#找到符合table_name的记录,find输出时只输出type_id,按照type_id递减排序,取到第一个
max_obj =stmt.find({"table_name":table_name},{"type_id":1}).sort("type_id",-1).limit(1)
#max_obj此时仍是cursor
new_id = 1
if max_obj.count()>0:#如果找到max_obj
   new_id = max_obj[0]["type_id"] + 1



2.upsert型存储
stmt = self.db[ALERT_REPORT_TAB]
stmt.update({"phone_number":phone_number},json,upsert=True)


3.mongodb取到update_time字段最大的一条
db.andriod_spider.find().sort({"update_time":-1}).limit(1)

4.mongodb建索引
db.andriod_spider.ensureIndex({"update_time": 1}) #为andriod_spider表建单一索引
db.andriod_spider.ensureIndex({"url": 1,"year":1}) #为andriod_spider表建url和year的联合索引
5.查询所建的索引:
> use spider
switched to db spider
> db.system.indexes.find()
{ "v" : 1, "key" : { "_id" : 1 }, "ns" : "spider.spider_seed", "name" : "_id_" }
{ "v" : 1, "key" : { "_id" : 1 }, "ns" : "spider.andriod_spider", "name" : "_id_" }
{ "v" : 1, "key" : { "update_time" : 1 }, "ns" : "spider.andriod_spider", "name" : "update_time_1" }
{ "v" : 1, "key" : { "url" : 1, "year" : 1 }, "ns" : "spider.andriod_spider", "name" : "url_1_year_1" }
{ "v" : 1, "key" : { "title" : 1, "type" : 1 }, "ns" : "spider.andriod_spider", "name" : "title_1_type_1" }

6.一次mongodb排查问题的过程
有台机器的mongo的CPU占用一直很高

通过db.currentOp()命令发现大量的查询操作是这个


最后通过这一句联合索引搞定,不能单独索引

db.ip_speed.ensureIndex({"start_ip":-1,"end_ip":1})

再次top


看到已经到25%了,成功使用上索引

7.mongo删除数据库
use test_db  #use 要删除的db
db.dropDatabase()


8.为json嵌套格式的内部数据建索引

比如数据的json格式为{"vv_record": [{"update_time":"2013-04-06 01:51:14"}, ...] }等


建立索引后的查询,记得带小数点,如vv_record.update_time

9.mongo查找/删除带指定key的数据
这里演示删除带有vv_record的记录
db.user_profile.remove({"vv_record":{$exists: true} })


[转载]mongodb索引附录:

  索引类型

  虽然MongoDB的索引在存储结构上都是一样的,但是根据不同的应用层需求,还是分成了唯一索引(unique)、稀疏索引(sparse)、多值索引(multikey)等几种类型。

  唯一索引

  唯一索引在创建时加上unique:true 的选项即可,创建命令如下:

db.users.ensureIndex({username: 1}, {unique: true})

  上面的唯一索引创建后,如果insert一条username已经存在的数据,则会报如下的错误:

E11000 duplicate key error index: gardening.users.$username_1 dup key: { : "kbanker" }

  如果你在一个已有数据的collection上创建唯一索引,若唯一索引对应的字段原来就有重复的数据项,那么创建会失败,我们需要加上一个dropDups的选项来强制将重复的项删除掉,命令如下例:

db.users.ensureIndex({username: 1}, {unique: true, dropDups: true})

  松散索引

   如果你的数据中一些行中没有某个字段或字段值为null,那么如果在这个字段上建立普通索引,那么无此字段或值null的行也会参与到索引结构中,占用 相应的空间。如果我们不希望这些值为空的行参与到我们的索引中,这时候可以采用松散索引,松散索引只会让指定字段不为空的行参与到索引创建中来。创建一个 松散索引可以用下面的命令:

db.reviews.ensureIndex({user_id: 1}, {sparse: true})

  多值索引

  MongoDB可以对一个array类型创建索引,比如像下面的结构,MongoDB可以在tags字段上创建索引:

  { name: "Wheelbarrow",
  tags: ["tools", "gardening", "soil"]
  }

  在生成索引时,会为tags中的三个值分别生成三个索引元素,索引中tools,gardening,soil三个值都会指向这同一行数据。相当于分裂成了三个独立的索引项。

  索引管理

  索引的创建和删除

  创建和删除索引的方法有很多种,下面两个是比较原始的方法,通过对system.indexes这个collection进行相应的写操作来完成索引的创建:

  spec = {ns: "green.users", key: {‘addresses.zip’: 1}, name: ‘zip’}
  db.system.indexes.insert(spec, true)

  上面命令往system.indexes中写入一条记录来创建索引,这条记录包含了要在上面创建索引的collection的名字空间,索引的信息,以及索引的名称。

  创建完成后,我们可以通过下面命令找到我们创建的索引:

  db.system.indexes.find()
  { "_id" : ObjectId("4d2205c4051f853d46447e95"), "ns" : "green.users",
  "key" : { "addresses.zip" : 1 }, "name" : "zip", "v" : 0 }

  要删除一个已创建的索引,我们可以使用下面的命令来实现:

  use green
  db.runCommand({deleteIndexes: "users", index: "zip"})

  创建索引命令

  实际上创建索引还有更方便的命令,那就是ensureIndex,比如我们创建一个open和close两个字段的联合索引,就可以用下面的命令:

db.values.ensureIndex({open: 1, close: 1})

  这个命令会触发索引创建的两个过程,一个是将相应的字段排序,因为索引是按B+树来组织的,要构建树,将数据进行排序后能够提高插入B+树的效率(第二个过程的效率),在日志中,你能看到和下面类似的输出:

Tue Jan 4 09:58:17 [conn1] building new index on { open: 1.0, close: 1.0 } for stocks.values
  1000000/4308303 23%
  2000000/4308303 46%
  3000000/4308303 69%
  4000000/4308303 92%
  Tue Jan 4 09:59:13 [conn1] external sort used : 5 files in 55 secs

  第二个过程是将排序好的数据插入到索引结构中,构成可用的索引:

  1200300/4308303 27%
  2227900/4308303 51%
  2837100/4308303 65%
  3278100/4308303 76%
  3783300/4308303 87%
  4075500/4308303 94%
  Tue Jan 4 10:00:16 [conn1] done building bottom layer, going to commit
  Tue Jan 4 10:00:16 [conn1] done for 4308303 records 118.942secs
  Tue Jan 4 10:00:16 [conn1] insert stocks.system.indexes 118942ms

  除了日志中的输出外,你还可以通过在终端执行currentOp命令来获取当前操作线程的相关信息,如下例:

  > db.currentOp()
  {
  "inprog" : [
  {
  "opid" : 58,
  "active" : true,
  "lockType" : "write",
  "waitingForLock" : false,
  "secs_running" : 55,
  "op" : "insert",
  "ns" : "stocks.system.indexes",
  "query" : {
  },
  "client" : "127.0.0.1:53421",
  "desc" : "conn",
  "msg" : "index: (1/3) external sort 3999999/4308303 92%"
  }
  ]
  }

  最后一部分就是一个索引构建过程,目前正在执行排序过程,执行到92%。

  在后台创建索引

   创建索引会对数据库添加写锁,如果数据集比如大,会将线上读写数据库的操作挂起,以等待索引创建结束。这影响了数据库的正常服务,我们可以通过在创建索 引时加background=\‘#\‘" 的选项,让创建工作在后台执行,这时候创建索引还是需要加写锁,但是这个写锁不会直接独占到索引创建完成,而是会暂停为其它读写操作让路,不至于造成严重 的性能影响。具体方法:

db.values.ensureIndex({open: 1, close: 1}, {background=\‘#\‘" /td>

  离线创建索引

   无论如何,索引的创建都会给数据库造成一定的压力,从而影响线上服务。如果希望创建索引的过程完全不影响线上服务,我们可以通过将replica sets中的节点先从集群中剥离,在这个节点上添加相应的索引,等索引添加完毕后再将其添加到replica sets中。这只需要保证一个条件,就是创建索引的时间不能长于oplog能够保存日志的时间,否则创建完后节点再上线发现再也无法追上primary 了,这时会进行resync操作。

  索引备份

  我们知道,无论是使用mongodump还是mongoexport命令,都只是对数据进行备份,无法备份索引。我们在恢复的时候,还是需要等待漫长的索引创建过程。所以,如果你希望备份的时候带上索引,那么最好采用备份数据文件的方式。

  索引压缩

  索引在使用一段时间后,经历增删改等操作,会变得比较松散,从而战用不必要的空间,我们可以通过reindex命令,重新组织索引,让索引的空间占用变得更小。



本文出自 “孤独的编程者” 博客,请务必保留此出处http://lonelyprogram.blog.51cto.com/6246243/1355274

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。