예제 #1
0
        /// <summary>
        /// Call this method to finalize defining the index after setting the index keys and options.
        /// </summary>
        /// <param name="cancellation">An optional cancellation token</param>
        public async Task CreateAsync(CancellationToken cancellation = default)
        {
            if (Keys.Count == 0)
            {
                throw new ArgumentException("Please define keys before calling this method.");
            }

            var propNames   = new HashSet <string>();
            var keyDefs     = new HashSet <IndexKeysDefinition <T> >();
            var isTextIndex = false;

            foreach (var key in Keys)
            {
                string keyType = string.Empty;

                switch (key.Type)
                {
                case KeyType.Ascending:
                    keyDefs.Add(Builders <T> .IndexKeys.Ascending(key.PropertyName));
                    keyType = "(Asc)";
                    break;

                case KeyType.Descending:
                    keyDefs.Add(Builders <T> .IndexKeys.Descending(key.PropertyName));
                    keyType = "(Dsc)";
                    break;

                case KeyType.Geo2D:
                    keyDefs.Add(Builders <T> .IndexKeys.Geo2D(key.PropertyName));
                    keyType = "(G2d)";
                    break;

                case KeyType.Geo2DSphere:
                    keyDefs.Add(Builders <T> .IndexKeys.Geo2DSphere(key.PropertyName));
                    keyType = "(Gsp)";
                    break;

                case KeyType.GeoHaystack:
                    keyDefs.Add(Builders <T> .IndexKeys.GeoHaystack(key.PropertyName));
                    keyType = "(Ghs)";
                    break;

                case KeyType.Hashed:
                    keyDefs.Add(Builders <T> .IndexKeys.Hashed(key.PropertyName));
                    keyType = "(Hsh)";
                    break;

                case KeyType.Text:
                    keyDefs.Add(Builders <T> .IndexKeys.Text(key.PropertyName));
                    isTextIndex = true;
                    break;

                case KeyType.Wildcard:
                    keyDefs.Add(Builders <T> .IndexKeys.Wildcard(key.PropertyName));
                    keyType = "(Wld)";
                    break;
                }
                propNames.Add(key.PropertyName + keyType);
            }

            if (string.IsNullOrEmpty(options.Name))
            {
                if (isTextIndex)
                {
                    options.Name = "[TEXT]";
                }
                else
                {
                    options.Name = string.Join(" | ", propNames);
                }
            }

            var model = new CreateIndexModel <T>(
                Builders <T> .IndexKeys.Combine(keyDefs),
                options);

            try
            {
                await DB.CreateIndexAsync(model, db, cancellation);
            }
            catch (MongoCommandException x)
            {
                if (x.Code == 85 || x.Code == 86)
                {
                    await DB.DropIndexAsync <T>(options.Name, db, cancellation);

                    await DB.CreateIndexAsync(model, db, cancellation);
                }
                else
                {
                    throw;
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Call this method to finalize defining the index after setting the index keys and options.
        /// </summary>
        async public Task CreateAsync()
        {
            if (Keys.Count == 0)
            {
                throw new ArgumentException("Please define keys before calling this method.");
            }

            var propNames   = new HashSet <string>();
            var keyDefs     = new HashSet <IndexKeysDefinition <T> >();
            var isTextIndex = false;

            foreach (var key in Keys)
            {
                switch (key.Type)
                {
                case Type.Ascending:
                    keyDefs.Add(Builders <T> .IndexKeys.Ascending(key.Property));
                    break;

                case Type.Descending:
                    keyDefs.Add(Builders <T> .IndexKeys.Descending(key.Property));
                    break;

                case Type.Geo2D:
                    keyDefs.Add(Builders <T> .IndexKeys.Geo2D(key.Property));
                    break;

                case Type.Geo2DSphere:
                    keyDefs.Add(Builders <T> .IndexKeys.Geo2DSphere(key.Property));
                    break;

                case Type.GeoHaystack:
                    keyDefs.Add(Builders <T> .IndexKeys.GeoHaystack(key.Property));
                    break;

                case Type.Hashed:
                    keyDefs.Add(Builders <T> .IndexKeys.Hashed(key.Property));
                    break;

                case Type.Text:
                    keyDefs.Add(Builders <T> .IndexKeys.Text(key.Property));
                    isTextIndex = true;
                    break;
                }

                var member = key.Property.Body as MemberExpression;
                if (member == null)
                {
                    member = (key.Property.Body as UnaryExpression)?.Operand as MemberExpression;
                }
                if (member == null)
                {
                    throw new ArgumentException("Unable to get property name");
                }
                propNames.Add(member.Member.Name);
            }

            if (string.IsNullOrEmpty(_options.Name))
            {
                _options.Name = DB.GetCollectionName <T>();
                if (isTextIndex)
                {
                    _options.Name = $"{_options.Name}[TEXT]";
                }
                else
                {
                    _options.Name = $"{_options.Name}[{string.Join("-", propNames)}]";
                }
            }

            var model = new CreateIndexModel <T>(
                Builders <T> .IndexKeys.Combine(keyDefs),
                _options.ToCreateIndexOptions());

            try
            {
                await DB.CreateIndexAsync <T>(model);
            }
            catch (MongoCommandException x)
            {
                if (x.Code == 85 || x.Code == 86)
                {
                    await DB.DropIndexAsync <T>(_options.Name);

                    await DB.CreateIndexAsync <T>(model);
                }
                else
                {
                    throw x;
                }
            }
        }