Skip to content

Commit

Permalink
Add match_only_text field (#5801)
Browse files Browse the repository at this point in the history
  • Loading branch information
stevejgordon authored and github-actions[bot] committed Jul 6, 2021
1 parent a9d6835 commit 146ce08
Show file tree
Hide file tree
Showing 15 changed files with 142 additions and 5 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 @@ -157,6 +157,10 @@ public IProperty Generic(Func<GenericPropertyDescriptor<T>, IGenericProperty> se
public IProperty DenseVector(Func<DenseVectorPropertyDescriptor<T>, IDenseVectorProperty> selector) =>
selector?.Invoke(new DenseVectorPropertyDescriptor<T>());

/// <inheritdoc />
public IProperty MatchOnlyText(Func<MatchOnlyTextPropertyDescriptor<T>, IMatchOnlyTextProperty> selector) =>
selector?.Invoke(new MatchOnlyTextPropertyDescriptor<T>());

#pragma warning disable CS3001 // Argument type is not CLS-compliant
public IProperty Scalar(Expression<Func<T, int>> field, Func<NumberPropertyDescriptor<T>, INumberProperty> selector = null) =>
selector.InvokeOrDefault(new NumberPropertyDescriptor<T>().Name(field).Type(NumberType.Integer));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information

namespace Nest
{
public class MatchOnlyTextAttribute : ElasticsearchCorePropertyAttributeBase, IMatchOnlyTextProperty {
public MatchOnlyTextAttribute() : base(FieldType.MatchOnlyText) { }
protected MatchOnlyTextAttribute(FieldType fieldType) : base(fieldType) { }
private IMatchOnlyTextProperty Self => this;
}
}
36 changes: 36 additions & 0 deletions src/Nest/Mapping/Types/Core/MatchOnlyText/MatchOnlyTextProperty.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information

using System.Diagnostics;
using Elasticsearch.Net.Utf8Json;

namespace Nest
{
/// <summary>
/// A variant of text that trades scoring and efficiency of positional queries for space efficiency.
/// This field effectively stores data the same way as a text field that only indexes documents
/// (index_options: docs) and disables norms (norms: false).
/// <para />
/// MatchOnlyText fields are not used for sorting and seldom used for aggregations.
/// </summary>
[InterfaceDataContract]
public interface IMatchOnlyTextProperty : ICoreProperty
{
}

/// <inheritdoc cref="IMatchOnlyTextProperty"/>
[DebuggerDisplay("{DebugDisplay}")]
public class MatchOnlyTextProperty : CorePropertyBase, IMatchOnlyTextProperty
{
public MatchOnlyTextProperty() : base(FieldType.MatchOnlyText) { }
}

/// <inheritdoc cref="IMatchOnlyTextProperty"/>
public class MatchOnlyTextPropertyDescriptor<T>
: CorePropertyDescriptorBase<MatchOnlyTextPropertyDescriptor<T>, IMatchOnlyTextProperty, T>, IMatchOnlyTextProperty
where T : class
{
public MatchOnlyTextPropertyDescriptor() : base(FieldType.MatchOnlyText) { }
}
}
8 changes: 7 additions & 1 deletion src/Nest/Mapping/Types/FieldType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,12 @@ public enum FieldType
/// A dense_vector field stores dense vectors of float values.
/// </summary>
[EnumMember(Value = "dense_vector")]
DenseVector
DenseVector,

/// <summary>
/// A variant of text that trades scoring and efficiency of positional queries for space efficiency.
/// </summary>
[EnumMember(Value = "match_only_text")]
MatchOnlyText,
}
}
6 changes: 6 additions & 0 deletions src/Nest/Mapping/Types/Properties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ TReturnType Nested<TChild>(Func<NestedPropertyDescriptor<T, TChild>, INestedProp

/// <inheritdoc cref="IDenseVectorProperty" />
TReturnType DenseVector(Func<DenseVectorPropertyDescriptor<T>, IDenseVectorProperty> selector);

/// <inheritdoc cref="IMatchOnlyTextProperty" />
TReturnType MatchOnlyText(Func<MatchOnlyTextPropertyDescriptor<T>, IMatchOnlyTextProperty> selector);
}

