【知识小课堂】mongodb 之 特殊集合及索引

1、固定集合

      一般的集合都是动态的,可以自动增长以容纳越来越多的数据。


MONGODB 还有另外一种集合:固定集合。集合大小创建时指定。如果没有空间了,就会自动删除最老的文档,以释放空间。(类似以一个循环队列)



数据插入是按顺序进行                                              当队列已占满,最老的数据被覆盖                                                                                                        


固定集合 :

它在碟式磁盘上写入速度非常快,尤其是有专用磁盘时(不会被其它集合的一些随机

性写操作而打扰)



示例:

创建:Size:存储空间为: 10,000 kb    Max: 记录数

> db.createCollection("capped_t1",{"capped":true,"size":100000,"max":100});
{ "ok" : 1 }
> for (i = 1; i <= 101; i++){ db.capped_t1.insert({_id:i,name:i+' name'}) }
> db.capped_t1.count()
100


> db.capped_t1.find().sort({_id:-1}).limit(5)
{ "_id" : 101, "name" : "101 name" }
{ "_id" : 100, "name" : "100 name" }
{ "_id" : 99, "name" : "99 name" }
{ "_id" : 98, "name" : "98 name" }
{ "_id" : 97, "name" : "97 name" }
> db.capped_t1.find().sort({_id:1}).limit(5)
{ "_id" : 2, "name" : "2 name" }
{ "_id" : 3, "name" : "3 name" }
{ "_id" : 4, "name" : "4 name" }
{ "_id" : 5, "name" : "5 name" }
{ "_id" : 6, "name" : "6 name" }
> 


我们来 检查一下集合的物理排序顺序 :  (mongodb 里叫自然排序的方法 )

这种方法看到的顺序,就是文档在磁盘上的顺序。


> db.capped_t1.find().sort({$natural:1}).limit(10)
{ "_id" : 2, "name" : "2 name" }
{ "_id" : 3, "name" : "3 name" }
{ "_id" : 4, "name" : "4 name" }
{ "_id" : 5, "name" : "5 name" }
{ "_id" : 6, "name" : "6 name" }
{ "_id" : 7, "name" : "7 name" }
{ "_id" : 8, "name" : "8 name" }
{ "_id" : 9, "name" : "9 name" }
{ "_id" : 10, "name" : "10 name" }
{ "_id" : 11, "name" : "11 name" }
> 


这里 插播一内容


上一讲我们讲到一个[稀疏索引],如果我建立了索引后,按索引走是查询不到没有此字段的数据。

这里我们也可以使用{$natural:1}

指定不用索引强制全表或其它索引搜索。

代码如下:


> db.foo.find({x:{$ne:2}}).hint({$natural:1})  
{ "_id" : 0 }  
{ "_id" : 1, "x" : 1 }  
{ "_id" : 3, "x" : 3 }  
> 

2.循环游标

循环游标类似于 tail –f 命令 ,当循环游标数据被取光后,游标不会被关闭,当有数据插入后,游标还可以取到结果。

$cursor = $collection->find()->tailable();
while (true) {
    if (!$cursor->hasNext()) {
        if ($cursor->dead()) {
            break;
        }
        sleep(1);
    }
    else {
        while ($cursor->hasNext()) {
                   do_stuff($cursor->getNext());
        }
    }
}

(不能在mongodb shell 中使用循环游标)


循环游标如果超过10分钟没有新的数据插入,游标被释放。

3.没有_id 字段??

我们现在使用的集合中,都有个默认的 _id 字段。它使用:唯一值,可以在分布数据库中保持数据文档的唯一性。

但如果我数据不修改,只插入,也不管它是不是唯一
指定:  {autoIndexId:false} 可以建立无 _id 集合

优点:性能有稍许提升;
缺点:集合无法复制;


4.TTL索引


使用TTL 可以设置一个时间范围,如果到了此范围,文档被删除。(开始我理解错误,一直以为TTL 是使用在固定集合中的一个索引,并测试一直发现索引无效,经多次测试,才发现,自己理解错误)


