MongoDB
 sql >> Teknologi Basis Data >  >> NoSQL >> MongoDB

Bagaimana cara mendekorasi item kelas menjadi indeks dan mendapatkan yang sama dengan menggunakan sureIndex?

Saya pikir ini ide yang bagus, tetapi Anda harus melakukannya sendiri, tidak ada dukungan bawaan untuk itu. Jika Anda memiliki lapisan akses, Anda dapat melakukannya di sana. Anda membutuhkan kelas atribut, seperti ini;

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

Anda kemudian dapat menerapkan atribut di tingkat kelas atau anggota sebagai berikut. Saya menemukan bahwa menambahkan di tingkat anggota cenderung tidak sinkron dengan skema dibandingkan dengan menambahkan di tingkat kelas. Tentu saja Anda perlu memastikan bahwa Anda mendapatkan nama elemen yang sebenarnya sebagai lawan dari nama anggota 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
}

dan kemudian dalam implementasi akses DB Anda (atau repositori), Anda memerlukan sesuatu seperti ini;

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

PastikanIndexes kemudian terlihat seperti ini;

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

Perhatikan bahwa Anda akan menempatkan ini setelah setiap pembaruan karena jika Anda lupa di suatu tempat, indeks Anda mungkin tidak dibuat. Oleh karena itu, penting untuk memastikan bahwa Anda mengoptimalkan panggilan sehingga panggilan kembali dengan cepat jika tidak ada pengindeksan yang harus dilakukan sebelum melalui semua kode refleksi itu. Idealnya, Anda melakukan ini hanya sekali, atau setidaknya, sekali per startup aplikasi. Jadi salah satu caranya adalah dengan menggunakan flag statis untuk melacak apakah Anda sudah melakukannya, dan Anda memerlukan perlindungan kunci tambahan untuk itu, tetapi secara berlebihan, tampilannya seperti ini;

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

Jadi itu metode yang Anda inginkan di setiap pembaruan DB yang Anda buat, yang, jika Anda beruntung, juga akan digarisbawahi oleh pengoptimal JIT.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Bagaimana cara menghitung semua dokumen dalam koleksi dan menggunakan cont di pengontrol, dengan MongoDB dan Express.js?

  2. Cara yang lebih baik untuk memindahkan Koleksi MongoDB ke Koleksi lain

  3. bagaimana cara memeriksa apakah ada bidang dalam dokumen tertentu Mongodb menggunakan C #?

  4. MapReduce di PyMongo

  5. Apakah module.require(...).* mengembalikan salinan module.exports.* atau referensinya?