sql >> Databáze >  >> NoSQL >> MongoDB

Jak ozdobit položku třídy tak, aby byla indexem, a získat totéž, jako pomocí secureIndex?

Myslím, že je to pěkný nápad, ale musíte to udělat sami, není pro to vestavěná podpora. Pokud máte přístupovou vrstvu, můžete to udělat tam. Potřebovali byste třídu atributů, něco takového;

public enum IndexConstraints
{
    Normal     = 0x00000001, // Ascending, non-indexed
    Descending = 0x00000010,
    Unique     = 0x00000100,
    Sparse     = 0x00001000, // allows nulls in the indexed fields
}

// Applied to a member
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class EnsureIndexAttribute : EnsureIndexes
{
    public EnsureIndex(IndexConstraints ic = IndexConstraints.Normal) : base(ic) { }
}

// Applied to a class
[AttributeUsage(AttributeTargets.Class)]
public class EnsureIndexesAttribute : Attribute
{
    public bool Descending { get; private set; }
    public bool Unique { get; private set; }
    public bool Sparse { get; private set; }
    public string[] Keys { get; private set; }

    public EnsureIndexes(params string[] keys) : this(IndexConstraints.Normal, keys) {}
    public EnsureIndexes(IndexConstraints ic, params string[] keys)
    {
        this.Descending = ((ic & IndexConstraints.Descending) != 0);
        this.Unique = ((ic & IndexConstraints.Unique) != 0); ;
        this.Sparse = ((ic & IndexConstraints.Sparse) != 0); ;
        this.Keys = keys;
    }

}//class EnsureIndexes

Potom můžete použít atributy na úrovni třídy nebo člena následovně. Zjistil jsem, že přidávání na úrovni členů je méně pravděpodobné, že se nesynchronizuje se schématem ve srovnání s přidáváním na úrovni třídy. Musíte se samozřejmě ujistit, že získáte skutečný název prvku na rozdíl od jména člena C#;

[CollectionName("People")]
//[EnsureIndexes("k")]// doing it here would allow for multi-key configs
public class Person 
{
    [BsonElement("k")] // name mapping in the DB schema
    [BsonIgnoreIfNull]
    [EnsureIndex(IndexConstraints.Unique|IndexConstraints.Sparse)] // name is implicit here
    public string userId{ get; protected set; }

// other properties go here
}

a pak ve vaší implementaci přístupu k databázi (nebo úložišti) potřebujete něco takového;

    private void AssureIndexesNotInlinable()
    {
                // We can only index a collection if there's at least one element, otherwise it does nothing
                if (this.collection.Count() > 0)
                {

                    // Check for EnsureIndex Attribute
                    var theClass = typeof(T);

                    // Walk the members of the class to see if there are any directly attached index directives
                    foreach (var m in theClass.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy))
                    {
                        List<string> elementNameOverride = new List<string>(1);
                        EnsureIndexes indexAttr = null;

                        // For each members attribs
                        foreach (Attribute attr in m.GetCustomAttributes())
                        {
                            if (attr.GetType() == typeof(EnsureIndex))
                                indexAttr = (EnsureIndex)attr;

                            if (attr.GetType() == typeof(RepoElementAttribute))
                                elementNameOverride.Add(((RepoElementAttribute)attr).ElementName);

                            if ((indexAttr != null) && (elementNameOverride.Count != 0))
                                break;
                        }

                        // Index
                        if (indexAttr != null)
                        {
                            if (elementNameOverride.Count() > 0)
                                EnsureIndexesAsDeclared(indexAttr, elementNameOverride);
                            else
                                EnsureIndexesAsDeclared(indexAttr);
                        }
                    }

                    // Walk the atributes on the class itself. WARNING: We don't validate the member names here, we just create the indexes
                    // so if you create a unique index and don't have a field to match you'll get an exception as you try to add the second
                    // item with a null value on that key
                    foreach (Attribute attr in theClass.GetCustomAttributes(true))
                    {
                        if (attr.GetType() == typeof(EnsureIndexes))
                            EnsureIndexesAsDeclared((EnsureIndexes)attr);

                    }//foreach

                }//if this.collection.count

    }//AssureIndexesNotInlinable()

SecureIndexes pak vypadá takto;

    private void EnsureIndexesAsDeclared(EnsureIndexes attr, List<string> indexFields = null)
    {
        var eia = attr as EnsureIndexes;

        if (indexFields == null)
            indexFields = eia.Keys.ToList();

        // use driver specific methods to actually create this index on the collection
        var db = GetRepositoryManager(); // if you have a repository or some other method of your own 
        db.EnsureIndexes(indexFields, attr.Descending, attr.Unique, attr.Sparse);

    }//EnsureIndexes()

Všimněte si, že toto umístíte po každé aktualizaci, protože pokud někde zapomenete, vaše indexy se nemusí vytvořit. Je proto důležité zajistit, abyste optimalizovali volání tak, aby se rychle vrátilo, pokud není třeba provést žádné indexování, než projdete celým tím odrazovým kódem. V ideálním případě byste to udělali pouze jednou nebo alespoň jednou za spuštění aplikace. Jedním ze způsobů by tedy bylo použití statického příznaku ke sledování, zda jste tak již učinili, a kolem toho byste potřebovali další ochranu zámkem, ale příliš zjednodušeně to vypadá asi takto;

    void AssureIndexes()
    {
        if (_requiresIndexing)
            AssureIndexesInit();
    }

Takže to je metodu, kterou budete chtít v každé aktualizaci DB, kterou provedete a která, pokud budete mít štěstí, bude také vložena do optimalizátoru JIT.



  1. Odeslání položky do pole kolekce Mongodb

  2. vložit klíč do redis

  3. C# MongoDB.Driver GetServer je pryč, co teď?

  4. Smazat dokument z mongoDB