db.log_events.ensureIndex( { "createdAt": 1 }, { expireAfterSeconds: 3600 } )

> db.log_events.find({},{createdAt:1,_id:0})
{ "createdAt" : ISODate("2014-07-28T03:59:46.824Z") }
{ "createdAt" : ISODate("2014-07-28T04:01:36.816Z") }
> db.log_events.insert( {    "createdAt": new Date('2014,07,28'),    "logEvent": 2,    "logMessage": "Success!" } )
> db.log_events.find({},{createdAt:1,_id:0})
{ "createdAt" : ISODate("2014-07-28T03:59:46.824Z") }
{ "createdAt" : ISODate("2014-07-28T04:01:36.816Z") }
{ "createdAt" : ISODate("2014-07-27T16:00:00Z") }
 > db.log_events.find({},{createdAt:1,_id:0})
{ "createdAt" : ISODate("2014-07-28T03:59:46.824Z") }
{ "createdAt" : ISODate("2014-07-28T04:01:36.816Z") }
> > new Date()
ISODate("2014-07-28T05:33:15.398Z")
> db.log_events.find({},{createdAt:1,_id:0})
> 

建立索引后,插入数据,并测试查看经过一段时间后,数据已清空。



注意,开始照:MONGODB 权威指南书里的实验来做,简写成:{expireAfterSecs:3600} 是无效的。
实验如下:
> db.bid.insert({_id:1,create_dt:new Date('2014,08,01')})
> db.bid.insert({_id:2,create_dt:new Date('2014,11,01')})
> db.bid.ensureIndex({create_dt:1},{"expireAfterSecs":60*60*24*14})
> db.bid.getIndexes()
[
	{
		"v" : 1,
		"key" : {
			"_id" : 1
		},
		"ns" : "test.bid",
		"name" : "_id_"
	},
	{
		"v" : 1,
		"key" : {
			"create_dt" : 1
		},
		"ns" : "test.bid",
		"name" : "create_dt_1",
		"expireAfterSecs" : 1209600
	}
]
> db.bid.find()
{ "_id" : 1, "create_dt" : ISODate("2014-07-31T16:00:00Z") }
{ "_id" : 2, "create_dt" : ISODate("2014-10-31T16:00:00Z") }
> db.bid.find()
{ "_id" : 1, "create_dt" : ISODate("2014-07-31T16:00:00Z") }
{ "_id" : 2, "create_dt" : ISODate("2014-10-31T16:00:00Z") }
> db.bid.find()
{ "_id" : 1, "create_dt" : ISODate("2014-07-31T16:00:00Z") }
{ "_id" : 2, "create_dt" : ISODate("2014-10-31T16:00:00Z") }
> db.bid.find()
{ "_id" : 1, "create_dt" : ISODate("2014-07-31T16:00:00Z") }
{ "_id" : 2, "create_dt" : ISODate("2014-10-31T16:00:00Z") }
> db.bid.find()
{ "_id" : 1, "create_dt" : ISODate("2014-07-31T16:00:00Z") }
{ "_id" : 2, "create_dt" : ISODate("2014-10-31T16:00:00Z") }
> db.bid.find()
{ "_id" : 1, "create_dt" : ISODate("2014-07-31T16:00:00Z") }
{ "_id" : 2, "create_dt" : ISODate("2014-10-31T16:00:00Z") }
> db.bid.find()
{ "_id" : 1, "create_dt" : ISODate("2014-07-31T16:00:00Z") }
{ "_id" : 2, "create_dt" : ISODate("2014-10-31T16:00:00Z") }
> db.runCommand({"collMod":"someapp.cache","expireAfterSecs":60})
{ "ok" : 0, "errmsg" : "ns does not exist" }
> db.runCommand({"collMod":"someapp.cache","expireAfterSecs":60})
{ "ok" : 0, "errmsg" : "ns does not exist" }
> db.bid.find()
{ "_id" : 1, "create_dt" : ISODate("2014-07-31T16:00:00Z") }
{ "_id" : 2, "create_dt" : ISODate("2014-10-31T16:00:00Z") }
> db.bid.find()
{ "_id" : 1, "create_dt" : ISODate("2014-07-31T16:00:00Z") }
{ "_id" : 2, "create_dt" : ISODate("2014-10-31T16:00:00Z") }
> db.bid.find()
{ "_id" : 1, "create_dt" : ISODate("2014-07-31T16:00:00Z") }
{ "_id" : 2, "create_dt" : ISODate("2014-10-31T16:00:00Z") }
> db.bid.find()
{ "_id" : 1, "create_dt" : ISODate("2014-07-31T16:00:00Z") }
{ "_id" : 2, "create_dt" : ISODate("2014-10-31T16:00:00Z") }
> db.bid.find()
{ "_id" : 1, "create_dt" : ISODate("2014-07-31T16:00:00Z") }
{ "_id" : 2, "create_dt" : ISODate("2014-10-31T16:00:00Z") }
> db.bid.find()
{ "_id" : 1, "create_dt" : ISODate("2014-07-31T16:00:00Z") }
{ "_id" : 2, "create_dt" : ISODate("2014-10-31T16:00:00Z") }
> db.bid.find()
{ "_id" : 1, "create_dt" : ISODate("2014-07-31T16:00:00Z") }
{ "_id" : 2, "create_dt" : ISODate("2014-10-31T16:00:00Z") }
> db.bid.getIndexes()
[
	{
		"v" : 1,
		"key" : {
			"_id" : 1
		},
		"ns" : "test.bid",
		"name" : "_id_"
	},
	{
		"v" : 1,
		"key" : {
			"create_dt" : 1
		},
		"ns" : "test.bid",
		"name" : "create_dt_1",
		"expireAfterSecs" : 1209600
	}
]
> db.bid.dropIndex("create_dt_1")
{ "nIndexesWas" : 2, "ok" : 1 }
> db.bid.getIndexes()
[
	{
		"v" : 1,
		"key" : {
			"_id" : 1
		},
		"ns" : "test.bid",
		"name" : "_id_"
	}
]
> db.log_events.ensureIndex( { "createdAt": 1 }, { expireAfterSeconds: 3600 } )
> db.bid.ensureIndex( { "create_dt": 1 }, { expireAfterSeconds: 3600 } )
> db.bid.find()
{ "_id" : 1, "create_dt" : ISODate("2014-07-31T16:00:00Z") }
{ "_id" : 2, "create_dt" : ISODate("2014-10-31T16:00:00Z") }
> db.bid.find()
{ "_id" : 1, "create_dt" : ISODate("2014-07-31T16:00:00Z") }
{ "_id" : 2, "create_dt" : ISODate("2014-10-31T16:00:00Z") }
> db.bid.find()
{ "_id" : 1, "create_dt" : ISODate("2014-07-31T16:00:00Z") }
{ "_id" : 2, "create_dt" : ISODate("2014-10-31T16:00:00Z") }
> db.bid.getIndexes()
[
	{
		"v" : 1,
		"key" : {
			"_id" : 1
		},
		"ns" : "test.bid",
		"name" : "_id_"
	},
	{
		"v" : 1,
		"key" : {
			"create_dt" : 1
		},
		"ns" : "test.bid",
		"name" : "create_dt_1",
		"expireAfterSeconds" : 3600
	}
]
> db.bid.getIndexes()
[
	{
		"v" : 1,
		"key" : {
			"_id" : 1
		},
		"ns" : "test.bid",
		"name" : "_id_"
	},
	{
		"v" : 1,
		"key" : {
			"create_dt" : 1
		},
		"ns" : "test.bid",
		"name" : "create_dt_1",
		"expireAfterSeconds" : 3600
	}
]
> db.bid.find()
{ "_id" : 1, "create_dt" : ISODate("2014-07-31T16:00:00Z") }
{ "_id" : 2, "create_dt" : ISODate("2014-10-31T16:00:00Z") }
> new Date()
ISODate("2014-11-05T03:10:34.828Z")
> db.bid.find()
{ "_id" : 1, "create_dt" : ISODate("2014-07-31T16:00:00Z") }
{ "_id" : 2, "create_dt" : ISODate("2014-10-31T16:00:00Z") }
> db.bid.find()
> db.bid.find()
> db.bid.dropIndex("create_dt_1")
{ "nIndexesWas" : 2, "ok" : 1 }
> db.bid.ensureIndex( { "create_dt": 1 }, { expireAfterSeconds: 3600*14 } )
> db.bid.insert({_id:1,create_dt:new Date('2014,08,01')})
> db.bid.insert({_id:1,create_dt:new Date('2014,01,01')})
E11000 duplicate key error index: test.bid.$_id_  dup key: { : 1.0 }
> db.bid.insert({_id:2,create_dt:new Date('2014,01,01')})
> db.bid.insert({_id:3,create_dt:new Date('2014,11,01')})
> db.bid.getIndexes()
[
	{
		"v" : 1,
		"key" : {
			"_id" : 1
		},
		"ns" : "test.bid",
		"name" : "_id_"
	},
	{
		"v" : 1,
		"key" : {
			"create_dt" : 1
		},
		"ns" : "test.bid",
		"name" : "create_dt_1",
		"expireAfterSeconds" : 50400
	}
]
> db.bid.dropIndex("create_dt_1")
{ "nIndexesWas" : 2, "ok" : 1 }
> db.bid.ensureIndex( { "create_dt": 1 }, { expireAfterSeconds: 3600*24*14 } )
> db.bid.getIndexes()
[
	{
		"v" : 1,
		"key" : {
			"_id" : 1
		},
		"ns" : "test.bid",
		"name" : "_id_"
	},
	{
		"v" : 1,
		"key" : {
			"create_dt" : 1
		},
		"ns" : "test.bid",
		"name" : "create_dt_1",
		"expireAfterSeconds" : 1209600
	}
]
> db.bid.find()
> db.bid.find()
> db.bid.insert({_id:3,create_dt:new Date('2014,11,01')})
> db.bid.find()
{ "_id" : 3, "create_dt" : ISODate("2014-10-31T16:00:00Z") }
> db.bid.insert({_id:2,create_dt:new Date('2014,01,01')})
> db.bid.find()
{ "_id" : 3, "create_dt" : ISODate("2014-10-31T16:00:00Z") }
{ "_id" : 2, "create_dt" : ISODate("2013-12-31T16:00:00Z") }
> db.bid.find()
{ "_id" : 3, "create_dt" : ISODate("2014-10-31T16:00:00Z") }
{ "_id" : 2, "create_dt" : ISODate("2013-12-31T16:00:00Z") }
> db.bid.find()
{ "_id" : 3, "create_dt" : ISODate("2014-10-31T16:00:00Z") }
{ "_id" : 2, "create_dt" : ISODate("2013-12-31T16:00:00Z") }
> db.bid.find()
{ "_id" : 3, "create_dt" : ISODate("2014-10-31T16:00:00Z") }
{ "_id" : 2, "create_dt" : ISODate("2013-12-31T16:00:00Z") }
> db.bid.find()
{ "_id" : 3, "create_dt" : ISODate("2014-10-31T16:00:00Z") }
{ "_id" : 2, "create_dt" : ISODate("2013-12-31T16:00:00Z") }
> db.bid.find()
{ "_id" : 3, "create_dt" : ISODate("2014-10-31T16:00:00Z") }
{ "_id" : 2, "create_dt" : ISODate("2013-12-31T16:00:00Z") }
> db.bid.find()
{ "_id" : 3, "create_dt" : ISODate("2014-10-31T16:00:00Z") }
> db.bid.find()
{ "_id" : 3, "create_dt" : ISODate("2014-10-31T16:00:00Z") }
> 






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值