Skip to content

Commit c04c3f0

Browse files
authored
Merge pull request #109279 from timsander1/master
update mongodb api indexing doc
2 parents ba20bfe + c0de36e commit c04c3f0

File tree

1 file changed

+134
-86
lines changed

1 file changed

+134
-86
lines changed

articles/cosmos-db/mongodb-indexing.md

Lines changed: 134 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -5,60 +5,160 @@ ms.service: cosmos-db
55
ms.subservice: cosmosdb-mongo
66
ms.devlang: nodejs
77
ms.topic: conceptual
8-
ms.date: 12/26/2018
9-
author: sivethe
10-
ms.author: sivethe
8+
ms.date: 03/27/2020
9+
author: timsander1
10+
ms.author: tisande
1111

1212
---
13-
14-
1513
# Indexing using Azure Cosmos DB's API for MongoDB
1614

17-
Azure Cosmos DB's API for MongoDB leverages automatic index management capabilities of Cosmos DB. As a result, users have access to the default indexing policies of Cosmos DB. So, if no indexes have been defined by the user, or no indexes have been dropped, then all fields will be automatically indexed by default when inserted into a collection. For most scenarios, we recommend using the default indexing policy set on the account.
15+
Azure Cosmos DB's API for MongoDB leverages the core index management capabilities of Azure Cosmos DB. This document focuses on how to add indexes using Azure Cosmos DB's API for MongoDB. You can also read an [overview of indexing in Azure Cosmos DB](index-overview.md) that is relevant across all API's.
1816

1917
## Indexing for version 3.6
2018

21-
Accounts serving wire protocol version 3.6 provide a different default indexing policy than the policy provided by earlier versions. By default, only the _id field is indexed. To index additional fields, the user must apply the MongoDB index management commands. To apply a sort to a query, currently an index must be created on the fields used in the sort operation.
19+
The `_id` field is always automatically indexed and cannot be dropped. Azure Cosmos DB's API for MongoDB automatically enforces uniqueness of the `_id` field per shard key.
20+
21+
To index additional fields, you should apply the MongoDB index management commands. As in MongoDB, only the `_id` field is indexed automatically. This default indexing policy is different from the Azure Cosmos DB SQL API, which indexes all fields by default.
22+
23+
To apply a sort to a query, an index must be created on the fields used in the sort operation.
24+
25+
## Index types
26+
27+
### Single field
28+
29+
You can create indexes on any single field. The sort order of the single field index does not matter. The following command will create an index on the field `name`:
30+
31+
`db.coll.createIndex({name:1})`
32+
33+
One query will utilize multiple single field indexes, where available.
2234

23-
### Dropping the default indexes (3.6)
35+
### Compound indexes (3.6)
2436

25-
For accounts serving wire protocol version 3.6, the only default index is _id, which cannot be dropped.
37+
Compound indexes are supported for accounts using the 3.6 wire protocol. You can include up to 8 fields in a compound index. Unlike in MongoDB, you should only create a compound index if your query needs to sort efficiently on multiple fields at once. For queries with multiple filters that don't need to sort, you should create multiple single field indexes instead of one single compound index.
2638

27-
### Creating a compound index (3.6)
39+
The following command will create a compound index on the fields `name` and `age`:
2840

29-
True compound indexes are supported for accounts using the 3.6 wire protocol. The following command will create a compound index on the fields 'a' and 'b':
30-
`db.coll.createIndex({a:1,b:1})`
41+
`db.coll.createIndex({name:1,age:1})`
3142

3243
Compound indexes can be used to sort efficiently on multiple fields at once, such as:
33-
`db.coll.find().sort({a:1,b:1})`
3444

