Example #1
0
        public static PropertiesDescriptor <T> SetupDefaults <T>(this PropertiesDescriptor <T> pd) where T : class
        {
            var hasIdentity         = typeof(IIdentity).IsAssignableFrom(typeof(T));
            var hasDates            = typeof(IHaveDates).IsAssignableFrom(typeof(T));
            var hasCreatedDate      = typeof(IHaveCreatedDate).IsAssignableFrom(typeof(T));
            var supportsSoftDeletes = typeof(ISupportSoftDeletes).IsAssignableFrom(typeof(T));

            if (hasIdentity)
            {
                pd.String(p => p.Name(d => (d as IIdentity).Id).IndexName("id").Index(FieldIndexOption.NotAnalyzed));
            }

            if (supportsSoftDeletes)
            {
                pd.Boolean(p => p.Name(d => (d as ISupportSoftDeletes).IsDeleted).IndexName(SoftDeletesQueryBuilder.Fields.Deleted));
            }

            if (hasCreatedDate)
            {
                pd.Date(p => p.Name(d => (d as IHaveCreatedDate).CreatedUtc).IndexName("created"));
            }

            if (hasDates)
            {
                pd.Date(p => p.Name(d => (d as IHaveDates).UpdatedUtc).IndexName("updated"));
            }

            return(pd);
        }
Example #2
0
        private void FromExamineType(PropertiesDescriptor <Document> descriptor, FieldDefinition field)
        {
            switch (field.Type.ToLowerInvariant())
            {
            case "date":
            case "datetimeoffset":
                descriptor.Date(s => s.Name(field.Name));
                break;

            case "double":
                descriptor.Number(s => s.Name(field.Name).Type(NumberType.Double));
                break;

            case "float":
                descriptor.Number(s => s.Name(field.Name).Type(NumberType.Float));
                break;

            case "long":
                descriptor.Number(s => s.Name(field.Name).Type(NumberType.Long));
                break;

            case "int":
            case "number":
                descriptor.Number(s => s.Name(field.Name).Type(NumberType.Integer));
                break;

            default:
                descriptor.Text(s => s.Name(field.Name).Analyzer(FromLuceneAnalyzer(Analyzer)));
                break;
            }
        }
        public static PropertiesDescriptor <T> DateTimeOffset <T>(this PropertiesDescriptor <T> propertiesDescriptor,
                                                                  Func <DatePropertyDescriptor <T>, IDateProperty> selector)
            where T : class
        {
            // Validate parameters.
            if (propertiesDescriptor == null)
            {
                throw new ArgumentNullException(nameof(propertiesDescriptor));
            }
            if (selector == null)
            {
                throw new ArgumentNullException(nameof(selector));
            }

            // Modify and return.
            return(propertiesDescriptor.Date(selector));
        }
Example #4
0
        /// <summary>
        /// Obtient le mapping de champ Elastic pour une catégorie donnée.
        /// </summary>
        /// <param name="selector">Descripteur des propriétés.</param>
        /// <param name="field">Catégorie de champ.</param>
        /// <returns>Mapping de champ.</returns>
        /// <typeparam name="T">Type du document.</typeparam>
        public PropertiesDescriptor <T> AddField <T>(PropertiesDescriptor <T> selector, DocumentFieldDescriptor field)
            where T : class
        {
            var fieldName = field.FieldName;

            /* TODO Externaliser. */

            switch (field.Category)
            {
            case SearchFieldCategory.Result:
                if (field.PropertyType == typeof(DateTime?))
                {
                    return(selector.Date(x => x
                                         .Name(fieldName)
                                         .Index(false)
                                         .Store(true)));
                }

                if (field.PropertyType == typeof(int?))
                {
                    return(selector.Number(x => x
                                           .Name(fieldName)
                                           .Type(NumberType.Integer)
                                           .Index(false)
                                           .Store(true)));
                }

                if (field.PropertyType == typeof(decimal?))
                {
                    return(selector.Number(x => x
                                           .Name(fieldName)
                                           .Type(NumberType.Double)
                                           .Index(false)
                                           .Store(true)));
                }

                return(selector.Text(x => x
                                     .Name(fieldName)
                                     .Index(false)
                                     .Store(true)));

            case SearchFieldCategory.Search:
                /* Champ de recherche textuelle full-text. */
                return(selector.Text(x => x
                                     .Name(fieldName)
                                     .Index(true)
                                     .Store(false)
                                     .Analyzer("text_fr")));

            case SearchFieldCategory.Security:
                /* Champ de filtrage de sécurité : listes de code. */
                /* TODO : faire un mapping plus spécifique ? */
                return(selector.Text(x => x
                                     .Name(fieldName)
                                     .Index(true)
                                     .Store(true)
                                     .Analyzer("text_fr")));

            case SearchFieldCategory.Facet:
                /* Champ de facette. */
                if (field.PropertyType == typeof(DateTime?))
                {
                    throw new ElasticException("Le type DateTime n'est pas supporté pour le champ de facette " + field.FieldName);
                }

                if (field.PropertyType == typeof(decimal?))
                {
                    return(selector.Number(x => x
                                           .Name(fieldName)
                                           .Index(true)
                                           .Store(false)));
                }

                return(selector.Keyword(x => x
                                        .Name(fieldName)
                                        .Index(true)
                                        .Store(false)));

            case SearchFieldCategory.ListFacet:
                return(selector.Text(x => x
                                     .Name(fieldName)
                                     .Index(true)
                                     .Store(false)
                                     .Analyzer("text_fr")));

            case SearchFieldCategory.Sort:
                if (field.PropertyType == typeof(DateTime?))
                {
                    return(selector.Date(x => x
                                         .Name(fieldName)
                                         .Index(true)
                                         .Store(false)));
                }

                if (field.PropertyType == typeof(decimal?))
                {
                    return(selector.Number(x => x
                                           .Name(fieldName)
                                           .Index(true)
                                           .Store(false)));
                }

                return(selector.Keyword(x => x
                                        .Name(fieldName)
                                        .Index(true)
                                        .Store(false)));

            case SearchFieldCategory.Filter:
                /* Champ filtre. */
                if (field.PropertyType == typeof(DateTime?))
                {
                    throw new ElasticException("Le type DateTime n'est pas supporté pour le champ de filtrage " + field.FieldName);
                }

                if (field.PropertyType == typeof(decimal?))
                {
                    return(selector.Number(x => x
                                           .Name(fieldName)
                                           .Index(true)
                                           .Store(false)));
                }

                return(selector.Keyword(x => x
                                        .Name(fieldName)
                                        .Index(true)
                                        .Store(false)));

            case SearchFieldCategory.Id:
                return(selector);

            default:
                throw new NotSupportedException("Category not supported : " + field.Category);
            }
        }
