Exemple #1
0
        /// <summary>
        /// Initalizes a new instance of the <see cref="SuggestWeightFieldValueProvider"/> class.
        /// </summary>
        /// <param name="member">Member Info for the suggest field</param>
        /// <param name="fieldName">ElasticSearch field name</param>
        public SuggestWeightFieldValueProvider(MemberInfo member, string fieldName)
        {
            var ci = BYteWareTypeInfo.GetBYteWareTypeInfo(member.DeclaringType);

            _Member      = ci.TypeInfo?.FindMember(member.Name);
            _WeightField = ci.ESSuggestFields.First(t => t.FieldName == fieldName).WeightField;
        }
        /// <inheritdoc/>
        protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
        {
            if (member == null)
            {
                throw new ArgumentNullException(nameof(member));
            }
            var jp    = base.CreateProperty(member, memberSerialization);
            var bti   = BYteWareTypeInfo.GetBYteWareTypeInfo(member.DeclaringType);
            var props = bti.ESProperties(member.Name);

            jp.PropertyName = ElasticSearchClient.FieldName(string.IsNullOrEmpty(props?.FieldName) ? member.Name : props.FieldName);
            var defType = ElasticSearchClient.GetFieldTypeFromType(member.Type());

            // Omit empty values, because Suggest Fields will raise errors otherwise
            if (defType == FieldType.text || defType == FieldType.keyword)
            {
                if (typeof(IEnumerable).IsAssignableFrom(member.Type()))
                {
                    jp.ShouldSerialize = t => (member.Get(t) as IEnumerable)?.Cast <object>().Any() ?? false;
                }
                else
                {
                    jp.ShouldSerialize = t => !string.IsNullOrEmpty(member.Get(t)?.ToString());
                }
            }
            if (!string.IsNullOrEmpty(props.WeightField))
            {
                jp.PropertyType  = typeof(object);
                jp.ValueProvider = new SuggestWeightFieldValueProvider(member, jp.PropertyName);
            }
            return(jp);
        }
        /// <inheritdoc/>
        protected override IList <JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
        {
            var props = base.CreateProperties(type, memberSerialization);
            var ci    = BYteWareTypeInfo.GetBYteWareTypeInfo(type);

            foreach (var pathField in ci.ESSuggestContextPathFields.Where(cpi => ci.ClassInfo.Members.Contains(cpi.MemberInfo) && !cpi.IsIndexed))
            {
                var jp = new JsonProperty
                {
                    PropertyName      = pathField.ESFieldName,
                    PropertyType      = typeof(IEnumerable <string>),
                    DeclaringType     = type,
                    ValueProvider     = new ContextPathValueProvider(pathField),
                    AttributeProvider = new EmptyAttributeProvider(),
                    Readable          = true,
                    Writable          = false,
                };
                if (pathField.MemberInfo != null)
                {
                    if (typeof(IEnumerable).IsAssignableFrom(pathField.MemberInfo.MemberType))
                    {
                        jp.ShouldSerialize = t => (pathField.MemberInfo.GetValue(t) as IEnumerable)?.Cast <object>().Select(o => o?.ToString()).Any(s => !string.IsNullOrEmpty(s)) ?? false;
                    }
                    else
                    {
                        jp.ShouldSerialize = t => !string.IsNullOrEmpty(pathField.MemberInfo.GetValue(t)?.ToString());
                    }
                }
                props.Add(jp);
            }
            return(props);
        }
        /// <inheritdoc/>
        protected override void OnActivated()
        {
            base.OnActivated();
            var model = (IModelListViewElasticSearchFilterSettings)View.Model;

            if (model != null)
            {
                ElasticSearchResults = model.ElasticSearchResults;
                RefreshBeforeSearch  = model.RefreshBeforeSearch;
            }
            if (Frame != null && Frame.Context == TemplateContext.LookupControl)
            {
                FilterFieldsAction = lookupFilterFieldsAction;
            }
            else
            {
                FilterFieldsAction = filterFieldsAction;
            }
            View.ModelChanged       += View_ModelChanged;
            isElasticSearchAvailable = false;
            var ti = View.ObjectTypeInfo;
            var os = ObjectSpace as XPObjectSpace;

            if (os != null && ElasticSearchClient.Instance.IsElasticSearchAvailable(ti))
            {
                var ci = BYteWareTypeInfo.GetBYteWareTypeInfo(ti.Type);
                if (ci.ESIndexes.All(t => ElasticSearchClient.Instance.IsIndexActive(t, os.Session)))
                {
                    isElasticSearchAvailable = true;
                }
            }
            FilterFieldsAction.Active.SetItemValue(NoElasticSearchReason, IsElasticSearchAvailable);
            SetupFilterFields();
        }
