Mongodb特殊索引和集合

1.参考

MongoDB权威指南(第2版)

Mongodb Docs

2.特殊集合

2.1.封顶集合

封顶集合和普通集合不一样,普通集合的大小是可以随着数据的增加而增加的,封顶集合是在创建的时候就已经设置了集合的大小。

封顶集合的大小已经满了后,当再次插入数据的时候,它会把最老的数据丢掉,然后写入新数据,封顶集合不难看出很适合当log型数据库。

2.1.1.创建封顶集合

创建封顶集合我们需要显式的创建集合,因为需要在显式创建的方法中设置一些选项,同时我们需要在选项中设置两个选项cappedsize

db.createCollection('test', {
    capped: true,
    size: 10485760
})

上面的代码中capped设置为true代表创建的文档是一个封顶文档,而设置了cappedtrue后,必须指定size选项,size选项是指定的固定集合的大小,单位为字节(Byte)。

除此这两个设置外,还可以指定max选项,设置它过后,可以控制总体文档的数量,如果超过设置的数量,就把最老的数据丢掉,写入新数据。

db.createCollection('test', {
    capped: true,
    size: 10485760,
    max: 5000
})

上面的代码设置了三个选项,其中一个表示创建封顶集合,一个是封顶集合的大小,还有一个是封顶集合的最大文档数量。集合的大小和集合的文档数量,只要其中一个条件满足都会从最老的数据位置开始覆盖写入。

需要注意的是封顶集合一旦创建就不能在改变,只有通过删除此集合然后在新建。

封顶集合的自然排序是由旧到新的,如果我们需要由新到旧的顺序查询我们的文档,我们可以通过下面的代码来执行:

db.test.find({}).sort({$natural: -1});

2.2.文档验证集合

我们在创建集合的时候可以通过设置一个或多个键的值验证机制,这样当写入数据的时候,Mongodb会进行验证,如果通过则写入,如果没有通过则抛出错误,设置验证文档通过validator选项,它接受一个对象,在里面可以使用元操作符$

比如下面的代码我设置了一个文档必须设置一个name值,并且值必须为String类型:

db.createCollection('blog', {
    validator: {
        name: { $type: 'string' }
    }
});

然后我们试着插入一个带name的文档但值为数值和插入一个带name的文档值为字符串类型。

> db.blog.insert({name: 123, age: 18})
WriteResult({
    "nInserted" : 0,
    "writeError" : {
        "code" : 121,
        "errmsg" : "Document failed validation"
    }
})

从上面的返回中可以看到错误消息提示的是文档验证失败,而我们试着插入一个合法的数据看看返回的是什么:

> db.blog.insert({name: '123', age: 18})
WriteResult({ "nInserted" : 1 })

2.2.1.查看集合验证

设置了验证后,我们可以通过官方提供的getCollectionInfos()方法来查看数据库上面哪些集合设置了文档验证,它有一个可选参数,接受一个对象,其中name的值代表集合名称,可以获取指定集合的文档验证:

db.getCollectionInfos();

它返回的大概内容为:

[
    {
        "name" : "blog",
        "type" : "collection",
        "options" : {
            "validator" : {
                "name" : {
                    "$type" : "string"
                }
            }
        },
        "info" : {
            "readOnly" : false
        },
        "idIndex" : {
            "v" : 2,
            "key" : {
                "_id" : 1
            },
            "name" : "_id_",
            "ns" : "blog.blog"
        }
    },
    {
        "name" : "test",
        "type" : "collection",
        "options" : {

        },
        "info" : {
            "readOnly" : false
        },
        "idIndex" : {
            "v" : 2,
            "key" : {
                "_id" : 1
            },
            "name" : "_id_",
            "ns" : "blog.test"
        }
    }
]

其中我们可以看见options里面的validator中含有我们的验证信息,我们可以获取指定集合的文档验证信息:

db.getCollectionInfos({name: 'blog'});

返回的信息:

[
    {
        "name" : "blog",
        "type" : "collection",
        "options" : {
            "validator" : {
                "name" : {
                    "$type" : "string"
                }
            }
        },
        "info" : {
            "readOnly" : false
        },
        "idIndex" : {
            "v" : 2,
            "key" : {
                "_id" : 1
            },
            "name" : "_id_",
            "ns" : "blog.blog"
        }
    }
]

如果你需要禁用这个文档的验证,你可以通过执行命令来设置validationLevel的值为off,如果validationLevel的值为strict,则默认开始所有文档验证,其中collMod的值是集合的名称,可以把这个理解为collection mod集合修改

db.runCommand({collMod: 'blog', validationLevel: 'off'});

在创建集合中还有很多选项,我这里只是拿出了一小部分常用的、容易理解的选项出来说,如果对其他选项有兴趣可以查看官方文档

3.特殊索引

3.1.TTL索引

TTL索引会给所有的文档设置一个过期时间,如果一旦过期,文档将会删除,设置一个TTL索引的方式如下:

db.blog.createIndex({da: 1}, { expireAfterSeconds: 10 });

文档内容:

{
    da: new Date(),
    s: 1
}

设置索引的键必须为日期类型的值,expireAfterSeconds键的值表示过期时间,以秒为单位。

这个设置将影响集合中所有文档,包括之前的所有文档,比如上面设置的10秒后过期,那么所有的文档将在10秒后过期,如果需要续期,就可以更新TTL索引的键的值为最新时间即可,这个常用于会话。

3.2.文本索引

文本索引需要将索引的键的值设置为字符串text,并且一个集合只能有一个文本索引,但是可以组合一个复合的文本索引,在查询的过程中,使用$text运算符对所有文本索引的键的值进行查询:

db.blog.insert({a: 'asd789'});

db.blog.createIndex({a: 'text'});

db.blog.find({$text: {$search: 'asd789'}});

文本索引会造成当前的集合更加缓慢,因为它是把索引的键的值全部索引,所以尽可能的少用文本索引。

文完

文档信息