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