/// <summary> /// Get a Search Index for the Hotels sample data. /// /// This index is tuned more for exercising document serialization, /// indexing, and querying operations. Also, the fields of this index /// should exactly match the properties of the Hotel test model class /// below. /// </summary> /// <param name="name"></param> /// <returns></returns> private static Microsoft.Azure.Search.Models.Index GetHotelIndex(string name) => new Microsoft.Azure.Search.Models.Index() { Name = name, Fields = new[] { Field.New("hotelId", DataType.String, isKey: true, isFilterable: true, isSortable: true, isFacetable: true), Field.New("hotelName", DataType.String, isSearchable: true, isFilterable: true, isSortable: true, isFacetable: false), Field.NewSearchableString("description", AnalyzerName.EnLucene), Field.NewSearchableString("descriptionFr", AnalyzerName.FrLucene), Field.New("category", DataType.String, isSearchable: true, isFilterable: true, isSortable: true, isFacetable: true), Field.New("tags", DataType.Collection(DataType.String), isSearchable: true, isFilterable: true, isFacetable: true), Field.New("parkingIncluded", DataType.Boolean, isFilterable: true, isSortable: true, isFacetable: true), Field.New("smokingAllowed", DataType.Boolean, isFilterable: true, isSortable: true, isFacetable: true), Field.New("lastRenovationDate", DataType.DateTimeOffset, isFilterable: true, isSortable: true, isFacetable: true), Field.New("rating", DataType.Int32, isFilterable: true, isSortable: true, isFacetable: true), Field.New("location", DataType.GeographyPoint, isFilterable: true, isSortable: true), Field.NewComplex("address", isCollection: false, fields: new[] { Field.New("streetAddress", DataType.String, isSearchable: true), Field.New("city", DataType.String, isSearchable: true, isFilterable: true, isSortable: true, isFacetable: true), Field.New("stateProvince", DataType.String, isSearchable: true, isFilterable: true, isSortable: true, isFacetable: true), Field.New("country", DataType.String, isSearchable: true, isFilterable: true, isSortable: true, isFacetable: true), Field.New("postalCode", DataType.String, isSearchable: true, isFilterable: true, isSortable: true, isFacetable: true) }), Field.NewComplex("rooms", isCollection: true, fields: new[] { Field.NewSearchableString("description", AnalyzerName.EnLucene), Field.NewSearchableString("descriptionFr", AnalyzerName.FrLucene), Field.New("type", DataType.String, isSearchable: true, isFilterable: true, isFacetable: true), Field.New("baseRate", DataType.Double, isFilterable: true, isFacetable: true), Field.New("bedOptions", DataType.String, isSearchable: true, isFilterable: true, isFacetable: true), Field.New("sleepsCount", DataType.Int32, isFilterable: true, isFacetable: true), Field.New("smokingAllowed", DataType.Boolean, isFilterable: true, isFacetable: true), Field.New("tags", DataType.Collection(DataType.String), isSearchable: true, isFilterable: true, isFacetable: true) }) }, Suggesters = new[] { new Suggester( name: "sg", sourceFields: new[] { "description", "hotelName" }) }, ScoringProfiles = new[] { new ScoringProfile("nearest") { FunctionAggregation = ScoringFunctionAggregation.Sum, Functions = new[] { new DistanceScoringFunction("location", 2, new DistanceScoringParameters("myloc", 100)) } } } };
private List <Field> GetTypeFields(Type sourceType, bool isTop) { var source = TypeAccessor.Create(sourceType); return(source.GetMembers().Select(x => { if (x.GetAttribute(typeof(JsonIgnoreAttribute), false) != null) { return null; } if (x.IsList()) { var argType = x.Type.GetGenericArguments()[0]; return new Field(x.Name, DataType.Collection(DataType.Complex), GetTypeFields(argType, false)); } DataType type; bool hasType = true; if (!TryGetDataType(x.Type, out type)) { if (x.Type.IsClass) { return new Field(x.Name, DataType.Complex, GetTypeFields(x.Type, false)); } hasType = false; } if (!hasType) { throw new ArgumentException($"Type of {x.Type.FullName} cannot be translated to Search Data-type."); } var isSearchable = x.Type == typeof(string); var isKey = isTop && x.GetAttribute(typeof(KeyAttribute), false) != null; var isFacetable = x.GetAttribute(typeof(IsFacetableAttribute), false) != null; var isFilterable = x.GetAttribute(typeof(IsFilterableAttribute), false) != null; var field = new Field(x.Name, type) { IsKey = isKey, IsSearchable = !isKey && isSearchable, IsFacetable = isFacetable, IsFilterable = isFilterable }; return field; }).Where(field => field != null).ToList()); }
/// <summary> /// Creates a new searchable string collection Field with required arguments. /// </summary> /// <param name="name">The name of the simple field.</param> /// <param name="analyzerName">The name of the analyzer to use for the field.</param> /// <param name="isKey">A value indicating whether the field uniquely /// identifies documents in the index. Default is false.</param> /// <param name="isRetrievable">A value indicating whether the field can /// be returned in a search result. Default is true.</param> /// <param name="isFilterable">A value indicating whether to enable the /// field to be referenced in $filter queries. Default is false.</param> /// <param name="isFacetable">A value indicating whether to enable the /// field to be referenced in facet queries. Default is false.</param> /// <param name="synonymMaps">A list of synonym map names that /// associates synonym maps with the field. Default is null.</param> /// <remarks>The new field will automatically be searchable and of type Collection(Edm.String).</remarks> public static Field NewSearchableCollection( string name, AnalyzerName analyzerName, bool isKey = false, bool isRetrievable = true, bool isFilterable = false, bool isFacetable = false, IList <string> synonymMaps = null) => new Field(name, DataType.Collection(DataType.String), analyzerName) { IsKey = isKey, IsRetrievable = isRetrievable, IsFilterable = isFilterable, IsFacetable = isFacetable, SynonymMaps = synonymMaps };
protected virtual Field CreateProviderField(string documentType, string fieldName, IndexDocumentField field) { DataType providerFieldType; if (field.ValueType == IndexDocumentFieldValueType.Undefined) { var originalFieldType = field.Value?.GetType() ?? typeof(object); providerFieldType = GetProviderFieldType(documentType, fieldName, originalFieldType); } else { providerFieldType = GetProviderFieldType(documentType, fieldName, field.ValueType); } var isGeoPoint = providerFieldType == DataType.GeographyPoint; var isString = providerFieldType == DataType.String; var isCollection = field.IsCollection && isString; if (isCollection) { providerFieldType = DataType.Collection(providerFieldType); } var providerField = new Field(fieldName, providerFieldType) { IsKey = fieldName == AzureSearchHelper.KeyFieldName, IsRetrievable = field.IsRetrievable, IsSearchable = isString && field.IsSearchable, IsFilterable = field.IsFilterable, IsFacetable = field.IsFilterable && !isGeoPoint, IsSortable = field.IsFilterable && !isCollection, }; if (providerField.IsSearchable == true) { providerField.IndexAnalyzer = ContentAnalyzerName; providerField.SearchAnalyzer = AnalyzerName.StandardLucene; } return(providerField); }
/// <summary> /// Creates a new complex Field with required arguments. /// </summary> /// <param name="name">The name of the complex field.</param> /// <param name="isCollection"><c>true</c> if the field should be of type Collection(Edm.ComplexType); <c>false</c> if it should be /// of type Edm.ComplexType.</param> /// <param name="fields">The sub-fields that comprise the complex type. They can be simple or complex fields themselves.</param> /// <exception cref="System.ArgumentNullException">Thrown if <c>fields</c> is null.</exception> /// <exception cref="System.ArgumentOutOfRangeException">Thrown if <c>fields</c> is empty.</exception> public static Field NewComplex(string name, bool isCollection, IList <Field> fields) => new Field(name, isCollection ? DataType.Collection(DataType.Complex) : DataType.Complex, fields);