1 /** 2 MongoDB index API definitions. 3 4 Copyright: © 2020-2022 Jan Jurzitza 5 License: Subject to the terms of the MIT license, as written in the included LICENSE.txt file. 6 Authors: Jan Jurzitza 7 */ 8 module vibe.db.mongo.impl.index; 9 10 @safe: 11 12 import core.time; 13 14 import std.array; 15 import std.typecons; 16 17 import vibe.db.mongo.collection; 18 import vibe.data.bson; 19 20 deprecated("Use CreateIndexOptions instead") 21 enum IndexFlags { 22 none = 0, 23 unique = 1<<0, 24 dropDuplicates = 1<<2, 25 background = 1<<3, 26 sparse = 1<<4, 27 expireAfterSeconds = 1<<5, 28 29 None = none, /// Deprecated compatibility alias, use `none` instead. 30 Unique = unique, /// Deprecated compatibility alias, use `unique` instead. 31 DropDuplicates = dropDuplicates, /// Deprecated compatibility alias, use `dropDuplicates` instead. 32 Background = background, /// Deprecated compatibility alias, use `background` instead. 33 Sparse = sparse, /// Deprecated compatibility alias, use `sparse` instead. 34 ExpireAfterSeconds = expireAfterSeconds, /// Deprecated compatibility alias, use `expireAfterSeconds` instead. 35 } 36 37 struct IndexModel 38 { 39 Bson keys = Bson.emptyObject; 40 IndexOptions options; 41 42 /** 43 Adds a single field or multikey index with a direction. 44 45 Call this method multiple times with different fields to create a 46 compound index. 47 48 Params: 49 field = the name of the field to index 50 direction = `1` for ascending or `-1` for descending 51 52 Returns: this IndexModel instance (caller) 53 */ 54 ref IndexModel add(string field, int direction) return 55 @safe { 56 // bson objects keep order 57 keys[field] = Bson(direction); 58 return this; 59 } 60 61 /** 62 Adds an index with a given index type. Use `IndexType` for a type-safe 63 setting of the string. 64 65 Params: 66 field = the name of the field to index 67 type = the index type to use 68 69 Returns: this IndexModel instance (caller) 70 */ 71 ref IndexModel add(string field, string type) return 72 @safe { 73 // bson objects keep order 74 keys[field] = Bson(type); 75 return this; 76 } 77 78 /** 79 Sets the options member of this IndexModel. 80 81 Returns: this IndexModel instance (caller) 82 */ 83 ref IndexModel withOptions(IndexOptions options) return 84 @safe { 85 this.options = options; 86 return this; 87 } 88 89 string name() const 90 @property @safe { 91 if (options.name.length) 92 { 93 return options.name; 94 } 95 else 96 { 97 auto indexname = appender!string(); 98 bool first = true; 99 foreach (string key, value; keys.byKeyValue) { 100 if (!first) indexname.put('_'); 101 else first = false; 102 indexname.put(key); 103 indexname.put('_'); 104 105 if (value.type == Bson.Type..string) 106 indexname.put(value.get!string); 107 else 108 indexname.put(value.toString()); 109 } 110 return indexname.data; 111 } 112 } 113 } 114 115 /** 116 Specifies the different index types which are available for index creation. 117 118 See_Also: $(LINK https://docs.mongodb.com/manual/indexes/#index-types) 119 */ 120 enum IndexType : string 121 { 122 /** 123 Legacy 2D plane index used in MongoDB 2.2 and earlier. Doesn't support 124 GeoJSON objects. Uses planar geometry to return results. 125 126 See_Also: $(LINK https://docs.mongodb.com/manual/core/2d/) 127 */ 128 legacy2D = "2d", 129 130 /** 131 2D sphere index that calculates geometries on an earth-like sphere. 132 Supports storing as GeoJSON objects. 133 134 See_Also: $(LINK https://docs.mongodb.com/manual/core/2dsphere/) 135 */ 136 sphere2D = "2dsphere", 137 138 /** 139 A geoHaystack index is a special index that is optimized to return 140 results over small areas. geoHaystack indexes improve performance on 141 queries that use flat geometry. 142 143 See_Also: $(LINK https://docs.mongodb.com/manual/core/geohaystack/) 144 */ 145 geoHaystack = "geoHaystack", 146 147 /** 148 Creates a text index which supports searching for string content in a 149 collection. These text indexes do not store language-specific stop words 150 and stem the words in a collection to only store root words. 151 152 See_Also: $(LINK https://docs.mongodb.com/manual/core/index-text/) 153 */ 154 text = "text", 155 156 /** 157 To support hash based sharding, MongoDB provides a hashed index type, 158 which indexes the hash of the value of a field. These indexes have a 159 more random distribution of values along their range, but only support 160 equality matches and cannot support range-based queries. 161 162 See_Also: $(LINK https://docs.mongodb.com/manual/core/index-hashed/) 163 */ 164 hashed = "hashed", 165 } 166 167 /** 168 See_Also: $(LINK https://docs.mongodb.com/manual/reference/command/createIndexes/) 169 170 Standards: $(LINK https://github.com/mongodb/specifications/blob/0c6e56141c867907aacf386e0cbe56d6562a0614/source/index-management.rst#common-api-components) 171 */ 172 struct IndexOptions 173 { 174 /** 175 Specifying true directs MongoDB to build the index in the background. 176 Background builds do not block operations on the collection. 177 Since MongoDB 4.2 indices are built on the background by default. 178 In MongoDB 4.0 and before, this defaults to `false`. 179 */ 180 @embedNullable @until(WireVersion.v42) 181 Nullable!bool background; 182 183 /** 184 Specifies the length in time, in seconds, for documents to remain in a 185 collection. 186 */ 187 @embedNullable Nullable!int expireAfterSeconds; 188 189 void expireAfter(Duration d) 190 @safe { 191 expireAfterSeconds = cast(int)d.total!"seconds"; 192 } 193 194 /** 195 Optionally specify a specific name for the index outside of the default 196 generated name. If none is provided then the name is generated in the 197 format "[field]_[direction]" 198 */ 199 @ignore string name; 200 201 /** 202 Tells the index to only reference documents with the specified field in 203 the index. 204 */ 205 @embedNullable Nullable!bool sparse; 206 207 /** 208 Allows configuring the storage engine on a per-index basis. 209 */ 210 @embedNullable @since(WireVersion.v30) 211 Nullable!Bson storageEngine; 212 213 /** 214 Forces the index to be unique. 215 */ 216 @embedNullable Nullable!bool unique; 217 218 /** 219 Creates a unique index on a field that may have duplicates. 220 */ 221 @embedNullable @until(WireVersion.v26) 222 Nullable!bool dropDups; 223 224 /** 225 Specifies the index version number, either 0 or 1. 226 */ 227 @embedNullable @(.name("v")) @until(WireVersion.v26) 228 Nullable!int version_; 229 230 /** 231 Default language for text indexes. Is "english" if none is provided. 232 */ 233 @embedNullable @(.name("default_language")) 234 Nullable!string defaultLanguage; 235 236 /** 237 Specifies the field in the document to override the language. 238 */ 239 @embedNullable @(.name("language_override")) 240 Nullable!string languageOverride; 241 242 /** 243 Sets the text index version number. 244 245 MongoDB 2.4 can only support version 1. 246 247 MongoDB 2.6 and higher may support version 1 or 2. 248 */ 249 @embedNullable @since(WireVersion.v26) 250 Nullable!int textIndexVersion; 251 252 /** 253 Specifies fields in the index and their corresponding weight values. 254 */ 255 @embedNullable Nullable!Bson weights; 256 257 /** 258 Sets the 2dsphere index version number. 259 260 MongoDB 2.4 can only support version 1. 261 262 MongoDB 2.6 and higher may support version 1 or 2. 263 264 MongoDB 3.2 and higher may support version 2 or 3. 265 */ 266 @embedNullable @(.name("2dsphereIndexVersion")) @since(WireVersion.v26) 267 Nullable!int _2dsphereIndexVersion; 268 269 /** 270 For 2d indexes, the number of precision of the stored geo hash value of 271 the location data. 272 */ 273 @embedNullable Nullable!int bits; 274 275 /** 276 For 2d indexes, the upper inclusive boundary for the longitude and 277 latitude values. 278 */ 279 @embedNullable Nullable!double max; 280 281 /** 282 For 2d indexes, the lower inclusive boundary for the longitude and 283 latitude values. 284 */ 285 @embedNullable Nullable!double min; 286 287 /** 288 For geoHaystack indexes, specify the number of units within which to 289 group the location values; i.e. group in the same bucket those location 290 values that are within the specified number of units to each other. 291 292 The value must be greater than 0. 293 */ 294 @embedNullable Nullable!double bucketSize; 295 296 /** 297 If specified, the index only references documents that match the filter 298 expression. See 299 $(LINK2 https://docs.mongodb.com/manual/core/index-partial/, Partial Indexes) 300 for more information. 301 */ 302 @embedNullable @since(WireVersion.v32) 303 Nullable!Bson partialFilterExpression; 304 305 /** 306 Collation allows users to specify language-specific rules for string 307 comparison, such as rules for letter-case and accent marks. 308 */ 309 @embedNullable @since(WireVersion.v34) 310 Nullable!Collation collation; 311 312 /** 313 Allows users to include or exclude specific field paths from a wildcard 314 index using the `{ "$**": 1 }` key pattern. 315 */ 316 @embedNullable @since(WireVersion.v42) 317 Nullable!Bson wildcardProjection; 318 } 319 320 /// Standards: $(LINK https://github.com/mongodb/specifications/blob/0c6e56141c867907aacf386e0cbe56d6562a0614/source/index-management.rst#common-api-components) 321 struct CreateIndexOptions 322 { 323 /** 324 The maximum amount of time to allow the index build to take before 325 returning an error. (not implemented) 326 */ 327 @embedNullable Nullable!long maxTimeMS; 328 } 329 330 /// Same as $(LREF CreateIndexOptions) 331 alias CreateIndexesOptions = CreateIndexOptions; 332 333 /// Standards: $(LINK https://github.com/mongodb/specifications/blob/f4020bdb6ec093fcd259984e6ff6f42356b17d0e/source/index-management.rst#standard-api) 334 struct DropIndexOptions 335 { 336 /** 337 The maximum amount of time to allow the index drop to take before 338 returning an error. (not implemented) 339 */ 340 @embedNullable Nullable!long maxTimeMS; 341 } 342 343 /// Same as $(LREF DropIndexOptions) 344 alias DropIndexesOptions = DropIndexOptions;