Mongodb 简明教程
MongoDB - Advanced Indexing
我们已按照如下方式在名为 users 的集合中插入下列文档:
we have inserted the following document in the collection named users as shown below −
db.users.insert(
{
"address": {
"city": "Los Angeles",
"state": "California",
"pincode": "123"
},
"tags": [
"music",
"cricket",
"blogs"
],
"name": "Tom Benzamin"
}
)
上述文档包含一个 address sub-document 和一个 tags array 。
The above document contains an address sub-document and a tags array.
Indexing Array Fields
假设我们希望根据用户的标签搜索用户文档。为此,我们将在集合中的 tags 数组上创建一个索引。
Suppose we want to search user documents based on the user’s tags. For this, we will create an index on tags array in the collection.
依次在数组上创建索引会针对其每个字段创建单独的索引项。因此,当我们在 tags 数组上创建索引时,将针对其值 music、cricket 和 blogs 创建单独的索引。
Creating an index on array in turn creates separate index entries for each of its fields. So in our case when we create an index on tags array, separate indexes will be created for its values music, cricket and blogs.
若要针对 tags 数组创建索引,请使用下列代码:
To create an index on tags array, use the following code −
>db.users.createIndex({"tags":1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 2,
"numIndexesAfter" : 3,
"ok" : 1
}
>
创建索引后,我们可以像这样搜索集合的 tags 字段:
After creating the index, we can search on the tags field of the collection like this −
> db.users.find({tags:"cricket"}).pretty()
{
"_id" : ObjectId("5dd7c927f1dd4583e7103fdf"),
"address" : {
"city" : "Los Angeles",
"state" : "California",
"pincode" : "123"
},
"tags" : [
"music",
"cricket",
"blogs"
],
"name" : "Tom Benzamin"
}
>
若要验证使用了正确的索引,请使用下列 explain 命令:
To verify that proper indexing is used, use the following explain command −
>db.users.find({tags:"cricket"}).explain()
这会生成下列结果:
This gives you the following result −
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "mydb.users",
"indexFilterSet" : false,
"parsedQuery" : {
"tags" : {
"$eq" : "cricket"
}
},
"queryHash" : "9D3B61A7",
"planCacheKey" : "04C9997B",
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"tags" : 1
},
"indexName" : "tags_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"tags" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"tags" : [
"[\"cricket\", \"cricket\"]"
]
}
}
},
"rejectedPlans" : [ ]
},
"serverInfo" : {
"host" : "Krishna",
"port" : 27017,
"version" : "4.2.1",
"gitVersion" : "edf6d45851c0b9ee15548f0f847df141764a317e"
},
"ok" : 1
}
>
上述命令生成的 "cursor" : "BtreeCursor tags_1" 证实使用了正确的索引。
The above command resulted in "cursor" : "BtreeCursor tags_1" which confirms that proper indexing is used.
Indexing Sub-Document Fields
假设我们希望根据 city、state 和 pincode 字段搜索文档。由于所有这些字段都是 address 子文档字段的一部分,我们将针对子文档的所有字段创建一个索引。
Suppose that we want to search documents based on city, state and pincode fields. Since all these fields are part of address sub-document field, we will create an index on all the fields of the sub-document.
若要针对子文档的所有三个字段创建索引,请使用下列代码:
For creating an index on all the three fields of the sub-document, use the following code −
>db.users.createIndex({"address.city":1,"address.state":1,"address.pincode":1})
{
"numIndexesBefore" : 4,
"numIndexesAfter" : 4,
"note" : "all indexes already exist",
"ok" : 1
}
>
在创建索引后,我们可以利用这个索引搜索任何子文档字段,如下: −
Once the index is created, we can search for any of the sub-document fields utilizing this index as follows −
> db.users.find({"address.city":"Los Angeles"}).pretty()
{
"_id" : ObjectId("5dd7c927f1dd4583e7103fdf"),
"address" : {
"city" : "Los Angeles",
"state" : "California",
"pincode" : "123"
},
"tags" : [
"music",
"cricket",
"blogs"
],
"name" : "Tom Benzamin"
}
记住,查询表达式必须遵循指定的索引顺序。因此,上面创建的索引将支持以下查询 −
Remember that the query expression has to follow the order of the index specified. So the index created above would support the following queries −
>db.users.find({"address.city":"Los Angeles","address.state":"California"}).pretty()
{
"_id" : ObjectId("5dd7c927f1dd4583e7103fdf"),
"address" : {
"city" : "Los Angeles",
"state" : "California",
"pincode" : "123"
},
"tags" : [
"music",
"cricket",
"blogs"
],
"name" : "Tom Benzamin"
}
>