public void EnsureGetIndex() { queue.EnsureGetIndex(new IndexKeysDocument("type", 1), new IndexKeysDocument("boo", -1)); queue.EnsureGetIndex(new IndexKeysDocument("another.sub", 1)); Assert.AreEqual(4, collection.GetIndexes().Count); var expectedOne = new IndexKeysDocument { { "running", 1 }, { "payload.type", 1 }, { "priority", 1 }, { "created", 1 }, { "payload.boo", -1 }, { "earliestGet", 1 } }; Assert.AreEqual(expectedOne, collection.GetIndexes()[1].Key); var expectedTwo = new IndexKeysDocument { { "running", 1 }, { "resetTimestamp", 1 } }; Assert.AreEqual(expectedTwo, collection.GetIndexes()[2].Key); var expectedThree = new IndexKeysDocument { { "running", 1 }, { "payload.another.sub", 1 }, { "priority", 1 }, { "created", 1 }, { "earliestGet", 1 } }; Assert.AreEqual(expectedThree, collection.GetIndexes()[3].Key); }
/// <summary> /// Ensure index for Count() method /// Is a no-op if the generated index is a prefix of an existing one. If you have a similar EnsureGetIndex call, call it first. /// </summary> /// <param name="index">fields in Count() call</param> /// <param name="includeRunning">whether running was given to Count() or not</param> /// <exception cref="ArgumentNullException">index was null</exception> /// <exception cref="ArgumentException">index field value is not 1 or -1</exception> public void EnsureCountIndex(IndexKeysDocument index, bool includeRunning) { if (index == null) { throw new ArgumentNullException("index"); } var completeFields = new IndexKeysDocument(); if (includeRunning) { completeFields.Add("running", 1); } foreach (var field in index) { if (field.Value != 1 && field.Value != -1) { throw new ArgumentException("field values must be 1 or -1 for ascending or descending", "index"); } completeFields.Add("payload." + field.Name, field.Value); } EnsureIndex(completeFields); }
public static string GetKeyString(IndexKeysDocument keys) { String KeyString = string.Empty; foreach (BsonElement key in keys.Elements) { KeyString += key.Name + ":"; switch (key.Value.ToString()) { case "1": KeyString += MongoDBHelper.IndexType.Ascending.ToString(); break; case "-1": KeyString += MongoDBHelper.IndexType.Descending.ToString(); break; case "2d": KeyString += MongoDBHelper.IndexType.GeoSpatial.ToString(); break; default: break; } KeyString += ";"; } KeyString = "[" + KeyString.TrimEnd(";".ToArray()) + "]"; return(KeyString); }
/// <summary> /// EnsureIndex for TTL(Time To Live) - Auto expiration feature /// </summary> /// <typeparam name="T"></typeparam> public void EnsureTTLIndex <T>() where T : class, new() { IndexKeysDocument ikd = new IndexKeysDocument(new BsonElement("Date", 1)); IndexOptionsDocument iod = new IndexOptionsDocument(new BsonElement("expireAfterSeconds", 21600)); // 6 hours mongoDb.GetCollection <T>(GetTypeName(typeof(T))).CreateIndex(ikd, iod); }
public void EnsureGetIndex() { queue.EnsureGetIndex(new IndexKeysDocument("type", 1), new IndexKeysDocument("boo", -1)); queue.EnsureGetIndex(new IndexKeysDocument("another.sub", 1)); var indexes = collection.Indexes.List().ToList(); Assert.AreEqual(4, indexes.Count); var expectedOne = new IndexKeysDocument { { "running", 1 }, { "payload.type", 1 }, { "priority", 1 }, { "created", 1 }, { "payload.boo", -1 }, { "earliestGet", 1 } }; Assert.AreEqual(expectedOne, indexes[1]["key"]); var expectedTwo = new IndexKeysDocument { { "running", 1 }, { "resetTimestamp", 1 } }; Assert.AreEqual(expectedTwo, indexes[2]["key"]); var expectedThree = new IndexKeysDocument { { "running", 1 }, { "payload.another.sub", 1 }, { "priority", 1 }, { "created", 1 }, { "earliestGet", 1 } }; Assert.AreEqual(expectedThree, indexes[3]["key"]); }
/// <summary> /// Key String /// </summary> /// <param name="keys"></param> /// <returns></returns> public static string GetKeyString(IndexKeysDocument keys) { var keyString = string.Empty; foreach (var key in keys.Elements) { keyString += key.Name + ":"; switch (key.Value.ToString()) { case "1": keyString += IndexType.Ascending.ToString(); break; case "-1": keyString += IndexType.Descending.ToString(); break; case "2d": keyString += IndexType.GeoSpatial.ToString(); break; case "text": keyString += IndexType.Text.ToString(); break; default: break; } keyString += ";"; } keyString = "[" + keyString.TrimEnd(";".ToArray()) + "]"; return(keyString); }
public void EnsureCountIndex() { queue.EnsureCountIndex(new IndexKeysDocument { { "type", 1 }, { "boo", -1 } }, false); queue.EnsureCountIndex(new IndexKeysDocument { { "another.sub", 1 } }, true); var indexes = collection.Indexes.List().ToList(); Assert.AreEqual(3, indexes.Count); var expectedOne = new IndexKeysDocument { { "payload.type", 1 }, { "payload.boo", -1 } }; Assert.AreEqual(expectedOne, indexes[1]["key"]); var expectedTwo = new IndexKeysDocument { { "running", 1 }, { "payload.another.sub", 1 } }; Assert.AreEqual(expectedTwo, indexes[2]["key"]); }
protected void EnsureIndex(string name, object keys, object extraOptions = null) { if (!Collection.IndexExistsByName(name)) { IMongoIndexKeys indexKeys = new IndexKeysWrapper(keys); var ints = keys as Dictionary <string, int>; if (ints != null) { indexKeys = new IndexKeysDocument(ints); } var options = new Dictionary <string, object> { { "name", name }, { "background", true } }; if (extraOptions != null) { foreach (var option in extraOptions.ToDictionary()) { options.Add(option.Key, option.Value); } } Collection.EnsureIndex(indexKeys, new IndexOptionsDocument(options)); } }
public void TestIndexKeysDocumentConstructor() { var document1 = new IndexKeysDocument(_dictionary); var document2 = new IndexKeysDocument(_hashtable); var document3 = new IndexKeysDocument(_idictionaryNonGeneric); var document4 = new IndexKeysDocument(_idictionary); Assert.AreEqual("Dictionary<string, object>", document1["type"].AsString); Assert.AreEqual("Hashtable", document2["type"].AsString); Assert.AreEqual("IDictionary", document3["type"].AsString); Assert.AreEqual("IDictionary<string, object>", document4["type"].AsString); }
private IndexKeysDocument ToDoc(List <KeyModel> keys) { var doc = new IndexKeysDocument(); if (keys != null && keys.Count > 0) { foreach (var key in keys) { doc.Add(key.Field, key.Order); } } return(doc); }
private void EnsureIndex(IndexKeysDocument index) { //if index is a prefix of any existing index we are good foreach (var existingIndex in collection.Indexes.List().ToEnumerable()) { var names = index.Names; var values = index.Values; var existingNamesPrefix = existingIndex.Names.Take(names.Count()); var existingValuesPrefix = existingIndex.Values.Take(values.Count()); if (Enumerable.SequenceEqual(names, existingNamesPrefix) && Enumerable.SequenceEqual(values, existingValuesPrefix)) { return; } } for (var i = 0; i < 1; ++i) { for (var name = Guid.NewGuid().ToString(); name.Length > 0; name = name.Substring(0, name.Length - 1)) { //creating an index with the same name and different spec does nothing. //creating an index with same spec and different name does nothing. //so we use any generated name, and then find the right spec after we have called, and just go with that name. try { collection.Indexes.CreateOne( new CreateIndexModel <BsonDocument>(index, new CreateIndexOptions { Name = name, Background = true })); } catch (MongoCommandException) { //this happens when the name was too long } foreach (var existingIndex in collection.Indexes.List().ToEnumerable()) { if (existingIndex["key"] == index) { return; } } } } throw new Exception("couldnt create index after 5 attempts"); }
/// <summary> /// Execute sql /// </summary> /// <typeparam name="T"></typeparam> /// <param name="sql"></param> public void ExecuteSql <T>(string sql) where T : class, new() { BsonDocument bDoc; switch (ParseSql(sql, out bDoc)) { case MongoFunction.EnsureIndex: IndexKeysDocument indexKeysDoc = new IndexKeysDocument(bDoc.Elements); this.GetCollection <T>().CreateIndex(indexKeysDoc); break; case MongoFunction.RunCommand: _MongoDatabase.RunCommand(new CommandDocument(bDoc.Elements)); break; } }
public void EnsureCountIndexWithPrefixOfPrevious() { queue.EnsureCountIndex(new IndexKeysDocument { { "type", 1 }, { "boo", -1 } }, false); queue.EnsureCountIndex(new IndexKeysDocument { { "type", 1 } }, false); Assert.AreEqual(2, collection.GetIndexes().Count); var expectedOne = new IndexKeysDocument { { "payload.type", 1 }, { "payload.boo", -1 } }; Assert.AreEqual(expectedOne, collection.GetIndexes()[1].Key); }
public void EnsureGetIndexWithNoArgs() { queue.EnsureGetIndex(); Assert.AreEqual(3, collection.GetIndexes().Count); var expectedOne = new IndexKeysDocument { { "running", 1 }, { "priority", 1 }, { "created", 1 }, { "earliestGet", 1 } }; Assert.AreEqual(expectedOne, collection.GetIndexes()[1].Key); var expectedTwo = new IndexKeysDocument { { "running", 1 }, { "resetTimestamp", 1 } }; Assert.AreEqual(expectedTwo, collection.GetIndexes()[2].Key); }
public void EnsureCountIndexWithPrefixOfPrevious() { queue.EnsureCountIndex(new IndexKeysDocument { { "type", 1 }, { "boo", -1 } }, false); queue.EnsureCountIndex(new IndexKeysDocument { { "type", 1 } }, false); var indexes = collection.Indexes.List().ToList(); Assert.AreEqual(3, indexes.Count); var expectedOne = new IndexKeysDocument { { "payload.type", 1 }, { "payload.boo", -1 } }; Assert.AreEqual(expectedOne, indexes[1]["key"]); }
/// <summary> /// Ensure index for Get() method /// </summary> /// <param name="beforeSort">fields in Get() call that should be before the sort fields in the index</param> /// <param name="afterSort">fields in Get() call that should be after the sort fields in the index</param> /// <exception cref="ArgumentNullException">beforeSort or afterSort is null</exception> /// <exception cref="ArgumentException">beforeSort or afterSort field value is not 1 or -1</exception> public void EnsureGetIndex(IndexKeysDocument beforeSort, IndexKeysDocument afterSort) { if (beforeSort == null) { throw new ArgumentNullException("beforeSort"); } if (afterSort == null) { throw new ArgumentNullException("afterSort"); } //using general rule: equality, sort, range or more equality tests in that order for index var completeIndex = new IndexKeysDocument("running", 1); foreach (var field in beforeSort) { if (field.Value != 1 && field.Value != -1) { throw new ArgumentException("field values must be 1 or -1 for ascending or descending", "beforeSort"); } completeIndex.Add("payload." + field.Name, field.Value); } completeIndex.Add("priority", 1); completeIndex.Add("created", 1); foreach (var field in afterSort) { if (field.Value != -1 && field.Value != 1) { throw new ArgumentException("field values must be 1 or -1 for ascending or descending", "afterSort"); } completeIndex.Add("payload." + field.Name, field.Value); } completeIndex.Add("earliestGet", 1); EnsureIndex(completeIndex);//main query in Get() EnsureIndex(new IndexKeysDocument { { "running", 1 }, { "resetTimestamp", 1 } }); //for the stuck messages query in Get() }
public void EnsureGetIndexWithNoArgs() { queue.EnsureGetIndex(); var indexes = collection.Indexes.List().ToList(); Assert.AreEqual(3, indexes.Count); var expectedOne = new IndexKeysDocument { { "running", 1 }, { "priority", 1 }, { "created", 1 }, { "earliestGet", 1 } }; Assert.AreEqual(expectedOne, indexes[1]["key"]); var expectedTwo = new IndexKeysDocument { { "running", 1 }, { "resetTimestamp", 1 } }; Assert.AreEqual(expectedTwo, indexes[2]["key"]); }
/// <summary> /// Internal dataset creator function. Creates all necessary metadata /// </summary> /// <param name="Name">Name of the dataset</param> /// <param name="FieldSet">Fields associated with the dataset</param> /// <param name="extent">The geographic extent of the dataset</param> /// <returns>A newly created MongoDBDataset</returns> public MongoDBDataset CreateDataset(string Name, IFields FieldSet, IEnvelope extent) { if (m_Connection.GetCollectionNames().Contains(Name)) { throw new COMException("Dataset " + Name + " already exists"); } m_Connection.CreateCollection(Name); var bsonIdex = new IndexKeysDocument { { CommonConst.SHAPEFIELD, "2d" } }; m_Connection[Name].EnsureIndex(bsonIdex); CatalogDatasetEntry dsEntry = new CatalogDatasetEntry(this.m_CatalogDS); dsEntry.Name = Name; dsEntry.Extent = extent; dsEntry.Fields = FieldSet; dsEntry.Save(); return(new MongoDBDataset(dsEntry, m_Connection)); }
public void EnsureCountIndex() { queue.EnsureCountIndex(new IndexKeysDocument { { "type", 1 }, { "boo", -1 } }, false); queue.EnsureCountIndex(new IndexKeysDocument { { "another.sub", 1 } }, true); Assert.AreEqual(3, collection.GetIndexes().Count); var expectedOne = new IndexKeysDocument { { "payload.type", 1 }, { "payload.boo", -1 } }; Assert.AreEqual(expectedOne, collection.GetIndexes()[1].Key); var expectedTwo = new IndexKeysDocument { { "running", 1 }, { "payload.another.sub", 1 } }; Assert.AreEqual(expectedTwo, collection.GetIndexes()[2].Key); }
private void CreateIndexJsonMode() { string indexJson = textBoxIndexJson.Text.Trim(); if (string.IsNullOrWhiteSpace(indexJson)) { throw new Exception("Enter index json."); } IndexKeysDocument keys = null; try { keys = BsonSerializer.Deserialize <IndexKeysDocument>(indexJson); } catch (Exception ex1) { throw new Exception($"Invalid index json.\r\n\r\n{ex1.Message}"); } string optionJson = textBoxIndexOptionsJson.Text.Trim(); IndexOptionsDocument options = null; if (string.IsNullOrWhiteSpace(optionJson)) { options = new IndexOptionsDocument(); } else { try { options = BsonSerializer.Deserialize <IndexOptionsDocument>(optionJson); } catch (Exception ex1) { throw new Exception($"Invalid options json.\r\n\r\n{ex1.Message}"); } } if (!options.Contains("name")) { string indexName = txtBoxIndexName.Text; if (string.IsNullOrWhiteSpace(indexName)) { throw new Exception("Please enter an index name."); } options.Add("name", indexName); } if (!options.Contains("unique")) { options.Add("unique", checkBoxUnique.Checked); } if (!options.Contains("dropDups") && checkBoxUnique.Checked) { options.Add("dropDups", checkBoxDropDups.Checked); } if (!options.Contains("background")) { options.Add("background", checkBoxBackground.Checked); } if (!options.Contains("sparse")) { options.Add("sparse", checkBoxSparse.Checked); } var mongoCollection = MongoCollectionInfo.GetMongoCollection(); WriteConcernResult writeConcernResult = mongoCollection.CreateIndex(keys, options); if (writeConcernResult.HasLastErrorMessage) { throw new Exception(writeConcernResult.LastErrorMessage); } }
public static bool CreateIndex(IndexOption UIOption, ref string strMessageTitle, ref string strMessageContent) { var Result = true; var option = new IndexOptionsBuilder(); option.SetBackground(UIOption.IsBackground); option.SetDropDups(UIOption.IsDropDups); option.SetSparse(UIOption.IsSparse); option.SetUnique(UIOption.IsUnique); if (UIOption.IsExpireData) { //TTL的限制条件很多 //http://docs.mongodb.org/manual/tutorial/expire-data/ //不能是组合键 var canUseTtl = true; if ((UIOption.ascendingKey.Count + UIOption.descendingKey.Count + (string.IsNullOrEmpty(UIOption.geoSpatialKey) ? 0 : 1)) != 1) { strMessageTitle = "Can't Set TTL"; strMessageContent = "the TTL index may not be compound (may not have multiple fields)."; canUseTtl = false; } else { //不能是_id if (UIOption.firstKey == ConstMgr.KeyId) { strMessageTitle = "Can't Set TTL"; strMessageContent = "you cannot create this index on the _id field, or a field that already has an index."; canUseTtl = false; } } if (RuntimeMongoDbContext.GetCurrentCollection().IsCapped()) { strMessageTitle = "Can't Set TTL"; strMessageContent = "you cannot use a TTL index on a capped collection, because MongoDB cannot remove documents from a capped collection."; canUseTtl = false; } if (canUseTtl) { strMessageTitle = "Constraints Of TimeToLive"; strMessageContent = "the indexed field must be a date BSON type. If the field does not have a date type, the data will not expire." + Environment.NewLine + "if the field holds an array, and there are multiple date-typed data in the index, the document will expire when the lowest (i.e. earliest) matches the expiration threshold."; option.SetTimeToLive(new TimeSpan(0, 0, UIOption.TTL)); } } var totalIndex = (UIOption.ascendingKey.Count + UIOption.descendingKey.Count + (string.IsNullOrEmpty(UIOption.geoSpatialKey) ? 0 : 1) + (string.IsNullOrEmpty(UIOption.textKey) ? 0 : 1)); if (UIOption.IndexName != string.Empty && !RuntimeMongoDbContext.GetCurrentCollection().IndexExists(UIOption.IndexName) && totalIndex != 0) { option.SetName(UIOption.IndexName); try { //暂时要求只能一个TextKey if (!string.IsNullOrEmpty(UIOption.textKey)) { var textKeysDoc = new IndexKeysDocument { { UIOption.textKey, "text" } }; RuntimeMongoDbContext.GetCurrentCollection().CreateIndex(textKeysDoc, option); } else { Operater.CreateMongoIndex(UIOption.ascendingKey.ToArray(), UIOption.descendingKey.ToArray(), UIOption.geoSpatialKey, option, RuntimeMongoDbContext.GetCurrentCollection()); } strMessageTitle = "Index Add Completed!"; strMessageContent = "IndexName:" + UIOption.IndexName + " is add to collection."; } catch (Exception ex) { strMessageTitle = "Index Add Failed!"; strMessageContent = "IndexName:" + UIOption.IndexName; Result = false; } } else { strMessageTitle = "Index Add Failed!"; strMessageContent = "Please Check the index information."; Result = false; } return(Result); }
/// <summary> /// Ensure index for Get() method with no fields after sort fields /// </summary> /// <param name="beforeSort">fields in Get() call that should be before the sort fields in the index</param> /// <exception cref="ArgumentNullException">beforeSort is null</exception> /// <exception cref="ArgumentException">beforeSort field value is not 1 or -1</exception> public void EnsureGetIndex(IndexKeysDocument beforeSort) { EnsureGetIndex(beforeSort, new IndexKeysDocument()); }
/// <summary> /// 增加索引 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void cmdAddIndex_Click(object sender, EventArgs e) { var AscendingKey = new List <String>(); var DescendingKey = new List <String>(); String GeoSpatialKey = string.Empty; String FirstKey = string.Empty; String TextKey = String.Empty; for (int i = 0; i < 5; i++) { var ctl = (ctlIndexCreate)Controls.Find("ctlIndexCreate" + (i + 1), true)[0]; if (ctl.KeyName == String.Empty) { continue; } FirstKey = ctl.KeyName.Trim(); switch (ctl.IndexKeyType) { case MongoDbHelper.IndexType.Ascending: AscendingKey.Add(ctl.KeyName.Trim()); break; case MongoDbHelper.IndexType.Descending: DescendingKey.Add(ctl.KeyName.Trim()); break; case MongoDbHelper.IndexType.GeoSpatial: GeoSpatialKey = ctl.KeyName.Trim(); break; case MongoDbHelper.IndexType.Text: TextKey = ctl.KeyName.Trim(); break; default: break; } } var option = new IndexOptionsBuilder(); option.SetBackground(chkIsBackground.Checked); option.SetDropDups(chkIsDroppedDups.Checked); option.SetSparse(chkIsSparse.Checked); option.SetUnique(chkIsUnique.Checked); if (chkExpireData.Checked) { //TTL的限制条件很多 //http://docs.mongodb.org/manual/tutorial/expire-data/ //不能是组合键 Boolean CanUseTTL = true; if ((AscendingKey.Count + DescendingKey.Count + (String.IsNullOrEmpty(GeoSpatialKey) ? 0 : 1)) != 1) { MyMessageBox.ShowMessage("Can't Set TTL", "the TTL index may not be compound (may not have multiple fields)."); CanUseTTL = false; } else { //不能是_id if (FirstKey == MongoDbHelper.KEY_ID) { MyMessageBox.ShowMessage("Can't Set TTL", "you cannot create this index on the _id field, or a field that already has an index."); CanUseTTL = false; } } if (SystemManager.GetCurrentCollection().IsCapped()) { MyMessageBox.ShowMessage("Can't Set TTL", "you cannot use a TTL index on a capped collection, because MongoDB cannot remove documents from a capped collection."); CanUseTTL = false; } if (CanUseTTL) { MyMessageBox.ShowMessage("Constraints", "Constraints Of TimeToLive", "the indexed field must be a date BSON type. If the field does not have a date type, the data will not expire." + Environment.NewLine + "if the field holds an array, and there are multiple date-typed data in the index, the document will expire when the lowest (i.e. earliest) matches the expiration threshold.", true); option.SetTimeToLive(new TimeSpan(0, 0, (int)numTTL.Value)); } } if (txtIndexName.Text != String.Empty && !SystemManager.GetCurrentCollection().IndexExists(txtIndexName.Text) && (AscendingKey.Count + DescendingKey.Count + (String.IsNullOrEmpty(GeoSpatialKey) ? 0 : 1) + (String.IsNullOrEmpty(TextKey) ? 0 : 1)) != 0) { option.SetName(txtIndexName.Text); try { //暂时要求只能一个TextKey if (!string.IsNullOrEmpty(TextKey)) { var TextKeysDoc = new IndexKeysDocument { { TextKey, "text" } }; SystemManager.GetCurrentCollection().CreateIndex(TextKeysDoc, option); } else { MongoDbHelper.CreateMongoIndex(AscendingKey.ToArray(), DescendingKey.ToArray(), GeoSpatialKey, option); } MyMessageBox.ShowMessage("Index Add Completed!", "IndexName:" + txtIndexName.Text + " is add to collection."); } catch (Exception ex) { SystemManager.ExceptionDeal(ex, "Index Add Failed!", "IndexName:" + txtIndexName.Text); } RefreshList(); } else { MyMessageBox.ShowMessage("Index Add Failed!", "Please Check the index information."); } }