public partial class PropertiesDescriptor<T> where T : class
Expand Down Expand Up @@ -229,6 +232,9 @@ public PropertiesDescriptor<T> ConstantKeyword(Func<ConstantKeywordPropertyDescr
/// <inheritdoc cref="ILongRangeProperty" />
public PropertiesDescriptor<T> LongRange(Func<LongRangePropertyDescriptor<T>, ILongRangeProperty> selector) => SetProperty(selector);

/// <inheritdoc cref="IMatchOnlyTextProperty" />
public PropertiesDescriptor<T> MatchOnlyText(Func<MatchOnlyTextPropertyDescriptor<T>, IMatchOnlyTextProperty> selector) => SetProperty(selector);

/// <inheritdoc cref="IMurmur3HashProperty" />
public PropertiesDescriptor<T> Murmur3Hash(Func<Murmur3HashPropertyDescriptor<T>, IMurmur3HashProperty> selector) => SetProperty(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 @@ -97,6 +97,7 @@ public IProperty Deserialize(ref JsonReader reader, IJsonFormatterResolver forma
case FieldType.Wildcard: return Deserialize<WildcardProperty>(ref segmentReader, formatterResolver);
case FieldType.Version: return Deserialize<VersionProperty>(ref segmentReader, formatterResolver);
case FieldType.DenseVector: return Deserialize<DenseVectorProperty>(ref segmentReader, formatterResolver);
case FieldType.MatchOnlyText: return Deserialize<MatchOnlyTextProperty>(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 @@ -223,6 +224,9 @@ public void Serialize(ref JsonWriter writer, IProperty value, IJsonFormatterReso
case IDenseVectorProperty denseVectorProperty:
Serialize(ref writer, denseVectorProperty, formatterResolver);
break;
case IMatchOnlyTextProperty matchOnlyTextProperty:
Serialize(ref writer, matchOnlyTextProperty, formatterResolver);
break;
default:
var formatter = formatterResolver.GetFormatter<object>();
formatter.Serialize(ref writer, value, formatterResolver);
Expand Down
4 changes: 4 additions & 0 deletions src/Nest/Mapping/Visitor/IMappingVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ public interface IMappingVisitor
void Visit(IVersionProperty property);

void Visit(IDenseVectorProperty property);

void Visit(IMatchOnlyTextProperty property);
}

public class NoopMappingVisitor : IMappingVisitor
Expand Down Expand Up @@ -148,5 +150,7 @@ public virtual void Visit(IConstantKeywordProperty property) { }
public virtual void Visit(IVersionProperty property) { }

public virtual void Visit(IDenseVectorProperty property) { }

public virtual void Visit(IMatchOnlyTextProperty 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 @@ -80,6 +80,8 @@ public interface IPropertyVisitor

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

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

IProperty Visit(PropertyInfo propertyInfo, ElasticsearchPropertyAttributeBase attribute);

bool SkipProperty(PropertyInfo propertyInfo, ElasticsearchPropertyAttributeBase attribute);
Expand Down
6 changes: 6 additions & 0 deletions src/Nest/Mapping/Visitor/MappingWalker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,12 @@ public void Accept(IProperties properties)
_visitor.Visit(t);
});
break;
case FieldType.MatchOnlyText:
Visit<IMatchOnlyTextProperty>(field, t =>
{
_visitor.Visit(t);
});
break;
case FieldType.None:
continue;
}
Expand Down
9 changes: 7 additions & 2 deletions src/Nest/Mapping/Visitor/NoopPropertyVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ public virtual void Visit(IVersionProperty type, PropertyInfo propertyInfo, Elas

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

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

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

public virtual void Visit(IProperty type, PropertyInfo propertyInfo, ElasticsearchPropertyAttributeBase attribute)
Expand Down Expand Up @@ -185,8 +187,11 @@ public virtual void Visit(IProperty type, PropertyInfo propertyInfo, Elasticsear
case IVersionProperty version:
Visit(version, propertyInfo, attribute);
break;
case IDenseVectorProperty version:
Visit(version, propertyInfo, attribute);
case IDenseVectorProperty denseVector:
Visit(denseVector, propertyInfo, attribute);
break;
case IMatchOnlyTextProperty matchOnlyText:
Visit(matchOnlyText, propertyInfo, attribute);
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public class FieldTypes : IsADictionaryBase<string, FieldCapabilities>
public FieldCapabilities Keyword => BackingDictionary.TryGetValue("keyword", out var f) ? f : null;
public FieldCapabilities Long => BackingDictionary.TryGetValue("long", out var f) ? f : null;
public FieldCapabilities LongRange => BackingDictionary.TryGetValue("long_range", out var f) ? f : null;
public FieldCapabilities MatchOnlyText => BackingDictionary.TryGetValue("match_only_text", out var f) ? f : null;
public FieldCapabilities Murmur3 => BackingDictionary.TryGetValue("murmur3", out var f) ? f : null;
public FieldCapabilities Parent => BackingDictionary.TryGetValue("_parent", out var f) ? f : null;
public FieldCapabilities ParentJoin => BackingDictionary.TryGetValue("_parent_join", out var f) ? f : null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@ internal class TestVisitor : IMappingVisitor

public void Visit(IDenseVectorProperty property) => Increment("dense_vector");

public void Visit(IMatchOnlyTextProperty property) => Increment("match_only_text");

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
Expand Up @@ -12,9 +12,9 @@
namespace Tests.Mapping.Types.Core.DenseVector
{
[SkipVersion("<7.6.0", "Dense Vector property GA in 7.6.0")]
public class DenseVectorTests : PropertyTestsBase
public class DenseVectorPropertyTests : PropertyTestsBase
{
public DenseVectorTests(WritableCluster cluster, EndpointUsage usage) : base(cluster, usage) { }
public DenseVectorPropertyTests(WritableCluster cluster, EndpointUsage usage) : base(cluster, usage) { }

protected override object ExpectJson => new { properties = new { name = new { type = "dense_vector", dims = 2 } } };

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information

using Elastic.Elasticsearch.Xunit.XunitPlumbing;
using Nest;

namespace Tests.Mapping.Types.Core.MatchOnlyText
{
public class MatchOnlyTextTest
{
[MatchOnlyText]
public string MatchOnlyText { get; set; }
}

[SkipVersion("<7.14.0", "Match only text property added in 7.14.0")]
public class MatchOnlyTextAttributeTests : AttributeTestsBase<MatchOnlyTextTest>
{
protected override object ExpectJson => new { properties = new { matchOnlyText = new { type = "match_only_text" } } };
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information

using System;
using Elastic.Elasticsearch.Xunit.XunitPlumbing;
using Nest;
using Tests.Core.ManagedElasticsearch.Clusters;
using Tests.Domain;
using Tests.Framework.EndpointTests.TestState;

namespace Tests.Mapping.Types.Core.MatchOnlyText
{
[SkipVersion("<7.14.0", "Match only text property added in 7.14.0")]
public class MatchOnlyTextPropertyTests : PropertyTestsBase
{
public MatchOnlyTextPropertyTests(WritableCluster cluster, EndpointUsage usage) : base(cluster, usage) { }

protected override object ExpectJson => new { properties = new { name = new { type = "match_only_text" } } };

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

protected override IProperties InitializerProperties => new Properties { { "name", new MatchOnlyTextProperty() } };
}
}

0 comments on commit 146ce08

Please sign in to comment.