Skip to content

Fix #3323 Add support for null_value, ignore_z_value on GeoPoint prop… #3364

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 20, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/Nest/Mapping/MetaFields/IFieldMapping.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
namespace Nest
{
/// <summary>
/// A document field mapping in Elasticsearch
/// </summary>
public interface IFieldMapping { }
}
9 changes: 7 additions & 2 deletions src/Nest/Mapping/Types/CorePropertyBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

namespace Nest
{
/// <summary>
/// Core properties of a mapping for a property type to a document field in Elasticsearch
/// </summary>
[JsonObject(MemberSerialization.OptIn)]
[ContractJsonConverter(typeof(PropertyJsonConverter))]
public interface ICoreProperty : IProperty
Expand All @@ -20,13 +23,14 @@ public interface ICoreProperty : IProperty

/// <summary>
/// Configures multi-fields for this field. Allows one field to be indexed in different
/// ways to serve different purposes
/// ways to serve different search and analytics purposes
/// </summary>
[JsonProperty("fields", DefaultValueHandling = DefaultValueHandling.Ignore)]
IProperties Fields { get; set; }

/// <summary>
/// Which relevancy scoring algorithm or similarity should be used. Defaults to BM25
/// Which relevancy scoring algorithm or similarity should be used.
/// Defaults to <see cref="SimilarityOption.BM25"/>
/// </summary>
[JsonProperty("similarity")]
Union<SimilarityOption, string> Similarity { get; set; }
Expand All @@ -40,6 +44,7 @@ public interface ICoreProperty : IProperty
Fields CopyTo { get; set; }
}

/// <inheritdoc cref="ICoreProperty"/>
[DebuggerDisplay("{DebugDisplay}")]
public abstract class CorePropertyBase : PropertyBase, ICoreProperty
{
Expand Down
6 changes: 6 additions & 0 deletions src/Nest/Mapping/Types/CorePropertyDescriptorBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

namespace Nest
{
/// <inheritdoc cref="ICoreProperty"/>
public abstract class CorePropertyDescriptorBase<TDescriptor, TInterface, T>
: PropertyDescriptorBase<TDescriptor, TInterface, T>, ICoreProperty
where TDescriptor : CorePropertyDescriptorBase<TDescriptor, TInterface, T>, TInterface
Expand All @@ -16,14 +17,19 @@ public abstract class CorePropertyDescriptorBase<TDescriptor, TInterface, T>

protected CorePropertyDescriptorBase(FieldType type) : base(type) {}

/// <inheritdoc cref="ICoreProperty.Store"/>
public TDescriptor Store(bool? store = true) => Assign(a => a.Store = store);

/// <inheritdoc cref="ICoreProperty.Fields"/>
public TDescriptor Fields(Func<PropertiesDescriptor<T>, IPromise<IProperties>> selector) => Assign(a => a.Fields = selector?.Invoke(new PropertiesDescriptor<T>())?.Value);

/// <inheritdoc cref="ICoreProperty.Similarity"/>
public TDescriptor Similarity(SimilarityOption? similarity) => Assign(a => a.Similarity = similarity);

/// <inheritdoc cref="ICoreProperty.Similarity"/>
public TDescriptor Similarity(string similarity) => Assign(a => a.Similarity = similarity);

/// <inheritdoc cref="ICoreProperty.CopyTo"/>
public TDescriptor CopyTo(Func<FieldsDescriptor<T>, IPromise<Fields>> fields) => Assign(a => a.CopyTo = fields?.Invoke(new FieldsDescriptor<T>())?.Value);
}
}
9 changes: 9 additions & 0 deletions src/Nest/Mapping/Types/DocValuesPropertyBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,27 @@

namespace Nest
{
/// <summary>
/// Properties of a mapping for a property type to a document field that has doc_values in Elasticsearch
/// </summary>
[JsonObject(MemberSerialization.OptIn)]
[ContractJsonConverter(typeof(PropertyJsonConverter))]
public interface IDocValuesProperty : ICoreProperty
{
/// <summary>
/// Whether to persist the value at index time in a columnar data structure (referred to as doc_values in Lucene)
/// which makes the value available for efficient sorting and aggregations. Default is <c>true</c>.
/// </summary>
[JsonProperty("doc_values")]
bool? DocValues { get; set; }
}

/// <inheritdoc cref="IDocValuesProperty"/>
public abstract class DocValuesPropertyBase : CorePropertyBase, IDocValuesProperty
{
protected DocValuesPropertyBase(FieldType type) : base(type) { }

/// <inheritdoc />
public bool? DocValues { get; set; }
}
}
2 changes: 2 additions & 0 deletions src/Nest/Mapping/Types/DocValuesPropertyDescriptorBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

