English 中文(简体)
如何将某一类物品作为指数化,与使用Index相同?
原标题:How to decorate a class item to be an index and get the same as using ensureIndex?

我愿在班级声明中确定哪些项目是指数,例如:

public class MyClass {
    public int SomeNum { get; set; }
    [THISISANINDEX]
    public string SomeProperty { get; set; }
}

从而发挥与确保Index(“SomeProperty”)相同的作用

这是可能的吗?

问题回答

我认为,这是一个好奇的想法,但你必须这样做,对此没有内在的支持。 如果你有一个进入层,你可以在那里这样做。 你们需要一个归属阶层,就像这样的;

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
}

之后,在您的行程(或存放处)中,你们需要这样的东西。

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

于是,确保这一点。

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

请注意,你在每次更新后都会这样做,因为如果你忘掉可能无法制作的指数。 因此,重要的是,确保你选择这一呼吁,以便它能够在没有索引的情况下迅速恢复,然后再通过所有这种思考守则。 理想的情况是,你每申请一次或至少一次这样做。 因此,一种办法是使用固定旗帜来跟踪你是否已经这样做,而且你需要附加锁的保护,但过于简单地看着这样的情况;

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

∗∗∗∗ 你们在每一行中都希望采用的方法,更新了你们,如果你回头 l,也会被国际投资协议最佳化者所控制。

See below for a naive implementation which can do with some grands to take the from the MongoDb documentation into consideration. 根据申请中使用的询问编制索引,而不是增加对财产的习俗属性,可能是另一种选择。

using System;
using System.Reflection;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Driver;
using NUnit.Framework;
using SharpTestsEx;

namespace Mongeek
{
    [TestFixture]
    class TestDecorateToEnsureIndex
    {
        [Test]
        public void ShouldIndexPropertyWithEnsureIndexAttribute() 
        {
            var server = MongoServer.Create("mongodb://localhost");
            var db = server.GetDatabase("IndexTest");
            var boatCollection = db.GetCollection<Boat>("Boats");
            boatCollection.DropAllIndexes();

            var indexer = new Indexer();
            indexer.EnsureThat(boatCollection).HasIndexesNeededBy<Boat>();

            boatCollection.IndexExists(new[] { "Name" }).Should().Be.True();
        }
    }

    internal class Indexer
    {
        private MongoCollection _mongoCollection;

        public Indexer EnsureThat(MongoCollection mongoCollection)
        {
            _mongoCollection = mongoCollection;
            return this;
        }

        public Indexer HasIndexesNeededBy<T>()
        {
            Type t = typeof (T);
            foreach(PropertyInfo prop in t.GetProperties() )
            {
                if (Attribute.IsDefined(prop, typeof (EnsureIndexAttribute)))
                {
                    _mongoCollection.EnsureIndex(new[] {prop.Name});
                }
            }
            return this;
        }
    }

    internal class Boat
    {
        public Boat(Guid id)
        {
            Id = id;
        }

        [BsonId]
        public Guid Id { get; private set; }

        public int Length { get; set; }

        [EnsureIndex]
        public string Name { get; set; }
    }

    internal class EnsureIndexAttribute  : Attribute
    {
    }
}




相关问题
Access DB Ref MongoDB

Whats the best way to access/query a DB Ref: UPDATE: users: name, groupref : {$ref:"groups",$id:"ObjectId ..." } } groups: name, topic, country,...,.. Assumption is that user belongs to only one ...

MongoDB nested sets

What re the best practices to store nested sets (like trees of comments) in MongoDB? I mean, every comment can have a parent comment and children-comments (answers). Storing them like this: { ...

MongoMapper and migrations

I m building a Rails application using MongoDB as the back-end and MongoMapper as the ORM tool. Suppose in version 1, I define the following model: class SomeModel include MongoMapper::Document ...

MongoDB takes long for indexing

I have the following setup: Mac Pro with 2 GB of RAM (yes, not that much) MongoDB 1.1.3 64-bit 8 million entries in a single collection index for one field (integer) wanted Calling .ensureIndex(...) ...

Storing and accessing large amounts of data

My application creates pieces of data that, in xml, would look like this: <resource url="someurl"> <term> <name>somename</name> <frequency>somenumber</...

热门标签