Skip to content

Commit

Permalink
Add histogram datatype (#4367)
Browse files Browse the repository at this point in the history
This commit adds the histogram datatype to the client. The histogram datatype
is available in Elasticsearch 7.6.0+ with at least a basic license level

Closes #4358

(cherry picked from commit 6b3f816)
  • Loading branch information
russcam committed Feb 10, 2020
1 parent 3b7a847 commit 34e2b59
Show file tree
Hide file tree
Showing 13 changed files with 179 additions and 3 deletions.
4 changes: 4 additions & 0 deletions src/Nest/Mapping/DynamicTemplate/SingleMapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ public IProperty Join(Func<JoinPropertyDescriptor<T>, IJoinProperty> selector) =
selector?.Invoke(new JoinPropertyDescriptor<T>());

/// <inheritdoc />
public IProperty Histogram(Func<HistogramPropertyDescriptor<T>, IHistogramProperty> selector) =>
selector?.Invoke(new HistogramPropertyDescriptor<T>());

/// <inheritdoc />
public IProperty FieldAlias(Func<FieldAliasPropertyDescriptor<T>, IFieldAliasProperty> selector) =>
selector?.Invoke(new FieldAliasPropertyDescriptor<T>());

Expand Down
5 changes: 4 additions & 1 deletion src/Nest/Mapping/Types/FieldType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ public enum FieldType
Flattened,

[EnumMember(Value = "shape")]
Shape
Shape,

[EnumMember(Value = "histogram")]
Histogram
}
}
6 changes: 6 additions & 0 deletions src/Nest/Mapping/Types/Properties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ TReturnType Nested<TChild>(Func<NestedPropertyDescriptor<T, TChild>, INestedProp
/// <inheritdoc cref="IJoinProperty"/>
TReturnType Join(Func<JoinPropertyDescriptor<T>, IJoinProperty> selector);

/// <inheritdoc cref="IHistogramProperty"/>
TReturnType Histogram(Func<HistogramPropertyDescriptor<T>, IHistogramProperty> selector);

/// <inheritdoc cref="IFieldAliasProperty"/>
TReturnType FieldAlias(Func<FieldAliasPropertyDescriptor<T>, IFieldAliasProperty> selector);

Expand Down Expand Up @@ -212,6 +215,9 @@ public PropertiesDescriptor<T> Object<TChild>(Func<ObjectTypeDescriptor<T, TChil
/// <inheritdoc cref="IFlattenedProperty"/>
public PropertiesDescriptor<T> Flattened(Func<FlattenedPropertyDescriptor<T>, IFlattenedProperty> selector) => SetProperty(selector);

/// <inheritdoc cref="IHistogramProperty"/>
public PropertiesDescriptor<T> Histogram(Func<HistogramPropertyDescriptor<T>, IHistogramProperty> selector) => SetProperty(selector);

public PropertiesDescriptor<T> Custom(IProperty customType) => SetProperty(customType);

private PropertiesDescriptor<T> SetProperty<TDescriptor, TInterface>(Func<TDescriptor, TInterface> selector)
Expand Down
4 changes: 4 additions & 0 deletions src/Nest/Mapping/Types/PropertyFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ public IProperty Deserialize(ref JsonReader reader, IJsonFormatterResolver forma
case FieldType.RankFeature: return Deserialize<RankFeatureProperty>(ref segmentReader, formatterResolver);
case FieldType.RankFeatures: return Deserialize<RankFeaturesProperty>(ref segmentReader, formatterResolver);
case FieldType.Flattened: return Deserialize<FlattenedProperty>(ref segmentReader, formatterResolver);
case FieldType.Histogram: return Deserialize<HistogramProperty>(ref segmentReader, formatterResolver);
case FieldType.None:
// no "type" field in the property mapping, or FieldType enum could not be parsed from typeString
return Deserialize<ObjectProperty>(ref segmentReader, formatterResolver);
Expand Down Expand Up @@ -199,6 +200,9 @@ public void Serialize(ref JsonWriter writer, IProperty value, IJsonFormatterReso
case IFlattenedProperty flattenedProperty:
Serialize(ref writer, flattenedProperty, formatterResolver);
break;
case IHistogramProperty histogramProperty:
Serialize(ref writer, histogramProperty, formatterResolver);
break;
case IGenericProperty genericProperty:
Serialize(ref writer, genericProperty, formatterResolver);
break;
Expand Down
18 changes: 18 additions & 0 deletions src/Nest/Mapping/Types/Specialized/Histogram/HistogramAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace Nest
{
public class HistogramAttribute : ElasticsearchPropertyAttributeBase, IHistogramProperty
{
public HistogramAttribute() : base(FieldType.Histogram) { }

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

bool? IHistogramProperty.IgnoreMalformed { get; set; }

private IHistogramProperty Self => this;
}
}
46 changes: 46 additions & 0 deletions src/Nest/Mapping/Types/Specialized/Histogram/HistogramProperty.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System.Diagnostics;
using System.Runtime.Serialization;
using Elasticsearch.Net.Utf8Json;

namespace Nest
{
/// <summary>
/// A field to store pre-aggregated numerical data representing a histogram.
/// <para />
/// Available in Elasticsearch 7.6.0+ with at least basic license level
/// </summary>
[InterfaceDataContract]
public interface IHistogramProperty : IProperty
{
/// <summary>
/// Whether to ignore malformed input values.
/// </summary>
[DataMember(Name = "ignore_malformed")]
bool? IgnoreMalformed { get; set; }
}

/// <inheritdoc cref="IHistogramProperty"/>
[DebuggerDisplay("{DebugDisplay}")]
public class HistogramProperty : PropertyBase, IHistogramProperty
{
public HistogramProperty() : base(FieldType.Histogram) { }

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

/// <inheritdoc cref="IHistogramProperty"/>
[DebuggerDisplay("{DebugDisplay}")]
public class HistogramPropertyDescriptor<T>
: PropertyDescriptorBase<HistogramPropertyDescriptor<T>, IHistogramProperty, T>, IHistogramProperty
where T : class
{
bool? IHistogramProperty.IgnoreMalformed { get; set; }

public HistogramPropertyDescriptor() : base(FieldType.Histogram) { }

/// <inheritdoc cref="IHistogramProperty.IgnoreMalformed"/>
public HistogramPropertyDescriptor<T> IgnoreMalformed(bool? ignoreMalformed = true) =>
Assign(ignoreMalformed, (a, v) => a.IgnoreMalformed = v);
}
}
4 changes: 4 additions & 0 deletions src/Nest/Mapping/Visitor/IMappingVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ public interface IMappingVisitor
void Visit(ISearchAsYouTypeProperty property);

void Visit(IFlattenedProperty property);

void Visit(IHistogramProperty property);
}

public class NoopMappingVisitor : IMappingVisitor
Expand Down Expand Up @@ -124,5 +126,7 @@ public virtual void Visit(IRankFeaturesProperty property) { }
public virtual void Visit(ISearchAsYouTypeProperty property) { }

public virtual void Visit(IFlattenedProperty property) { }

public virtual void Visit(IHistogramProperty property) { }
}
}
2 changes: 2 additions & 0 deletions src/Nest/Mapping/Visitor/IPropertyVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ public interface IPropertyVisitor

void Visit(IFlattenedProperty type, PropertyInfo propertyInfo, ElasticsearchPropertyAttributeBase attribute);

void Visit(IHistogramProperty type, PropertyInfo propertyInfo, ElasticsearchPropertyAttributeBase attribute);

IProperty Visit(PropertyInfo propertyInfo, ElasticsearchPropertyAttributeBase attribute);

bool SkipProperty(PropertyInfo propertyInfo, ElasticsearchPropertyAttributeBase attribute);
Expand Down
10 changes: 8 additions & 2 deletions src/Nest/Mapping/Visitor/MappingWalker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,6 @@ public void Accept(IProperties properties)
Accept(t.Fields);
});
break;
case FieldType.None:
continue;
case FieldType.Percolator:
Visit<IPercolatorProperty>(field, t => { _visitor.Visit(t); });
break;
Expand Down Expand Up @@ -253,6 +251,14 @@ public void Accept(IProperties properties)
_visitor.Visit(t);
});
break;
case FieldType.Histogram:
Visit<IHistogramProperty>(field, t =>
{
_visitor.Visit(t);
});
break;
case FieldType.None:
continue;
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/Nest/Mapping/Visitor/NoopPropertyVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ public virtual void Visit(IKeywordProperty type, PropertyInfo propertyInfo, Elas

public virtual void Visit(IFlattenedProperty type, PropertyInfo propertyInfo, ElasticsearchPropertyAttributeBase attribute) { }

public virtual void Visit(IHistogramProperty type, PropertyInfo propertyInfo, ElasticsearchPropertyAttributeBase attribute) { }

public virtual IProperty Visit(PropertyInfo propertyInfo, ElasticsearchPropertyAttributeBase attribute) => null;

public void Visit(IProperty type, PropertyInfo propertyInfo, ElasticsearchPropertyAttributeBase attribute)
Expand Down Expand Up @@ -144,6 +146,9 @@ public void Visit(IProperty type, PropertyInfo propertyInfo, ElasticsearchProper
case IRankFeaturesProperty rankFeatures:
Visit(rankFeatures, propertyInfo, attribute);
break;
case IHistogramProperty histogram:
Visit(histogram, propertyInfo, attribute);
break;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@ internal class TestVisitor : IMappingVisitor

public void Visit(IFlattenedProperty property) => Increment("flattened");

public void Visit(IHistogramProperty property) => Increment("histogram");

private void Increment(string key)
{
if (!Counts.ContainsKey(key)) Counts.Add(key, 0);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using Nest;

namespace Tests.Mapping.Types.Specialized.Histogram
{
public class HistogramTest
{
[Histogram(IgnoreMalformed = true)]
public string Full { get; set; }

[Histogram]
public string Minimal { get; set; }
}

public class HistogramAttributeTests : AttributeTestsBase<HistogramTest>
{
protected override object ExpectJson => new
{
properties = new
{
full = new
{
type = "histogram",
ignore_malformed = true
},
minimal = new
{
type = "histogram"
}
}
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System;
using Elastic.Xunit.XunitPlumbing;
using Nest;
using Tests.Core.ManagedElasticsearch.Clusters;
using Tests.Domain;
using Tests.Framework.EndpointTests.TestState;

namespace Tests.Mapping.Types.Specialized.Histogram
{
[SkipVersion("<7.6.0", "Introduced in 7.6.0")]
public class HistogramPropertyTests : PropertyTestsBase
{
public HistogramPropertyTests(WritableCluster cluster, EndpointUsage usage) : base(cluster, usage) { }

protected override object ExpectJson => new
{
properties = new
{
name = new
{
type = "histogram",
ignore_malformed = true,
}
}
};

protected override Func<PropertiesDescriptor<Project>, IPromise<IProperties>> FluentProperties => f => f
.Histogram(s => s
.Name(p => p.Name)
.IgnoreMalformed()
);


protected override IProperties InitializerProperties => new Properties
{
{
"name", new HistogramProperty
{
IgnoreMalformed = true,
}
}
};
}
}

0 comments on commit 34e2b59

Please sign in to comment.