namespace Nest
{
/// <inheritdoc cref="IDocValuesProperty"/>
public abstract class DocValuesPropertyDescriptorBase<TDescriptor, TInterface, T>
: CorePropertyDescriptorBase<TDescriptor, TInterface, T>, IDocValuesProperty
where TDescriptor : DocValuesPropertyDescriptorBase<TDescriptor, TInterface, T>, TInterface
Expand All @@ -13,6 +14,7 @@ public abstract class DocValuesPropertyDescriptorBase<TDescriptor, TInterface, T

protected DocValuesPropertyDescriptorBase(FieldType type) : base(type) { }

/// <inheritdoc cref="IDocValuesProperty.DocValues"/>
public TDescriptor DocValues(bool? docValues = true) => Assign(a => a.DocValues = docValues);
}
}
8 changes: 7 additions & 1 deletion src/Nest/Mapping/Types/Geo/GeoPoint/GeoPointAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ public class GeoPointAttribute : ElasticsearchDocValuesPropertyAttributeBase, IG
public GeoPointAttribute() : base(FieldType.GeoPoint) { }

bool? IGeoPointProperty.IgnoreMalformed { get; set; }
bool? IGeoPointProperty.IgnoreZValue { get; set; }
GeoLocation IGeoPointProperty.NullValue { get; set; }

public bool IgnoreMalformed { get { return Self.IgnoreMalformed.GetValueOrDefault(); } set { Self.IgnoreMalformed = value; } }
/// <inheritdoc cref="IGeoPointProperty.IgnoreMalformed"/>
public bool IgnoreMalformed { get => Self.IgnoreMalformed.GetValueOrDefault(); set => Self.IgnoreMalformed = value; }

/// <inheritdoc cref="IGeoPointProperty.IgnoreZValue"/>
public bool IgnoreZValue { get => Self.IgnoreZValue.GetValueOrDefault(true); set => Self.IgnoreZValue= value; }
}
}
40 changes: 40 additions & 0 deletions src/Nest/Mapping/Types/Geo/GeoPoint/GeoPointProperty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,50 @@

namespace Nest
{
/// <summary>
/// Data type mapping to map a property as a geopoint
/// </summary>
[JsonObject(MemberSerialization.OptIn)]
public interface IGeoPointProperty : IDocValuesProperty
{
/// <summary>
/// If true, malformed geo-points are ignored. If false (default), malformed
/// geo-points throw an exception and reject the whole document.
/// </summary>
[JsonProperty("ignore_malformed")]
bool? IgnoreMalformed { get; set; }


/// <summary>
/// If true (default) three dimension points will be accepted (stored in source) but only
/// latitude and longitude values will be indexed; the third dimension is ignored. If false, geo-points
/// containing any more than latitude and longitude (two dimensions) values
/// throw an exception and reject the whole document.
/// </summary>
[JsonProperty("ignore_z_value")]
bool? IgnoreZValue { get; set; }

/// <summary>
/// Accepts a geo_point value which is substituted for any explicit null values.
/// Defaults to null, which means the field is treated as missing.
/// </summary>
[JsonProperty("null_value")]
GeoLocation NullValue { get; set; }
}

[DebuggerDisplay("{DebugDisplay}")]
public class GeoPointProperty : DocValuesPropertyBase, IGeoPointProperty
{
public GeoPointProperty() : base(FieldType.GeoPoint) { }

/// <inheritdoc />
public bool? IgnoreMalformed { get; set; }

/// <inheritdoc />
public bool? IgnoreZValue { get; set; }

/// <inheritdoc />
public GeoLocation NullValue { get; set; }
}

[DebuggerDisplay("{DebugDisplay}")]
Expand All @@ -25,9 +56,18 @@ public class GeoPointPropertyDescriptor<T>
where T : class
{
bool? IGeoPointProperty.IgnoreMalformed { get; set; }
bool? IGeoPointProperty.IgnoreZValue { get; set; }
GeoLocation IGeoPointProperty.NullValue { get; set; }

public GeoPointPropertyDescriptor() : base(FieldType.GeoPoint) { }

/// <inheritdoc cref="IGeoPointProperty.IgnoreMalformed" />
public GeoPointPropertyDescriptor<T> IgnoreMalformed(bool? ignoreMalformed = true) => Assign(a => a.IgnoreMalformed = ignoreMalformed);

/// <inheritdoc cref="IGeoPointProperty.IgnoreZValue" />
public GeoPointPropertyDescriptor<T> IgnoreZValue(bool? ignoreZValue = true) => Assign(a => a.IgnoreZValue = ignoreZValue);

/// <inheritdoc cref="IGeoPointProperty.NullValue" />
public GeoPointPropertyDescriptor<T> NullValue(GeoLocation defaultValue) => Assign(a => a.NullValue = defaultValue);
}
}
2 changes: 1 addition & 1 deletion src/Nest/Mapping/Types/Properties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public partial interface IPropertiesDescriptor<T, out TReturnType>
TReturnType Text(Func<TextPropertyDescriptor<T>, ITextProperty> selector);
TReturnType Keyword(Func<KeywordPropertyDescriptor<T>, IKeywordProperty> selector);
/// <summary>
/// Number introduces a numeric mapping that defaults to `float` use .Type() to set the right type if needed or use
/// Number introduces a numeric mapping that defaults to `float`. Use .Type() to set the right type if needed or use
/// Scalar instead of <see cref="Number"/>
/// </summary>
TReturnType Number(Func<NumberPropertyDescriptor<T>, INumberProperty> selector);
Expand Down
22 changes: 16 additions & 6 deletions src/Nest/Mapping/Types/PropertyBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