Example #5
0
        public static IPromise <IProperties> MapProperties(JToken node, PropertiesDescriptor <object> descriptor, PropertiesDescriptor <object> analyzers, List <string> interpretedFields, string path)
        {
            var properties = node.Children <JProperty>().ToList();

            foreach (JProperty property in properties)
            {
                var name          = property.Name;
                var fullPath      = path.AppendSeparator(".") + name;
                var isInterpreted = interpretedFields.Contains(fullPath, StringComparer.OrdinalIgnoreCase);
                Func <PropertiesDescriptor <object>, IPromise <IProperties> > applyAnalyzerFields = field => isInterpreted ? analyzers : field;
                var tokenPrefix = string.Empty;

                var type   = property.Value.SelectToken(SchemaHelper.Elements.Type)?.Value <string>();
                var format = property.Value.SelectToken(SchemaHelper.Elements.Format)?.Value <string>();

                if (string.IsNullOrEmpty(type))
                {
                    // Json schema validator should catch this
                    throw new ArgumentNullException($"Elastic type is not provided");
                }

                // Elastic nem kezel külön array-t, ezért ha így tartalmazza a schema az eleme típusát használjuk fel
                if (type == SchemaHelper.Types.Array)
                {
                    tokenPrefix = $"{SchemaHelper.Elements.Items}.";
                    type        = property.Value.SelectToken($"{tokenPrefix}{SchemaHelper.Elements.Type}")?.Value <string>();
                    format      = property.Value.SelectToken($"{tokenPrefix}{SchemaHelper.Elements.Format}")?.Value <string>();
                }

                switch (type)
                {
                case SchemaHelper.Types.String:
                {
                    descriptor.String(desc => desc
                                      .Name(name)
                                      .Fields(applyAnalyzerFields));
                    break;
                }

                case SchemaHelper.Types.Long:
                case SchemaHelper.Types.Integer:
                case SchemaHelper.Types.Short:
                case SchemaHelper.Types.Byte:
                case SchemaHelper.Types.Double:
                case SchemaHelper.Types.Float:
                {
                    var numberType = (NumberType)Enum.Parse(typeof(NumberType), type, true);
                    descriptor.Number(desc => desc
                                      .Name(name)
                                      .Type(numberType)
                                      .Fields(applyAnalyzerFields));
                    break;
                }

                case SchemaHelper.Types.Boolean:
                {
                    descriptor.Boolean(desc => desc
                                       .Name(name)
                                       .Fields(applyAnalyzerFields));
                    break;
                }

                case SchemaHelper.Types.Date:
                {
                    if (string.IsNullOrWhiteSpace(format))
                    {
                        format = "strict_date_optional_time||epoch_millis";
                    }

                    descriptor.Date(desc => desc
                                    .Name(name)
                                    .Format(format)
                                    .Fields(applyAnalyzerFields));
                }
                break;

                case SchemaHelper.Types.Attachment:
                {
                    descriptor.Attachment(desc => desc
                                          .Name(name)
                                          .FileField(d => d //ContentField
                                                     .Store(true)
                                                     .Fields(applyAnalyzerFields))
                                          .ContentTypeField(d => d.Store(true))
                                          .ContentLengthField(d => (d as NumberPropertyDescriptor <object>).Store(true))
                                          .LanguageField(d => (d as StringPropertyDescriptor <object>).Store(true))
                                          .KeywordsField(d => d.Store(true))
                                          .AuthorField(d => d.Store(true))
                                          .DateField(d => d.Store(true))
                                          .TitleField(d => d.Store(true))
                                          );
                    break;
                }

                case SchemaHelper.Types.Object:
                {
                    descriptor.Object <object>(desc => desc
                                               .Name(name)
                                               .Properties(propDesc =>
                                                           MapProperties(property.Value.SelectToken($"{tokenPrefix}{SchemaHelper.Elements.Properties}"),
                                                                         propDesc,
                                                                         analyzers,
                                                                         interpretedFields,
                                                                         fullPath)));
                    break;
                }

                default:
                {
                    throw new NotImplementedException($"Elastic type '{type}' is not implemented");
                }
                }
            }

            return(descriptor);
        }