Exemple #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="TypeMappingWriter"/> class.
        /// internal constructor by TypeMappingWriter itself when it recurses, passes seenTypes as safeguard against maxRecursion
        /// </summary>
        /// <param name="ec">ElasticSearchClient instance</param>
        /// <param name="bti">Type to create the mapping for</param>
        /// <param name="maxRecursion">Maximum number of recursions for nested types</param>
        /// <param name="optOut">Was the type marked as opting out of ElasticSearch indexing</param>
        /// <param name="baseType">Type Info for the base class</param>
        /// <param name="seenTypes">Already visited types</param>
        internal TypeMappingWriter(ElasticSearchClient ec, BYteWareTypeInfo bti, int maxRecursion, bool optOut, BYteWareTypeInfo baseType, ConcurrentDictionary <Type, int> seenTypes)
        {
            byteWareTypeInfo    = bti;
            baseBWTypeInfo      = baseType;
            elasticSearchClient = ec;

            MaxRecursion = maxRecursion;
            OptOut       = optOut;

            SeenTypes = seenTypes;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="TypeMappingWriter"/> class.
        /// </summary>
        /// <param name="ec">ElasticSearchClient instance</param>
        /// <param name="bti">Type to create the mapping for</param>
        /// <param name="maxRecursion">Maximum number of recursions for nested types</param>
        /// <param name="optOut">Was the type marked as opting out of ElasticSearch indexing</param>
        public TypeMappingWriter(ElasticSearchClient ec, BYteWareTypeInfo bti, int maxRecursion, bool optOut)
        {
            byteWareTypeInfo    = bti ?? throw new ArgumentNullException(nameof(bti));
            baseBWTypeInfo      = bti;
            elasticSearchClient = ec ?? throw new ArgumentNullException(nameof(ec));

            MaxRecursion = maxRecursion;
            OptOut       = optOut;

            SeenTypes = new ConcurrentDictionary <Type, int>();
            SeenTypes.TryAdd(bti.Type, 0);
        }
        protected override List <MemberInfo> GetSerializableMembers(Type objectType)
        {
            var source = new List <MemberInfo>();
            var bti    = BYteWareTypeInfo.GetBYteWareTypeInfo(objectType);

            foreach (var p in bti.GetTopPropertyInfos)
            {
                var props = bti.ESProperties(p.Name);
                var type  = ElasticSearchClient.GetElasticSearchType(props, p.PropertyType);
                if (props != null && !props.OptOut && type != null)
                {
                    source.Add(p);
                }
            }
            return(source);
        }
Exemple #8
0
        /// <summary>
        /// Generate Nodes for all ElasticSearch Indexes
        /// </summary>
        /// <param name="node">The parent node</param>
        protected override void GenerateNodesCore(ModelNode node)
        {
            if (node == null)
            {
                throw new ArgumentNullException(nameof(node));
            }
            var indexNames = new HashSet <string>();

            foreach (var ti in XafTypesInfo.Instance.PersistentTypes.Where(t => t.IsPersistent))
            {
                var bi = BYteWareTypeInfo.GetBYteWareTypeInfo(ti.Type);
                if (bi?.ESAttribute != null && indexNames.Add(bi.ESAttribute.IndexName))
                {
                    var modelElasticSearchIndex = node.AddNode <IModelElasticSearchIndex>();
                    modelElasticSearchIndex.Name = bi.ESAttribute.IndexName;
                }
            }
        }
Exemple #9
0
 /// <summary>
 /// Update Business Class Model entries with ElasticSearch settings
 /// </summary>
 /// <param name="node">The Business Class Model node</param>
 public override void UpdateNode(ModelNode node)
 {
     if (node is IModelBOModel boModel && node?.Application is IModelApplicationElasticSearch appElasticSearch)
     {
         foreach (var modelClass in boModel)
         {
             var modelElasticSearch = modelClass as IModelClassElasticSearch;
             if (modelClass.TypeInfo?.Type != null)
             {
                 var bi = BYteWareTypeInfo.GetBYteWareTypeInfo(modelClass.TypeInfo.Type);
                 if (bi?.ESAttribute != null)
                 {
                     modelElasticSearch.ElasticSearchIndex  = appElasticSearch.ElasticSearch.Indexes.GetNode(bi.ESAttribute.IndexName) as IModelElasticSearchIndex;
                     modelElasticSearch.TypeName            = bi.ESAttribute.TypeName;
                     modelElasticSearch.SourceFieldDisabled = bi.ESAttribute.SourceFieldDisabled;
                 }
             }
         }
     }
 }
Exemple #10
0
        private static void WriteProperties(JsonWriter jsonWriter, BYteWareTypeInfo bti, PropertyInfo propInfo, IElasticSearchFieldProperties props, string fieldName, string type)
        {
#pragma warning disable CC0021 // Use nameof
            var fieldProps = props as IElasticProperties;
            jsonWriter.WritePropertyName("type");
            jsonWriter.WriteValue(type);

            if (!string.IsNullOrEmpty(props.Normalizer))
            {
                jsonWriter.WritePropertyName("normalizer");
                jsonWriter.WriteValue(props.Normalizer);
            }
            else if (type == ElasticSearchClient.GetElasticSearchTypeFromFieldType(FieldType.keyword))
            {
                jsonWriter.WritePropertyName("normalizer");
                jsonWriter.WriteValue("lowercase_normalizer");
            }

            if (!string.IsNullOrEmpty(props.Analyzer))
            {
                jsonWriter.WritePropertyName("analyzer");
                jsonWriter.WriteValue(props.Analyzer);
            }
            if (props.Boost.HasValue)
            {
                jsonWriter.WritePropertyName("boost");
                jsonWriter.WriteValue(props.Boost.Value);
            }
            if (props.DocValues.HasValue)
            {
                jsonWriter.WritePropertyName("doc_values");
                jsonWriter.WriteValue(props.DocValues.Value);
            }
            if (props.EagerGlobalOrdinals.HasValue)
            {
                jsonWriter.WritePropertyName("eager_global_ordinals");
                jsonWriter.WriteValue(props.EagerGlobalOrdinals.Value);
            }
            if (props.FieldData.HasValue)
            {
                jsonWriter.WritePropertyName("fielddata");
                jsonWriter.WriteValue(props.FieldData.Value);
            }
            if (props.ESIndex.HasValue)
            {
                jsonWriter.WritePropertyName("index");
                jsonWriter.WriteValue(props.ESIndex.Value);
            }
            if (props.IndexOptions.HasValue)
            {
                jsonWriter.WritePropertyName("index_options");
                jsonWriter.WriteValue(Enum.GetName(typeof(IndexOptions), props.IndexOptions.Value));
            }
            if (props.Norms.HasValue)
            {
                jsonWriter.WritePropertyName("norms");
                jsonWriter.WriteValue(props.Norms.Value);
            }
            if (props.PositionOffsetGap.HasValue)
            {
                jsonWriter.WritePropertyName("position_offset_gap");
                jsonWriter.WriteValue(props.PositionOffsetGap.Value);
            }
            if (props.Store.HasValue)
            {
                jsonWriter.WritePropertyName("store");
                jsonWriter.WriteValue(props.Store.Value);
            }
            if (!string.IsNullOrEmpty(props.SearchAnalyzer))
            {
                jsonWriter.WritePropertyName("search_analyzer");
                jsonWriter.WriteValue(props.SearchAnalyzer);
            }
            if (!string.IsNullOrEmpty(props.SearchQuoteAnalyzer))
            {
                jsonWriter.WritePropertyName("search_quote_analyzer");
                jsonWriter.WriteValue(props.SearchQuoteAnalyzer);
            }
            if (!string.IsNullOrEmpty(props.Similarity))
            {
                jsonWriter.WritePropertyName("similarity");
                jsonWriter.WriteValue(props.Similarity);
            }
            if (props.TermVector.HasValue)
            {
                jsonWriter.WritePropertyName("term_vector");
                jsonWriter.WriteValue(Enum.GetName(typeof(TermVectorOption), props.TermVector.Value));
            }
            if (props.IgnoreAbove.HasValue)
            {
                jsonWriter.WritePropertyName("ignore_above");
                jsonWriter.WriteValue(props.IgnoreAbove.Value);
            }
            if (!string.IsNullOrEmpty(props.NullValue))
            {
                jsonWriter.WritePropertyName("null_value");
                jsonWriter.WriteValue(props.NullValue);
            }
            if (props.Coerce.HasValue)
            {
                jsonWriter.WritePropertyName("coerce");
                jsonWriter.WriteValue(props.Coerce.Value);
            }
            if (props.IgnoreMalformed.HasValue)
            {
                jsonWriter.WritePropertyName("ignore_malformed");
                jsonWriter.WriteValue(props.IgnoreMalformed.Value);
            }
            if (props.ScalingFactor.HasValue)
            {
                jsonWriter.WritePropertyName("scaling_factor");
                jsonWriter.WriteValue(props.ScalingFactor.Value);
            }
            if (!string.IsNullOrEmpty(props.DateFormat))
            {
                jsonWriter.WritePropertyName("format");
                jsonWriter.WriteValue(props.DateFormat);
            }
            if (!string.IsNullOrEmpty(props.Locale))
            {
                jsonWriter.WritePropertyName("locale");
                jsonWriter.WriteValue(props.Locale);
            }
            if (fieldProps != null && fieldProps.IncludeInAll.HasValue)
            {
                jsonWriter.WritePropertyName("include_in_all");
                jsonWriter.WriteValue(fieldProps.IncludeInAll.Value);
            }
            if (props.PreserveSeparators.HasValue)
            {
                jsonWriter.WritePropertyName("preserve_separators");
                jsonWriter.WriteValue(props.PreserveSeparators.Value);
            }
            if (props.PreservePositionIncrements.HasValue)
            {
                jsonWriter.WritePropertyName("preserve_position_increments");
                jsonWriter.WriteValue(props.PreservePositionIncrements.Value);
            }
            if (props.MaxInputLength.HasValue)
            {
                jsonWriter.WritePropertyName("max_input_length");
                jsonWriter.WriteValue(props.MaxInputLength.Value);
            }
            if (fieldProps != null && !string.IsNullOrEmpty(fieldProps.CopyTo))
            {
                jsonWriter.WritePropertyName("copy_to");
                jsonWriter.WriteStartArray();
                foreach (var item in fieldProps.CopyTo.Split(";, ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
                {
                    jsonWriter.WriteValue(item);
                }
                jsonWriter.WriteEndArray();
            }
            if (type == ElasticSearchClient.GetElasticSearchTypeFromFieldType(FieldType.completion))
            {
                var defType = ElasticSearchClient.GetFieldTypeFromType(propInfo.PropertyType);
                if (defType != FieldType.text && defType != FieldType.keyword)
                {
                    throw new ElasticIndexException(CaptionHelper.GetLocalizedText(ElasticSearchClient.IndexExceptionGroup, "SuggestNoString"));
                }
                var sf = bti.ESSuggestFields.First(t => t.FieldName == fieldName);
                if (sf.ContextSettings.Any())
                {
                    jsonWriter.WritePropertyName("contexts");
                    jsonWriter.WriteStartArray();
                    foreach (var ca in sf.ContextSettings)
                    {
                        jsonWriter.WriteStartObject();
                        jsonWriter.WritePropertyName("name");
                        jsonWriter.WriteValue(ca.ContextName);
                        jsonWriter.WritePropertyName("type");
                        jsonWriter.WriteValue(Enum.GetName(typeof(SuggestContextType), ca.ContextType));
                        if (ca.ContextPathFieldInfo != null)
                        {
                            jsonWriter.WritePropertyName("path");
                            jsonWriter.WriteValue(ca.ContextPathFieldInfo.ESFieldName);
                        }
                        if (!string.IsNullOrEmpty(ca.Precision))
                        {
                            jsonWriter.WritePropertyName("precision");
                            jsonWriter.WriteValue(ca.Precision);
                        }
                        jsonWriter.WriteEndObject();
                    }
                    jsonWriter.WriteEndArray();
                }
            }
#pragma warning restore CC0021 // Use nameof
        }
Exemple #11
0
        internal void WriteProperties(JsonWriter jsonWriter)
        {
            foreach (var p in byteWareTypeInfo.GetTopPropertyInfos)
            {
                var props        = byteWareTypeInfo.ESProperties(p.Name);
                var type         = ElasticSearchClient.GetElasticSearchType(props, p.PropertyType);
                var propertyName = ElasticSearchClient.FieldName(string.IsNullOrEmpty(props?.FieldName) ? p.Name : props.FieldName);
                if ((props != null && props.OptOut) || (props == null && OptOut) || (type == null))
                {
                    continue;
                }

                jsonWriter.WritePropertyName(propertyName);
                jsonWriter.WriteStartObject();
                {
                    if (props == null)
                    {
                        // properties that follow can not be inferred from the CLR.
#pragma warning disable CC0021 // Use nameof
                        jsonWriter.WritePropertyName("type");
#pragma warning restore CC0021 // Use nameof
                        jsonWriter.WriteValue(type);
                    }
                    else
                    {
                        WriteProperties(jsonWriter, byteWareTypeInfo, p, props, propertyName, type);
                        var multiFields = BYteWareTypeInfo.Model != null ? (props as IModelMemberElasticSearchField)?.Fields : Attribute.GetCustomAttributes(p, typeof(ElasticMultiFieldAttribute), true).OfType <IElasticSearchFieldProperties>();
                        if (multiFields != null && multiFields.Any())
                        {
                            jsonWriter.WritePropertyName("fields");
                            jsonWriter.WriteStartObject();
                            foreach (var ga in multiFields.GroupBy(t => t.FieldName))
                            {
                                var a         = ga.First();
                                var fieldName = ElasticSearchClient.FieldName(ga.Key);
                                jsonWriter.WritePropertyName(fieldName);
                                jsonWriter.WriteStartObject();
                                WriteProperties(jsonWriter, byteWareTypeInfo, p, a, string.Format(CultureInfo.InvariantCulture, "{0}.{1}", propertyName, fieldName), ElasticSearchClient.GetElasticSearchType(a, p.PropertyType));
                                jsonWriter.WriteEndObject();
                            }
                            jsonWriter.WriteEndObject();
                        }
                    }
                    if (type == "object" || type == "nested")
                    {
                        var deepType  = p.PropertyType;
                        var dbti      = BYteWareTypeInfo.GetBYteWareTypeInfo(BYteWareTypeInfo.GetUnderlyingType(deepType));
                        var seenTypes = new ConcurrentDictionary <Type, int>(SeenTypes);
                        seenTypes.AddOrUpdate(deepType, 0, (t, i) => ++ i);

                        var newTypeMappingWriter = new TypeMappingWriter(elasticSearchClient, dbti, MaxRecursion, OptOut, baseBWTypeInfo, seenTypes);
                        var nestedProperties     = newTypeMappingWriter.MapProperties();

                        jsonWriter.WritePropertyName("properties");
                        nestedProperties.WriteTo(jsonWriter);
                        foreach (var pathField in byteWareTypeInfo.ESSuggestContextPathFields.Where(pi => dbti.ClassInfo.Members.Contains(pi.MemberInfo)))
                        {
                            WritePathField(jsonWriter, pathField);
                        }
                    }
                }
                jsonWriter.WriteEnd();
            }
        }
Exemple #12
0
 private void Application_ModelChanged(object sender, EventArgs e)
 {
     BYteWareTypeInfo.ModelRefresh();
     BYteWareTypeInfo.Model = Application.Model;
 }
Exemple #13
0
 private void Application_LoggingOff(object sender, LoggingOffEventArgs e)
 {
     BYteWareTypeInfo.LoggingOff();
 }
 protected override void FullTextSearch(ParametrizedActionExecuteEventArgs args)
 {
     if (args == null)
     {
         throw new ArgumentNullException(nameof(args));
     }
     WaitScreen.Instance.Show(CaptionHelper.GetLocalizedText(ElasticSearchClient.MessageGroup, "FullTextSearchWaitScreenCaption"), CaptionHelper.GetLocalizedText(ElasticSearchClient.MessageGroup, "FullTextSearchWaitScreenText"));
     try
     {
         if (RefreshBeforeSearch)
         {
             ObjectSpace.Refresh();
         }
         lastSearchElastic = false;
         if (IsElasticSearchAvailable)
         {
             var ci = BYteWareTypeInfo.GetBYteWareTypeInfo(View.ObjectTypeInfo.Type);
             if (!ci.ElasticIndexError)
             {
                 var  searchText = args.ParameterCurrentValue == null ? string.Empty : args.ParameterCurrentValue.ToString();
                 bool fuzzy;
                 bool wildcard;
                 if (string.IsNullOrEmpty(searchText))
                 {
                     searchText = "*";
                 }
                 searchText = ElasticSearchClient.PrepareSearchText(searchText, out fuzzy, out wildcard);
                 var filter = string.Empty;
                 if (SetFilterAction.Active && SetFilterAction.SelectedItem != null && SetFilterAction.SelectedItem.Model != null)
                 {
                     var filterExtension = SetFilterAction.SelectedItem.Model as IModelListViewFilterItemElasticSearch;
                     if (filterExtension != null)
                     {
                         filter = filterExtension.ElasticSearchFilter ?? string.Empty;
                     }
                 }
                 var customSearchEventArgs = new CustomSearchEventArgs(
                     args.ParameterCurrentValue == null ? string.Empty : args.ParameterCurrentValue.ToString(),
                     ci.ESIndexes.ToArray(),
                     ci.ESTypes.ToArray(),
                     filter,
                     ci.ESSecurityFilter);
                 SearchOptions(searchText, fuzzy, wildcard, customSearchEventArgs);
                 lastSearchElastic = customSearchEventArgs.Handled;
                 if (!lastSearchElastic)
                 {
                     var hits = ElasticSearchClient.Instance.Search(customSearchEventArgs.Indexes, customSearchEventArgs.Types, customSearchEventArgs.Json);
                     if (hits != null)
                     {
                         _ElasticCanFuzzy = (!wildcard && !fuzzy) || (wildcard && !searchText.EveryWordContains("~"));
                         if (hits.Total == 0 && _ElasticCanFuzzy && !customSearchEventArgs.Retry)
                         {
                             hits = DoFuzzySearch(customSearchEventArgs, wildcard, searchText);
                         }
                         if (!lastSearchElastic && hits != null)
                         {
                             View.CollectionSource.CollectionReloaded -= CollectionSource_CollectionReloaded;
                             View.CollectionSource.CollectionChanged  -= CollectionSource_CollectionReloaded;
                             SaveScores(hits);
                             if (View.CollectionSource.List.Count <= 0 && _ElasticCanFuzzy && !customSearchEventArgs.Retry)
                             {
                                 hits = DoFuzzySearch(customSearchEventArgs, wildcard, searchText);
                                 if (hits != null)
                                 {
                                     SaveScores(hits);
                                 }
                             }
                             if (hits != null)
                             {
                                 if (!View.CollectionSource.IsServerMode)
                                 {
                                     CollectionSource_CollectionReloaded(View.CollectionSource, null);
                                     View.CollectionSource.CollectionReloaded += CollectionSource_CollectionReloaded;
                                     View.CollectionSource.CollectionChanged  += CollectionSource_CollectionReloaded;
                                 }
                                 lastSearchElastic       = true;
                                 SetFilterAction.ToolTip = GetToolTip();
                             }
                         }
                     }
                 }
             }
         }
         if (!lastSearchElastic)
         {
             if (FilterFieldsAction.Active)
             {
                 FilterFieldsAction.Active.SetItemValue(NoElasticSearchReason, false);
             }
             scores.Clear();
             base.FullTextSearch(args);
         }
         else
         {
             if (!FilterFieldsAction.Active[NoElasticSearchReason])
             {
                 FilterFieldsAction.Active.SetItemValue(NoElasticSearchReason, true);
             }
         }
     }
     finally
     {
         WaitScreen.Instance.Hide();
     }
 }