35-
### Track the index progress
45+
`db.coll.find().sort({name:1,age:1})`
46+
47+
The above compound index can also be used for efficient sorting on a query with the opposite sort order on all fields. Here's an example:
48+
49+
`db.coll.find().sort({name:-1,age:-1})`
50+
51+
However, the sequence of the paths in the compound index must exactly match the query. Here's an example of a query that would require an additional compound index:
52+
53+
`db.coll.find().sort({age:1,name:1})`
54+
55+
### Multikey indexes
56+
57+
Azure Cosmos DB creates multikey indexes to index content stored in arrays. If you index a field with an array value, Azure Cosmos DB automatically indexes every element in the array.
58+
59+
### Geospatial indexes
60+
61+
Many geospatial operators will benefit from geospatial indexes. Currently, Azure Cosmos DB's API for MongoDB supports `2dsphere` indexes. `2d` indexes are not yet supported.
62+
63+
Here's an example for creating a geospatial index on the `location` field:
64+
65+
`db.coll.createIndex({ location : "2dsphere" })`
66+
67+
### Text indexes
68+
69+
Text indexes are not currently supported. For text search queries on strings, you should use [Azure Cognitive Search's](https://docs.microsoft.com/azure/search/search-howto-index-cosmosdb) integration with Azure Cosmos DB.
70+
71+
## Index properties
72+
73+
The following operations are common for both accounts serving wire protocol version 3.6 and accounts serving earlier wire protocol versions. You can also learn more about [supported indexes and indexed properties](mongodb-feature-support-36.md#indexes-and-index-properties).
74+
75+
### Unique indexes
76+
77+
[Unique indexes](unique-keys.md) are useful for enforcing that no two or more documents contain the same value for the indexed field(s).
78+
79+
>[!Important]
80+
> Unique indexes can be created only when the collection is empty (contains no documents).
81+
82+
The following command creates a unique index on the field "student_id":
83+
84+
```shell
85+
globaldb:PRIMARY> db.coll.createIndex( { "student_id" : 1 }, {unique:true} )
86+
{
87+
"_t" : "CreateIndexesResponse",
88+
"ok" : 1,
89+
"createdCollectionAutomatically" : false,
90+
"numIndexesBefore" : 1,
91+
"numIndexesAfter" : 4
92+
}
93+
```
94+
95+
For sharded collections, creating a unique index requires providing the shard (partition) key. In other words, all unique indexes on a sharded collection are compound indexes where one of the fields is the partition key.
96+
97+
The following commands create a sharded collection ```coll``` (shard key is ```university```) with a unique index on fields student_id and university:
98+
99+
```shell
100+
globaldb:PRIMARY> db.runCommand({shardCollection: db.coll._fullName, key: { university: "hashed"}});
101+
{
102+
"_t" : "ShardCollectionResponse",
103+
"ok" : 1,
104+
"collectionsharded" : "test.coll"
105+
}
106+
globaldb:PRIMARY> db.coll.createIndex( { "student_id" : 1, "university" : 1 }, {unique:true})
107+
{
108+
"_t" : "CreateIndexesResponse",
109+
"ok" : 1,
110+
"createdCollectionAutomatically" : false,
111+
"numIndexesBefore" : 3,
112+
"numIndexesAfter" : 4
113+
}
114+
```
115+
116+
In the above example, if ```"university":1``` clause was omitted, an error with the following message would be returned:
117+
118+
```"cannot create unique index over {student_id : 1.0} with shard key pattern { university : 1.0 }"```
119+
120+
### TTL indexes
121+
122+
To enable document expiration in a particular collection, a ["TTL index" (time-to-live index)](../cosmos-db/time-to-live.md) needs to be created. A TTL index is an index on the _ts field with an "expireAfterSeconds" value.
123+
124+
Example:
125+
126+
```JavaScript
127+
globaldb:PRIMARY> db.coll.createIndex({"_ts":1}, {expireAfterSeconds: 10})
128+
```
129+
130+
The preceding command will cause the deletion of any documents in ```db.coll``` collection that have not been modified in the last 10 seconds.
131+
132+
> [!NOTE]
133+
> **_ts** is an Azure Cosmos DB-specific field and is not accessible from MongoDB clients. It is a reserved (system) property that contains the timestamp of the document's last modification.
134+
135+
## Track the index progress
36136
37137
The 3.6 version of Azure Cosmos DB's API for MongoDB accounts support the `currentOp()` command to track index progress on a database instance. This command returns a document that contains information about the in-progress operations on a database instance. The `currentOp` command is used to track all the in-progress operations in native MongoDB whereas in Azure Cosmos DB's API for MongoDB, this command only supports tracking the index operation.
38138
39139
Here are some examples that show how to use the `currentOp` command to track the index progress:
40140
41-
Get the index progress for a collection:
141+
* Get the index progress for a collection:
42142
43143
```shell
44144
db.currentOp({"command.createIndexes": <collectionName>, "command.$db": <databaseName>})
45145
```
46146
47-
Get the index progress for all the collections in a database:
147+
* Get the index progress for all the collections in a database:
48148
49149
```shell
50150
db.currentOp({"command.$db": <databaseName>})
51151
```
52152
53-
Get the index progress for all the databases and collections in an Azure Cosmos account:
153+
* Get the index progress for all the databases and collections in an Azure Cosmos account:
54154
55155
```shell
56156
db.currentOp({"command.createIndexes": { $exists : true } })
57157
```
58158
59159
The index progress details contain percentage of progress for the current index operation. The following example shows the output document format for different stages of index progress:
60160
61-
1. If the index operation on a foo collection and bar database that has 60 % indexing complete will have the following output document. `Inprog[0].progress.total` shows 100 as the target completion.
161+
1. If the index operation on a 'foo' collection and 'bar' database that has 60 % indexing complete will have the following output document. `Inprog[0].progress.total` shows 100 as the target completion.
62162
63163
```json
64164
{
@@ -82,7 +182,7 @@ The index progress details contain percentage of progress for the current index
82182
}
83183
```
84184
85-
2. For an index operation that has just started on a foo collection and bar database, the output document may show 0% progress until it reaches to a measurable level.
185+
2. For an index operation that has just started on a 'foo' collection and 'bar' database, the output document may show 0% progress until it reaches to a measurable level.
86186
87187
```json
88188
{
@@ -115,88 +215,36 @@ The index progress details contain percentage of progress for the current index
115215
}
116216
```
117217
118-
## Indexing for version 3.2
119-
120-
### Dropping the default indexes (3.2)
121-
122-
The following command can be used to drop the default indexes for a collection ```coll```:
123-
124-
```JavaScript
125-
> db.coll.dropIndexes()
126-
{ "_t" : "DropIndexesResponse", "ok" : 1, "nIndexesWas" : 3 }
127-
```
128-
129-
### Creating a compound index (3.2)
218+
### Background index updates
130219
131-
Compound indexes hold references to multiple fields of a document. Logically, they are equivalent to creating multiple individual indexes per field. To take advantage of the optimizations provided by Cosmos DB indexing techniques, we recommend creating multiple individual indexes instead of a single (non-unique) compound index.
220+
Regardless of the value specified for the **Background** index property, index updates are always done in the background. Index updates consume RU's at a lower priority than other database operations. Therefore, index changes won't result in any downtime for writes, updates, or deletes.
132221
133-
## Common Indexing Operations
222+
When adding a new index, queries will immediately utilize it. This means that queries may not return all the matching results, and will do so without returning any errors. Once the index transformation is completed, query results will be consistent. You can [track the index progress](#track-the-index-progress).
134223
135-
The following operations are common for both accounts serving wire protocol version 3.6 and accounts serving earlier wire protocol versions.
136-
137-
## Creating unique indexes
138-
139-
[Unique indexes](unique-keys.md) are useful for enforcing that no two or more documents contain the same value for the indexed field(s).
140-
141-
>[!Important]
142-
> Currently, unique indexes can be created only when the collection is empty (contains no documents).
143-
144-
The following command creates a unique index on the field "student_id":
145-
146-
```shell
147-
globaldb:PRIMARY> db.coll.createIndex( { "student_id" : 1 }, {unique:true} )
148-
{
149-
"_t" : "CreateIndexesResponse",
150-
"ok" : 1,
151-
"createdCollectionAutomatically" : false,
152-
"numIndexesBefore" : 1,
153-
"numIndexesAfter" : 4
154-
}
155-
```
156-
157-
For sharded collections, as per MongoDB behavior, creating a unique index requires providing the shard (partition) key. In other words, all unique indexes on a sharded collection are compound indexes where one of the fields is the partition key.
158-
159-
The following commands create a sharded collection ```coll``` (shard key is ```university```) with a unique index on fields student_id and university:
224+
## Migrating collections with indexes
160225
161-
```shell
162-
globaldb:PRIMARY> db.runCommand({shardCollection: db.coll._fullName, key: { university: "hashed"}});
163-
{
164-
"_t" : "ShardCollectionResponse",
165-
"ok" : 1,
166-
"collectionsharded" : "test.coll"
167-
}
168-
globaldb:PRIMARY> db.coll.createIndex( { "student_id" : 1, "university" : 1 }, {unique:true})
169-
{
170-
"_t" : "CreateIndexesResponse",
171-
"ok" : 1,
172-
"createdCollectionAutomatically" : false,
173-
"numIndexesBefore" : 3,
174-
"numIndexesAfter" : 4
175-
}
176-
```
226+
Currently, creating unique indexes is possible only when the collection contains no documents. Popular MongoDB migration tools attempt to create the unique indexes after importing the data. To circumvent this issue, it is suggested that users manually create the corresponding collections and unique indexes, instead of allowing the migration tool (for ```mongorestore``` this behavior is achieved by using the `--noIndexRestore` flag in the command line).
177227
178-
In the above example, if ```"university":1``` clause was omitted, an error with the following message would be returned:
228+
## Indexing for version 3.2
179229
180-
```"cannot create unique index over {student_id : 1.0} with shard key pattern { university : 1.0 }"```
230+
For Azure Cosmos DB accounts compatible with the 3.2 version of the MongoDB wire protocol, the available indexing features and defaults are different. You can [check your account's version](mongodb-feature-support-36.md#protocol-support). You can upgrade to the 3.6 version by filing a [support request](https://portal.azure.com/?#blade/Microsoft_Azure_Support/HelpAndSupportBlade).
181231
182-
## TTL indexes
232+
If you are using version 3.2, this section outlines key differences with version 3.6.
183233
184-
To enable document expiration in a particular collection, a ["TTL index" (time-to-live index)](../cosmos-db/time-to-live.md) needs to be created. A TTL index is an index on the _ts field with an "expireAfterSeconds" value.
234+
### Dropping the default indexes (3.2)
185235
186-
Example:
236+
Unlike the 3.6 version of Azure Cosmos DB's API for MongoDB, 3.2 version indexes every property by default. The following command can be used to drop these default indexes for a collection ```coll```:
187237
188238
```JavaScript
189-
globaldb:PRIMARY> db.coll.createIndex({"_ts":1}, {expireAfterSeconds: 10})
239+
> db.coll.dropIndexes()
240+
{ "_t" : "DropIndexesResponse", "ok" : 1, "nIndexesWas" : 3 }
190241
```
191242
192-
The preceding command will cause the deletion of any documents in ```db.coll``` collection that have not been modified in the last 10 seconds.
193-
194-
> [!NOTE]
195-
> **_ts** is a Cosmos DB-specific field and is not accessible from MongoDB clients. It is a reserved (system) property that contains the timestamp of the document's last modification.
243+
After dropping the default indexes, you can add on additional indexes as done in Version 3.6.
196244
197-
## Migrating collections with indexes
245+
### Compound indexes (3.2)
198246
199-
Currently, creating unique indexes is possible only when the collection contains no documents. Popular MongoDB migration tools attempt to create the unique indexes after importing the data. To circumvent this issue, it is suggested that users manually create the corresponding collections and unique indexes, instead of allowing the migration tool (for ```mongorestore``` this behavior is achieved by using the `--noIndexRestore` flag in the command line).
247+
Compound indexes hold references to multiple fields of a document. If you would like to create a compound index, please upgrade to 3.6 version by filing a [support request](https://portal.azure.com/?#blade/Microsoft_Azure_Support/HelpAndSupportBlade).
200248
201249
## Next steps
202250

0 commit comments

Comments
 (0)