namespace Nest
{
/// <summary>
/// A mapping for a property type to a document field in Elasticsearch
/// </summary>
[JsonObject(MemberSerialization.OptIn)]
[ContractJsonConverter(typeof(PropertyJsonConverter))]
public interface IProperty : IFieldMapping
Expand All @@ -29,25 +32,32 @@ public interface IProperty : IFieldMapping
IDictionary<string, object> LocalMetadata { get; set; }
}

/// <summary>
/// A mapping for a property from a CLR type
/// </summary>
public interface IPropertyWithClrOrigin
{
/// <summary>
/// The CLR property to which the mapping relates
/// </summary>
PropertyInfo ClrOrigin { get; set; }
}

/// <inheritdoc cref="IProperty"/>
[DebuggerDisplay("{DebugDisplay}")]
public abstract class PropertyBase : IProperty, IPropertyWithClrOrigin
{
private string _type;
protected string TypeOverride { get => _type; set => _type = value; }

string IProperty.Type { get => _type; set => _type = value; }

PropertyInfo IPropertyWithClrOrigin.ClrOrigin { get; set; }

protected PropertyBase(FieldType type)
{
((IProperty)this).Type = type.GetStringValue();
}
protected PropertyBase(FieldType type) => ((IProperty)this).Type = type.GetStringValue();

/// <summary>
/// Override for the property type, used for custom mappings
/// </summary>
protected string TypeOverride { get => _type; set => _type = value; }

protected string DebugDisplay => $"Type: {((IProperty)this).Type ?? "<empty>"}, Name: {Name.DebugDisplay} ";

Expand Down
7 changes: 4 additions & 3 deletions src/Nest/Mapping/Types/PropertyDescriptorBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

namespace Nest
{
/// <inheritdoc cref="IProperty"/>
public abstract class PropertyDescriptorBase<TDescriptor, TInterface, T>
: DescriptorBase<TDescriptor, TInterface>, IProperty
where TDescriptor : PropertyDescriptorBase<TDescriptor, TInterface, T>, TInterface
Expand All @@ -21,13 +22,13 @@ public abstract class PropertyDescriptorBase<TDescriptor, TInterface, T>

protected PropertyDescriptorBase(FieldType type) { Self.Type = type.GetStringValue(); }

/// <inheritdoc cref="IProperty.Name"/>
public TDescriptor Name(PropertyName name) => Assign(a => a.Name = name);

/// <inheritdoc cref="IProperty.Name"/>
public TDescriptor Name(Expression<Func<T, object>> objectPath) => Assign(a => a.Name = objectPath);

/// <summary>
/// Local property metadata that will NOT be stored in Elasticsearch with the mappings
/// </summary>
/// <inheritdoc cref="IProperty.LocalMetadata"/>
public TDescriptor LocalMetadata(Func<FluentDictionary<string, object>, FluentDictionary<string, object>> selector) =>
Assign(a => a.LocalMetadata = selector?.Invoke(new FluentDictionary<string, object>()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ namespace Tests.Mapping.Types.Geo.GeoPoint
{
public class GeoPointTest
{
[GeoPoint(
IgnoreMalformed = true)]
[GeoPoint(IgnoreMalformed = true, IgnoreZValue = true)]
public string Full { get; set; }

[GeoPoint]
Expand All @@ -24,7 +23,8 @@ public class GeoPointAttributeTests : AttributeTestsBase<GeoPointTest>
full = new
{
type = "geo_point",
ignore_malformed = true
ignore_malformed = true,
ignore_z_value = true
},
minimal = new
{
Expand Down