猿教程 Logo

.Net连接MongoDb:索引选项

阿里云服务器,每月低至7.8元,项目演示即建站必备,比腾讯云更便宜,并且不需学生认证,从此链接购买有效:去购买

介绍

在上一篇文章中,我们调查了如何在子文档中创建索引。 在查询子文档时看到的点符号也提供了深度索引的语法。 我们也很快看到如何检索集合的所有索引。 另外我们了解到,数组索引在MongoDb中称为多键索引。 explain函数返回的查询计划显示用于查询执行的某个索引是否为多键。

在这篇文章中,我们将介绍创建索引时可用的几个选项。

索引名称

我们已经看过这个了。 我们可以为索引添加一个名称,该名称覆盖了我的MongoDb的默认名称。 我们在上一篇文章中创建了一个小人物集合。 如果您没有,请使用上述链接导航回上一部分并创建集合。

我们在名称字段上创建一个索引,并给索引一个名字:

db.people.createIndex({"name" : 1}, {"name" : "index-on-name"})

我们可以使用创建它的JSON来删除此索引:

db.people.dropIndex({"name" : 1})

...或者您可以通过其名称作为字符串参数来引用它:

db.people.dropIndex("index-on-name")

唯一索引

说你只想拥有特定字段的唯一值。 例如。 你可能不想在集合中有两个同名的客户。 在传统的SQL数据库中,MongoDb中没有UNIQUE约束。 相反,我们可以创建一个唯一的索引。 考虑以下小公司收藏:

use model
db.companies.insert({"name" : "Sony", "phone" : "1234"})
db.companies.insert({"name" : "Microsoft", "phone" : "9876"})
db.companies.insert({"name" : "Ericsson", "phone" : "45765"})
db.companies.insert({"name" : "Apple", "phone" : "42454746"})
db.companies.insert({"name" : "10gen", "phone" : "9283746"})
db.companies.insert({"name" : "Atlassian"})

我们希望保持名称唯一。 独特的选项提供了解决方案:

db.companies.createIndex({"name" : 1}, {"unique" : true})

如果我们尝试添加一个现有公司名称的新帖子...:

db.companies.insert({"name" : "Sony", "phone" : "1234"})

那么我们得到一个响亮的NO:

WriteResult({
        "nInserted" : 0,
        "writeError" : {
                "code" : 11000,
                "errmsg" : "E11000 duplicate key error collection: model.companies index: name_1 dup key: { : \"Sony\" }"
        }
})

稀疏索引

稀疏选项与唯一索引结合使用。 考虑上述公司文件中的手机财产。 他们当然是独一无二的,但Atlassian没有定义手机,即它是空的。

我们将在电话领域创建一个唯一的索引:

db.companies.createIndex({"phone" : 1}, {"unique" : true})

没关系,创建索引。 我们现在想添加一个还没有电话号码的新公司:

db.companies.insert({"name" : "General Motors"})

我们被拒绝

E11000重复键错误收集:model.companies index:phone_1 dup key:{:null}

这是为什么? 上述文档缺少电话字段,即它是空的。 但是,我们已经拥有一个空值较大的文档,因此我们面临着重复的问题。

该解决方案采用稀疏索引的形式。 稀疏索引不会索引缺少索引字段的文档。

我们首先删除上面的索引:

db.companies.dropIndex({"phone" : 1})

...并使用稀疏选项重新创建它:

db.companies.createIndex({"phone" : 1}, {"unique" : true, "sparse" : true})

我们现在可以插入通用汽车:

db.companies.insert({"name" : "General Motors"})

我们可以很容易地证明没有电话领域的两个文件没有编入索引。 我们先使用explain函数查询具体的电话号码:

db.companies.explain(true).find({"phone" : "1234"})

我们将看到一个索引扫描阶段,并且该文档已经被扫描并且还被返回。

但是,如果我们搜索缺少电话号码的文档:

db.companies.explain(true).find({"phone" : null})

...然后我们会看到执行了总的收集扫描。 所有7份文件均已审查,2份归档。

背景索引创建

默认情况下,在MongoDb的前台线程中创建索引。 这意味着索引创建具有优先级,而索引创建过程正在运行,所有其他读取和写入都将在数据库中被阻止。 如果创建索引需要很长时间,那么您可以无意中锁定整个依赖数据库的应用程序。

避免这种情况的一个选择是让索引创建在具有较低优先级的后台线程上运行。 读写不会被阻止。 但是,与在前台线程上创建索引相比,该过程也将花费更长的时间。 为此,背景选项可以设置为true:

db.companies.createIndex({"name" : 1}, {"unique" : true, "background" : true})

在下一篇文章中,我们将再来看一些关于explain函数返回的查询计划的其他部分。

阿里云服务器,每月低至7.8元,项目演示即建站必备,比腾讯云更便宜,并且不需学生认证,从此链接购买有效: 去购买


版权声明:本站所有教程均为本站原创或翻译,转载请注明出处,请尊重他人劳动果实。请记住本站地址:www.yuanjiaocheng.net (猿教程) 作者:卿文刚
本文标题: C#环境
本文地址:http://www.yuanjiaocheng.net/CsharpMongo/35.html