MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

Làm thế nào để trang trí một hạng mục thành một chỉ mục và giống như khi sử dụng ensureIndex?

Tôi nghĩ đây là một ý tưởng hay, nhưng bạn phải tự làm điều này, không có hỗ trợ tích hợp cho nó. Nếu bạn có một lớp truy cập, bạn có thể làm điều đó trong đó. Bạn cần một lớp thuộc tính, giống như thế này;

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

Sau đó, bạn có thể áp dụng các thuộc tính ở cấp độ lớp học hoặc cấp độ thành viên như sau. Tôi nhận thấy rằng việc thêm ở cấp độ thành viên ít có khả năng không đồng bộ với lược đồ hơn so với việc thêm ở cấp độ lớp học. Tất nhiên, bạn cần đảm bảo rằng bạn nhận được tên phần tử thực sự thay vì tên thành viên 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
}

và sau đó trong triển khai quyền truy cập DB của bạn (hoặc kho lưu trữ), bạn cần một cái gì đó như thế này;

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

Sau đó, EnsureIndexes trông như thế này;

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

Lưu ý rằng bạn sẽ đặt cái này sau mỗi lần cập nhật vì nếu bạn quên ở đâu đó thì chỉ mục của bạn có thể không được tạo. Do đó, điều quan trọng là phải đảm bảo rằng bạn tối ưu hóa cuộc gọi để nó trả về nhanh chóng nếu không có việc lập chỉ mục nào để thực hiện trước khi xem qua tất cả mã phản ánh đó. Lý tưởng nhất là bạn chỉ làm điều này một lần hoặc ít nhất là một lần cho mỗi lần khởi động ứng dụng. Vì vậy, một cách sẽ là sử dụng cờ tĩnh để theo dõi xem bạn đã làm như vậy chưa và bạn cần bảo vệ khóa bổ sung xung quanh đó, nhưng đơn giản quá mức, nó trông giống như thế này;

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

Vì vậy, đó là phương pháp bạn muốn trong mỗi và mọi bản cập nhật DB mà bạn thực hiện, điều này, nếu bạn may mắn cũng sẽ được trình tối ưu hóa JIT đưa vào.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Kết nối với vùng chứa của Docker Mongodb từ vùng chứa của docker khác

  2. 3 cách xóa giá trị khỏi mảng trong MongoDB

  3. Giao dịch MongoDB

  4. Mongodb và truy vấn đa giác tìm kiếm giao với đa giác

  5. Các chỉ mục thưa thớt hợp chất MongoDB