sql >> データベース >  >> NoSQL >> MongoDB

クラスアイテムをインデックスとして装飾し、ensureIndexを使用するのと同じようにするにはどうすればよいですか?

    これはいい考えだと思いますが、これは自分で行う必要があります。組み込みのサポートはありません。アクセスレイヤーがある場合は、そこで実行できます。このような属性クラスが必要です;

    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
    

    次に、次のように、クラスレベルまたはメンバーレベルのいずれかで属性を適用できます。メンバーレベルでの追加は、クラスレベルでの追加と比較して、スキーマと同期しなくなる可能性が低いことがわかりました。もちろん、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
    }
    

    次に、DBアクセスの実装(またはリポジトリ)で、次のようなものが必要です。

        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()
    

    その場合、EnsureIndexesは次のようになります;

        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()
    

    どこかを忘れるとインデックスが作成されない可能性があるため、更新のたびにこれを配置することに注意してください。したがって、すべてのリフレクションコードを実行する前に、インデックスを作成する必要がない場合にすぐに返されるように、呼び出しを最適化することが重要です。理想的には、これを1回だけ、または少なくともアプリケーションの起動ごとに1回実行します。したがって、1つの方法は、静的フラグを使用して、すでに実行したかどうかを追跡することです。その周りに追加のロック保護が必要になりますが、単純に言うと、次のようになります。

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

    だからそれは 実行するすべてのDB更新で必要となる方法。運が良ければ、JITオプティマイザーによってもインライン化されます。



    1. WebおよびWorkerdynoをHerokuのNode.jsと通信する方法は?

    2. POSTリクエストからのデータストリームをGridFS、express、mongoDB、node.jsに保存する

    3. sudochownの意味-R`id-u` / data / db

    4. ImportError:redisという名前のモジュールがありません