diff --git a/docs/asciidoc/query-dsl/specialized/percolate/percolate-query-usage.asciidoc b/docs/asciidoc/query-dsl/specialized/percolate/percolate-query-usage.asciidoc new file mode 100644 index 00000000000..488136620c3 --- /dev/null +++ b/docs/asciidoc/query-dsl/specialized/percolate/percolate-query-usage.asciidoc @@ -0,0 +1,246 @@ +:ref_current: https://www.elastic.co/guide/en/elasticsearch/reference/master + +:github: https://github.com/elastic/elasticsearch-net + +:nuget: https://www.nuget.org/packages + +[[percolate-query-usage]] +== Percolate Query Usage + +The percolate query can be used to match queries stored in an index. +The percolate query itself contains the document that will be used as query to match with the stored queries. + +IMPORTANT: In order for the percolate query to work, the index in which your stored queries reside must contain +a mapping for documents that you wish to percolate, so that they are parsed correctly at query time. + +See the Elasticsearch documentation on {ref_current}/query-dsl-percolate-query.html[percolate query] for more details. + +In this example, we have a document stored with a `query` field that is mapped as a `percolator` type. This field +contains a `match` query. + +[source,csharp] +---- +foreach (var index in values.Values) +{ + this.Client.CreateIndex(index, c => c + .Mappings(m => m + .Map(mm => mm.AutoMap() + .Properties(Seeder.ProjectProperties) + ) + .Map(mm => mm.AutoMap() + .Properties(Seeder.PercolatedQueryProperties) + ) + ) + ); + + this.Client.Index(new PercolatedQuery + { + Id = PercolatorId, + Query = new QueryContainer(new MatchQuery + { + Field = Infer.Field(f => f.LeadDeveloper.FirstName), + Query = "Martijn" + }) + }, d => d.Index(index)); + + this.Client.Refresh(index); +} +---- + +=== Fluent DSL Example + +[source,csharp] +---- +f => +f.Query(QueryFluent).Index(CallIsolatedValue).AllTypes() +---- + +=== Object Initializer Syntax Example + +[source,csharp] +---- +new SearchRequest(CallIsolatedValue, Types.All) +{ + Query = this.QueryInitializer +} +---- + +[source,javascript] +.Example json output +---- +{ + "percolator": { + "document_type": "project", + "document": { + "name": "Koch, Collier and Mohr", + "state": "BellyUp", + "startedOn": "2015-01-01T00:00:00", + "lastActivity": "0001-01-01T00:00:00", + "leadDeveloper": { + "gender": "Male", + "id": 0, + "firstName": "Martijn", + "lastName": "Laarman" + }, + "location": { + "lat": 42.1523, + "lon": -80.321 + } + } + } +} +---- + +=== Fluent DSL Example + +[source,csharp] +---- +q +.Percolate(p => p + .DocumentType(typeof(Project)) + .Document(Project.Instance) +) +---- + +=== Object Initializer Syntax Example + +[source,csharp] +---- +new PercolateQuery +{ + DocumentType = typeof(Project), + Document = Project.Instance, +} +---- + +=== Handling Responses + +[source,csharp] +---- +response.Total.Should().BeGreaterThan(0); +response.Hits.Should().NotBeNull(); +response.Hits.Count().Should().BeGreaterThan(0); +var match = response.Documents.First(); +match.Id.Should().Be(PercolatorId); +((IQueryContainer)match.Query).Match.Should().NotBeNull(); +---- + +[[percolate-an-existing-document]] +[float] +== Percolate an existing document + +Instead of specifying a the source of the document being percolated, the source can also be +retrieved from an already stored document. The percolate query will then internally execute a get request to fetch that document. + +The required fields to percolate an existing document are: + +* `index` in which the document resides + +* `type` of the document + +* `id` of the document + +* `document_type` type / mapping of the document + +See the Elasticsearch documentation on {ref_current}/query-dsl-percolate-query.html[percolate query] for more details. + +[source,csharp] +---- +foreach (var index in values.Values) +{ + this.Client.CreateIndex(index, c => c + .Mappings(m => m + .Map(mm => mm.AutoMap() + .Properties(Seeder.ProjectProperties) + ) + .Map(mm => mm.AutoMap() + .Properties(Seeder.PercolatedQueryProperties) + ) + ) + ); + + this.Client.Index(new PercolatedQuery + { + Id = PercolatorId, + Query = new QueryContainer(new MatchQuery + { + Field = Infer.Field(f => f.LeadDeveloper.FirstName), + Query = "Martijn" + }) + }, d => d.Index(index)); + + this.Client.Index(Project.Instance); + this.Client.Refresh(Nest.Indices.Index(index).And()); +} +---- + +=== Fluent DSL Example + +[source,csharp] +---- +f => +f.Query(QueryFluent).Index(CallIsolatedValue).AllTypes() +---- + +=== Object Initializer Syntax Example + +[source,csharp] +---- +new SearchRequest(CallIsolatedValue, Types.All) +{ + Query = this.QueryInitializer +} +---- + +[source,javascript] +.Example json output +---- +{ + "percolator": { + "type": "project", + "index": "project", + "id": "Durgan LLC", + "document_type": "project" + } +} +---- + +=== Fluent DSL Example + +[source,csharp] +---- +q +.Percolate(p => p + .Type() + .Index() + .Id(Project.Instance.Name) + .DocumentType() <1> +) +---- +<1> specify the `type`, `index`, `id` and `document_type` of the document to fetch, to percolate. + +=== Object Initializer Syntax Example + +[source,csharp] +---- +new PercolateQuery +{ + Type = typeof(Project), + Index = IndexName.From(), + Id = Project.Instance.Name, + DocumentType = typeof(Project) +} +---- + +=== Handling Responses + +[source,csharp] +---- +response.Total.Should().BeGreaterThan(0); +response.Hits.Should().NotBeNull(); +response.Hits.Count().Should().BeGreaterThan(0); +var match = response.Documents.First(); +match.Id.Should().Be(PercolatorId); +((IQueryContainer)match.Query).Match.Should().NotBeNull(); +---- + diff --git a/paket.lock b/paket.lock index 65764c6d9ab..2e60f137114 100644 --- a/paket.lock +++ b/paket.lock @@ -1,7 +1,11 @@ NUGET - remote: https://www.nuget.org/api/v2 + remote: http://api.nuget.org/v3/index.json specs: AsciiDocNet (1.0.0-alpha3) + SemanticVersioning (0.6.17) + ShellProgressBar (3.0) + remote: https://www.nuget.org/api/v2 + specs: Bogus (3.0.5-beta-2) Newtonsoft.Json (>= 8.0.2) - framework: >= net40, dnx451, dnxcore50 System.ComponentModel (>= 4.0.1-beta-23516) - framework: dnxcore50 @@ -348,10 +352,6 @@ NUGET System.Threading.Tasks (>= 4.0) - framework: dnxcore50 xunit.abstractions (>= 2.0) - framework: dnxcore50 xunit.extensibility.core (2.1) - framework: >= net45, dnx451, dnxcore50, monoandroid, monotouch, xamarinios, winv4.5, wpv8.0, wpav8.1 - remote: http://api.nuget.org/v3/index.json - specs: - SemanticVersioning (0.6.17) - ShellProgressBar (3.0) GROUP build NUGET diff --git a/src/CodeGeneration/Nest.Litterateur/AsciiDoc/GeneratedAsciidocVisitor.cs b/src/CodeGeneration/Nest.Litterateur/AsciiDoc/GeneratedAsciidocVisitor.cs index d806b913773..7a80f137f22 100644 --- a/src/CodeGeneration/Nest.Litterateur/AsciiDoc/GeneratedAsciidocVisitor.cs +++ b/src/CodeGeneration/Nest.Litterateur/AsciiDoc/GeneratedAsciidocVisitor.cs @@ -54,17 +54,17 @@ public override void Visit(Document document) _newDocument.Attributes.Add(attributeEntry); } - if (!document.Attributes.Any(a => a.Name == "ref_current")) + if (document.Attributes.All(a => a.Name != "ref_current")) { - _newDocument.Attributes.Add(new AttributeEntry("ref_current", "https://www.elastic.co/guide/en/elasticsearch/reference/current")); + _newDocument.Attributes.Add(new AttributeEntry("ref_current", "https://www.elastic.co/guide/en/elasticsearch/reference/master")); } - if (!document.Attributes.Any(a => a.Name == "github")) + if (document.Attributes.All(a => a.Name != "github")) { _newDocument.Attributes.Add(new AttributeEntry("github", "https://github.com/elastic/elasticsearch-net")); } - if (!document.Attributes.Any(a => a.Name == "nuget")) + if (document.Attributes.All(a => a.Name != "nuget")) { _newDocument.Attributes.Add(new AttributeEntry("nuget", "https://www.nuget.org/packages")); } diff --git a/src/Elasticsearch.Net/Connection/HttpConnection-CoreFx.cs b/src/Elasticsearch.Net/Connection/HttpConnection-CoreFx.cs index f2c95333b1f..0e65ea68f49 100644 --- a/src/Elasticsearch.Net/Connection/HttpConnection-CoreFx.cs +++ b/src/Elasticsearch.Net/Connection/HttpConnection-CoreFx.cs @@ -30,10 +30,6 @@ public class HttpConnection : IConnection private readonly object _lock = new object(); private readonly ConcurrentDictionary _clients = new ConcurrentDictionary(); - private string DefaultContentType => "application/json"; - - public HttpConnection() { } - private HttpClient GetClient(RequestData requestData) { var hashCode = requestData.GetHashCode(); @@ -127,7 +123,7 @@ private static HttpRequestMessage CreateHttpRequestMessage(RequestData requestDa requestMessage.Headers.TryAddWithoutValidation(key, requestData.Headers.GetValues(key)); } - requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(requestData.ContentType)); + requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(requestData.Accept)); if (!requestData.RunAs.IsNullOrEmpty()) requestMessage.Headers.Add("es-shield-runas-user", requestData.RunAs); diff --git a/src/Elasticsearch.Net/Domain/IPropertyMapping.cs b/src/Elasticsearch.Net/Domain/IPropertyMapping.cs index 37bfff74395..fabf101fdbc 100644 --- a/src/Elasticsearch.Net/Domain/IPropertyMapping.cs +++ b/src/Elasticsearch.Net/Domain/IPropertyMapping.cs @@ -33,6 +33,5 @@ public class PropertyMapping : IPropertyMapping ///
- When Indexing this type do not serialize whatever this value hold
/// public bool Ignore { get; set; } - } } diff --git a/src/Nest/CommonAbstractions/Infer/Id/IdExtensions.cs b/src/Nest/CommonAbstractions/Infer/Id/IdExtensions.cs new file mode 100644 index 00000000000..ab005605cdc --- /dev/null +++ b/src/Nest/CommonAbstractions/Infer/Id/IdExtensions.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Nest +{ + internal static class IdExtensions + { + internal static bool IsConditionless(this Id id) + { + return id == null || (id.Value == null && id.Document == null); + } + } +} diff --git a/src/Nest/CommonAbstractions/Infer/Indices/Indices.cs b/src/Nest/CommonAbstractions/Infer/Indices/Indices.cs index 8c67ee224de..772a4bcced3 100644 --- a/src/Nest/CommonAbstractions/Infer/Indices/Indices.cs +++ b/src/Nest/CommonAbstractions/Infer/Indices/Indices.cs @@ -86,4 +86,4 @@ public override int GetHashCode() ); } } -} \ No newline at end of file +} diff --git a/src/Nest/CommonAbstractions/Infer/PropertyName/PropertyNameExtensions.cs b/src/Nest/CommonAbstractions/Infer/PropertyName/PropertyNameExtensions.cs index c8159a6f95c..7965692fe70 100644 --- a/src/Nest/CommonAbstractions/Infer/PropertyName/PropertyNameExtensions.cs +++ b/src/Nest/CommonAbstractions/Infer/PropertyName/PropertyNameExtensions.cs @@ -1,6 +1,6 @@ namespace Nest { - public static class PropertyNameExtensions + internal static class PropertyNameExtensions { internal static bool IsConditionless(this PropertyName property) { diff --git a/src/Nest/CommonAbstractions/Infer/TypeName/TypeNameExtensions.cs b/src/Nest/CommonAbstractions/Infer/TypeName/TypeNameExtensions.cs index 4743aa5c4a9..b61707ba4e8 100644 --- a/src/Nest/CommonAbstractions/Infer/TypeName/TypeNameExtensions.cs +++ b/src/Nest/CommonAbstractions/Infer/TypeName/TypeNameExtensions.cs @@ -1,11 +1,10 @@ namespace Nest { - public static class TypeNameExtensions + internal static class TypeNameExtensions { - - public static bool IsConditionless(this TypeName marker) + internal static bool IsConditionless(this TypeName marker) { return marker == null || marker.Name.IsNullOrEmpty() && marker.Type == null; } } -} \ No newline at end of file +} diff --git a/src/Nest/Mapping/AttributeBased/ElasticsearchCorePropertyAttributeBase.cs b/src/Nest/Mapping/AttributeBased/ElasticsearchCorePropertyAttributeBase.cs new file mode 100644 index 00000000000..617cb9738f9 --- /dev/null +++ b/src/Nest/Mapping/AttributeBased/ElasticsearchCorePropertyAttributeBase.cs @@ -0,0 +1,34 @@ +using System; +using System.Reflection; +using Newtonsoft.Json; + +namespace Nest +{ + [AttributeUsage(AttributeTargets.Property)] + [JsonObject(MemberSerialization = MemberSerialization.OptIn)] + public abstract class ElasticsearchCorePropertyAttributeBase : ElasticsearchPropertyAttributeBase, ICoreProperty + { + private ICoreProperty Self => this; + + bool? ICoreProperty.Store { get; set; } + IProperties ICoreProperty.Fields { get; set; } + SimilarityOption? ICoreProperty.Similarity { get; set; } + Fields ICoreProperty.CopyTo { get; set; } + + public SimilarityOption Similarity { get { return Self.Similarity.GetValueOrDefault(); } set { Self.Similarity = value; } } + public bool Store { get { return Self.Store.GetValueOrDefault(); } set { Self.Store = value; } } + + protected ElasticsearchCorePropertyAttributeBase(string typeName) : base(typeName) + { + } + + protected ElasticsearchCorePropertyAttributeBase(Type type) : base(type) + { + } + + public new static ElasticsearchCorePropertyAttributeBase From(MemberInfo memberInfo) + { + return memberInfo.GetCustomAttribute(true); + } + } +} diff --git a/src/Nest/Mapping/AttributeBased/ElasticsearchDocValuesPropertyAttributeBase.cs b/src/Nest/Mapping/AttributeBased/ElasticsearchDocValuesPropertyAttributeBase.cs new file mode 100644 index 00000000000..ba75f7edfb5 --- /dev/null +++ b/src/Nest/Mapping/AttributeBased/ElasticsearchDocValuesPropertyAttributeBase.cs @@ -0,0 +1,30 @@ +using System; +using System.Reflection; +using Newtonsoft.Json; + +namespace Nest +{ + [AttributeUsage(AttributeTargets.Property)] + [JsonObject(MemberSerialization = MemberSerialization.OptIn)] + public abstract class ElasticsearchDocValuesPropertyAttributeBase : ElasticsearchCorePropertyAttributeBase, IDocValuesProperty + { + private IDocValuesProperty Self => this; + + bool? IDocValuesProperty.DocValues { get; set; } + + public bool DocValues { get { return Self.DocValues.GetValueOrDefault(true); } set { Self.DocValues = value; } } + + protected ElasticsearchDocValuesPropertyAttributeBase(string typeName) : base(typeName) + { + } + + protected ElasticsearchDocValuesPropertyAttributeBase(Type type) : base(type) + { + } + + public new static ElasticsearchDocValuesPropertyAttributeBase From(MemberInfo memberInfo) + { + return memberInfo.GetCustomAttribute(true); + } + } +} diff --git a/src/Nest/Mapping/AttributeBased/ElasticsearchPropertyAttributeBase.cs b/src/Nest/Mapping/AttributeBased/ElasticsearchPropertyAttributeBase.cs index 8acd9a6bc61..83e07d1ed50 100644 --- a/src/Nest/Mapping/AttributeBased/ElasticsearchPropertyAttributeBase.cs +++ b/src/Nest/Mapping/AttributeBased/ElasticsearchPropertyAttributeBase.cs @@ -15,18 +15,10 @@ public abstract class ElasticsearchPropertyAttributeBase : Attribute, IProperty, PropertyName IProperty.Name { get; set; } TypeName IProperty.Type { get; set; } string IProperty.IndexName { get; set; } - bool? IProperty.Store { get; set; } - bool? IProperty.DocValues { get; set; } - IProperties IProperty.Fields { get; set; } - SimilarityOption? IProperty.Similarity { get; set; } - Fields IProperty.CopyTo { get; set; } public string Name { get; set; } public bool Ignore { get; set; } - public bool DocValues { get { return Self.DocValues.GetValueOrDefault(); } set { Self.DocValues = value; } } public string IndexName { get { return Self.IndexName; } set { Self.IndexName = value; } } - public SimilarityOption Similarity { get { return Self.Similarity.GetValueOrDefault(); } set { Self.Similarity = value; } } - public bool Store { get { return Self.Store.GetValueOrDefault(); } set { Self.Store = value; } } protected ElasticsearchPropertyAttributeBase(string typeName) { @@ -43,4 +35,4 @@ public static ElasticsearchPropertyAttributeBase From(MemberInfo memberInfo) return memberInfo.GetCustomAttribute(true); } } -} \ No newline at end of file +} diff --git a/src/Nest/Mapping/AttributeBased/ElasticsearchTypeAttribute.cs b/src/Nest/Mapping/AttributeBased/ElasticsearchTypeAttribute.cs index 68fa0c15eb7..1ac47eec10b 100644 --- a/src/Nest/Mapping/AttributeBased/ElasticsearchTypeAttribute.cs +++ b/src/Nest/Mapping/AttributeBased/ElasticsearchTypeAttribute.cs @@ -5,7 +5,7 @@ namespace Nest { - [AttributeUsage(System.AttributeTargets.Class, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] public class ElasticsearchTypeAttribute : Attribute { private static readonly ConcurrentDictionary CachedTypeLookups = @@ -27,4 +27,4 @@ public static ElasticsearchTypeAttribute From(Type type) return attr; } } -} \ No newline at end of file +} diff --git a/src/Nest/Mapping/DynamicTemplate/SingleMapping.cs b/src/Nest/Mapping/DynamicTemplate/SingleMapping.cs index 66a4fb2f88e..9ffa8bd14bb 100644 --- a/src/Nest/Mapping/DynamicTemplate/SingleMapping.cs +++ b/src/Nest/Mapping/DynamicTemplate/SingleMapping.cs @@ -53,5 +53,8 @@ public IProperty Murmur3Hash(Func, IMurmur3Hash public IProperty TokenCount(Func, ITokenCountProperty> selector) => selector?.Invoke(new TokenCountPropertyDescriptor()); + + public IProperty Percolator(Func, IPercolatorProperty> selector) => + selector?.Invoke(new PercolatorPropertyDescriptor()); } } diff --git a/src/Nest/Mapping/Types/Complex/Object/ObjectAttribute.cs b/src/Nest/Mapping/Types/Complex/Object/ObjectAttribute.cs index 904e2211b1f..ee050c87675 100644 --- a/src/Nest/Mapping/Types/Complex/Object/ObjectAttribute.cs +++ b/src/Nest/Mapping/Types/Complex/Object/ObjectAttribute.cs @@ -2,7 +2,7 @@ namespace Nest { - public class ObjectAttribute : ElasticsearchPropertyAttributeBase, IObjectProperty + public class ObjectAttribute : ElasticsearchCorePropertyAttributeBase, IObjectProperty { IObjectProperty Self => this; @@ -20,5 +20,5 @@ public class ObjectAttribute : ElasticsearchPropertyAttributeBase, IObjectProper public ObjectAttribute() : base("object") { } protected ObjectAttribute(string typeName) : base(typeName) { } protected ObjectAttribute(Type type) : base(type) { } - } + } } diff --git a/src/Nest/Mapping/Types/Complex/Object/ObjectProperty.cs b/src/Nest/Mapping/Types/Complex/Object/ObjectProperty.cs index 8fff5793a47..3951d8120bc 100644 --- a/src/Nest/Mapping/Types/Complex/Object/ObjectProperty.cs +++ b/src/Nest/Mapping/Types/Complex/Object/ObjectProperty.cs @@ -5,7 +5,7 @@ namespace Nest { [JsonObject(MemberSerialization.OptIn)] - public interface IObjectProperty : IProperty + public interface IObjectProperty : ICoreProperty { [JsonProperty("dynamic")] DynamicMapping? Dynamic { get; set; } @@ -23,7 +23,7 @@ public interface IObjectProperty : IProperty IProperties Properties { get; set; } } - public class ObjectProperty : PropertyBase, IObjectProperty + public class ObjectProperty : CorePropertyBase, IObjectProperty { public ObjectProperty() : base("object") { } @@ -44,7 +44,7 @@ public class ObjectTypeDescriptor } public abstract class ObjectPropertyDescriptorBase - : PropertyDescriptorBase, IObjectProperty + : CorePropertyDescriptorBase, IObjectProperty where TDescriptor : ObjectPropertyDescriptorBase, TInterface where TInterface : class, IObjectProperty where TParent : class @@ -58,7 +58,7 @@ public abstract class ObjectPropertyDescriptorBase AutoMap(null, maxRecursion); } -} \ No newline at end of file +} diff --git a/src/Nest/Mapping/Types/Core/Binary/BinaryAttribute.cs b/src/Nest/Mapping/Types/Core/Binary/BinaryAttribute.cs index e435ff6d958..a9d984790ba 100644 --- a/src/Nest/Mapping/Types/Core/Binary/BinaryAttribute.cs +++ b/src/Nest/Mapping/Types/Core/Binary/BinaryAttribute.cs @@ -3,8 +3,8 @@ namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - public class BinaryAttribute : ElasticsearchPropertyAttributeBase, IBinaryProperty + public class BinaryAttribute : ElasticsearchDocValuesPropertyAttributeBase, IBinaryProperty { public BinaryAttribute() : base("binary") { } - } + } } diff --git a/src/Nest/Mapping/Types/Core/Binary/BinaryProperty.cs b/src/Nest/Mapping/Types/Core/Binary/BinaryProperty.cs index 344033c035d..f9f3f3c7fd0 100644 --- a/src/Nest/Mapping/Types/Core/Binary/BinaryProperty.cs +++ b/src/Nest/Mapping/Types/Core/Binary/BinaryProperty.cs @@ -3,19 +3,19 @@ namespace Nest { [JsonObject(MemberSerialization.OptIn)] - public interface IBinaryProperty : IProperty + public interface IBinaryProperty : IDocValuesProperty { } - public class BinaryProperty : PropertyBase, IBinaryProperty + public class BinaryProperty : DocValuesPropertyBase, IBinaryProperty { public BinaryProperty() : base("binary") { } } - public class BinaryPropertyDescriptor - : PropertyDescriptorBase, IBinaryProperty, T>, IBinaryProperty + public class BinaryPropertyDescriptor + : DocValuesPropertyDescriptorBase, IBinaryProperty, T>, IBinaryProperty where T : class { public BinaryPropertyDescriptor() : base("binary") { } } -} \ No newline at end of file +} diff --git a/src/Nest/Mapping/Types/Core/Boolean/BooleanAttribute.cs b/src/Nest/Mapping/Types/Core/Boolean/BooleanAttribute.cs index 820f3da0eb4..9523c6b9ef0 100644 --- a/src/Nest/Mapping/Types/Core/Boolean/BooleanAttribute.cs +++ b/src/Nest/Mapping/Types/Core/Boolean/BooleanAttribute.cs @@ -1,6 +1,6 @@ namespace Nest { - public class BooleanAttribute : ElasticsearchPropertyAttributeBase, IBooleanProperty + public class BooleanAttribute : ElasticsearchDocValuesPropertyAttributeBase, IBooleanProperty { IBooleanProperty Self => this; diff --git a/src/Nest/Mapping/Types/Core/Boolean/BooleanProperty.cs b/src/Nest/Mapping/Types/Core/Boolean/BooleanProperty.cs index 872dd2a73e9..533c23f2930 100644 --- a/src/Nest/Mapping/Types/Core/Boolean/BooleanProperty.cs +++ b/src/Nest/Mapping/Types/Core/Boolean/BooleanProperty.cs @@ -3,9 +3,8 @@ namespace Nest { - [JsonObject(MemberSerialization.OptIn)] - public interface IBooleanProperty : IProperty + public interface IBooleanProperty : IDocValuesProperty { [JsonProperty("index")] bool? Index { get; set; } @@ -20,7 +19,7 @@ public interface IBooleanProperty : IProperty INumericFielddata Fielddata { get; set; } } - public class BooleanProperty : PropertyBase, IBooleanProperty + public class BooleanProperty : DocValuesPropertyBase, IBooleanProperty { public BooleanProperty() : base("boolean") { } @@ -31,7 +30,7 @@ public BooleanProperty() : base("boolean") { } } public class BooleanPropertyDescriptor - : PropertyDescriptorBase, IBooleanProperty, T>, IBooleanProperty + : DocValuesPropertyDescriptorBase, IBooleanProperty, T>, IBooleanProperty where T : class { double? IBooleanProperty.Boost { get; set; } diff --git a/src/Nest/Mapping/Types/Core/Date/DateAttribute.cs b/src/Nest/Mapping/Types/Core/Date/DateAttribute.cs index c374d426b3b..ae2213cc758 100644 --- a/src/Nest/Mapping/Types/Core/Date/DateAttribute.cs +++ b/src/Nest/Mapping/Types/Core/Date/DateAttribute.cs @@ -2,7 +2,7 @@ namespace Nest { - public class DateAttribute : ElasticsearchPropertyAttributeBase, IDateProperty + public class DateAttribute : ElasticsearchDocValuesPropertyAttributeBase, IDateProperty { IDateProperty Self => this; diff --git a/src/Nest/Mapping/Types/Core/Date/DateProperty.cs b/src/Nest/Mapping/Types/Core/Date/DateProperty.cs index 99eb01bae57..803659e173e 100644 --- a/src/Nest/Mapping/Types/Core/Date/DateProperty.cs +++ b/src/Nest/Mapping/Types/Core/Date/DateProperty.cs @@ -4,7 +4,7 @@ namespace Nest { [JsonObject(MemberSerialization.OptIn)] - public interface IDateProperty : IProperty + public interface IDateProperty : IDocValuesProperty { [JsonProperty("index")] bool? Index { get; set; } @@ -34,7 +34,7 @@ public interface IDateProperty : IProperty INumericFielddata Fielddata { get; set; } } - public class DateProperty : PropertyBase, IDateProperty + public class DateProperty : DocValuesPropertyBase, IDateProperty { public DateProperty() : base("date") { } @@ -50,7 +50,7 @@ public DateProperty() : base("date") { } } public class DatePropertyDescriptor - : PropertyDescriptorBase, IDateProperty, T>, IDateProperty + : DocValuesPropertyDescriptorBase, IDateProperty, T>, IDateProperty where T : class { bool? IDateProperty.Index { get; set; } diff --git a/src/Nest/Mapping/Types/Core/Keyword/KeywordAttribute.cs b/src/Nest/Mapping/Types/Core/Keyword/KeywordAttribute.cs index 1c0d266d996..85a367f91b5 100644 --- a/src/Nest/Mapping/Types/Core/Keyword/KeywordAttribute.cs +++ b/src/Nest/Mapping/Types/Core/Keyword/KeywordAttribute.cs @@ -6,7 +6,7 @@ namespace Nest { - public class KeywordAttribute : ElasticsearchPropertyAttributeBase, IKeywordProperty + public class KeywordAttribute : ElasticsearchDocValuesPropertyAttributeBase, IKeywordProperty { IKeywordProperty Self => this; diff --git a/src/Nest/Mapping/Types/Core/Keyword/KeywordProperty.cs b/src/Nest/Mapping/Types/Core/Keyword/KeywordProperty.cs index 26a9d6c760b..e45faf277a8 100644 --- a/src/Nest/Mapping/Types/Core/Keyword/KeywordProperty.cs +++ b/src/Nest/Mapping/Types/Core/Keyword/KeywordProperty.cs @@ -8,7 +8,7 @@ namespace Nest { [JsonObject(MemberSerialization.OptIn)] - public interface IKeywordProperty : IProperty + public interface IKeywordProperty : IDocValuesProperty { [JsonProperty("boost")] double? Boost { get; set; } @@ -38,7 +38,7 @@ public interface IKeywordProperty : IProperty string SearchAnalyzer { get; set; } } - public class KeywordProperty : PropertyBase, IKeywordProperty + public class KeywordProperty : DocValuesPropertyBase, IKeywordProperty { public KeywordProperty() : base("keyword") { } @@ -54,7 +54,7 @@ public KeywordProperty() : base("keyword") { } } public class KeywordPropertyDescriptor - : PropertyDescriptorBase, IKeywordProperty, T>, IKeywordProperty + : DocValuesPropertyDescriptorBase, IKeywordProperty, T>, IKeywordProperty where T : class { double? IKeywordProperty.Boost { get; set; } diff --git a/src/Nest/Mapping/Types/Core/Number/NumberAttribute.cs b/src/Nest/Mapping/Types/Core/Number/NumberAttribute.cs index c12e1813984..6a584b769ee 100644 --- a/src/Nest/Mapping/Types/Core/Number/NumberAttribute.cs +++ b/src/Nest/Mapping/Types/Core/Number/NumberAttribute.cs @@ -4,7 +4,7 @@ /// Maps a property as a number type. If no type is specified, /// the default type is float (single precision floating point). /// - public class NumberAttribute : ElasticsearchPropertyAttributeBase, INumberProperty + public class NumberAttribute : ElasticsearchDocValuesPropertyAttributeBase, INumberProperty { INumberProperty Self => this; diff --git a/src/Nest/Mapping/Types/Core/Number/NumberProperty.cs b/src/Nest/Mapping/Types/Core/Number/NumberProperty.cs index aaf4a9f61dd..9f981c622f1 100644 --- a/src/Nest/Mapping/Types/Core/Number/NumberProperty.cs +++ b/src/Nest/Mapping/Types/Core/Number/NumberProperty.cs @@ -4,7 +4,7 @@ namespace Nest { [JsonObject(MemberSerialization.OptIn)] - public interface INumberProperty : IProperty + public interface INumberProperty : IDocValuesProperty { [JsonProperty("index")] bool? Index { get; set; } @@ -31,7 +31,7 @@ public interface INumberProperty : IProperty INumericFielddata Fielddata { get; set; } } - public class NumberProperty : PropertyBase, INumberProperty + public class NumberProperty : DocValuesPropertyBase, INumberProperty { public NumberProperty() : base(NumberType.Float.GetStringValue()) { } public NumberProperty(NumberType type) : base(type.GetStringValue()) { } @@ -48,7 +48,7 @@ protected NumberProperty(string type) : base(type) { } } public abstract class NumberPropertyDescriptorBase - : PropertyDescriptorBase, INumberProperty + : DocValuesPropertyDescriptorBase, INumberProperty where TDescriptor : NumberPropertyDescriptorBase, TInterface where TInterface : class, INumberProperty where T : class diff --git a/src/Nest/Mapping/Types/Core/Percolator/PercolatorAttribute.cs b/src/Nest/Mapping/Types/Core/Percolator/PercolatorAttribute.cs new file mode 100644 index 00000000000..71a78a3b7cc --- /dev/null +++ b/src/Nest/Mapping/Types/Core/Percolator/PercolatorAttribute.cs @@ -0,0 +1,7 @@ +namespace Nest +{ + public class PercolatorAttribute : ElasticsearchPropertyAttributeBase, IPercolatorProperty + { + public PercolatorAttribute() : base("percolator") { } + } +} diff --git a/src/Nest/Mapping/Types/Core/Percolator/PercolatorProperty.cs b/src/Nest/Mapping/Types/Core/Percolator/PercolatorProperty.cs new file mode 100644 index 00000000000..0b5daab27c7 --- /dev/null +++ b/src/Nest/Mapping/Types/Core/Percolator/PercolatorProperty.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; + +namespace Nest +{ + [JsonObject(MemberSerialization.OptIn)] + public interface IPercolatorProperty : IProperty + { + } + + public class PercolatorProperty : PropertyBase, IPercolatorProperty + { + public PercolatorProperty() : base("percolator") { } + } + + public class PercolatorPropertyDescriptor + : PropertyDescriptorBase, IPercolatorProperty, T>, IPercolatorProperty + where T : class + { + public PercolatorPropertyDescriptor() : base("percolator") { } + } +} diff --git a/src/Nest/Mapping/Types/Core/String/StringAttribute.cs b/src/Nest/Mapping/Types/Core/String/StringAttribute.cs index d1fabedcfcf..ecd921b23bf 100644 --- a/src/Nest/Mapping/Types/Core/String/StringAttribute.cs +++ b/src/Nest/Mapping/Types/Core/String/StringAttribute.cs @@ -1,6 +1,6 @@ namespace Nest { - public class StringAttribute : ElasticsearchPropertyAttributeBase, IStringProperty + public class StringAttribute : ElasticsearchDocValuesPropertyAttributeBase, IStringProperty { IStringProperty Self => this; diff --git a/src/Nest/Mapping/Types/Core/String/StringProperty.cs b/src/Nest/Mapping/Types/Core/String/StringProperty.cs index db7cf7a322d..fe5b1ebd06a 100644 --- a/src/Nest/Mapping/Types/Core/String/StringProperty.cs +++ b/src/Nest/Mapping/Types/Core/String/StringProperty.cs @@ -4,7 +4,7 @@ namespace Nest { [JsonObject(MemberSerialization.OptIn)] - public interface IStringProperty : IProperty + public interface IStringProperty : IDocValuesProperty { [JsonProperty("index")] FieldIndexOption? Index { get; set; } @@ -43,7 +43,7 @@ public interface IStringProperty : IProperty IStringFielddata Fielddata { get; set; } } - public class StringProperty : PropertyBase, IStringProperty + public class StringProperty : DocValuesPropertyBase, IStringProperty { public StringProperty() : base("string") { } @@ -62,7 +62,7 @@ public StringProperty() : base("string") { } } public class StringPropertyDescriptor - : PropertyDescriptorBase, IStringProperty, T>, IStringProperty + : DocValuesPropertyDescriptorBase, IStringProperty, T>, IStringProperty where T : class { FieldIndexOption? IStringProperty.Index { get; set; } diff --git a/src/Nest/Mapping/Types/Core/Text/TextAttribute.cs b/src/Nest/Mapping/Types/Core/Text/TextAttribute.cs index efed1d18b59..42faf95e439 100644 --- a/src/Nest/Mapping/Types/Core/Text/TextAttribute.cs +++ b/src/Nest/Mapping/Types/Core/Text/TextAttribute.cs @@ -6,7 +6,7 @@ namespace Nest { - public class TextAttribute : ElasticsearchPropertyAttributeBase, ITextProperty + public class TextAttribute : ElasticsearchCorePropertyAttributeBase, ITextProperty { ITextProperty Self => this; diff --git a/src/Nest/Mapping/Types/Core/Text/TextProperty.cs b/src/Nest/Mapping/Types/Core/Text/TextProperty.cs index 773abbe5664..81c2ca142fe 100644 --- a/src/Nest/Mapping/Types/Core/Text/TextProperty.cs +++ b/src/Nest/Mapping/Types/Core/Text/TextProperty.cs @@ -8,7 +8,7 @@ namespace Nest { [JsonObject(MemberSerialization.OptIn)] - public interface ITextProperty : IProperty + public interface ITextProperty : ICoreProperty { [JsonProperty("analyzer")] string Analyzer { get; set; } @@ -50,7 +50,7 @@ public interface ITextProperty : IProperty TermVectorOption? TermVector { get; set; } } - public class TextProperty : PropertyBase, ITextProperty + public class TextProperty : CorePropertyBase, ITextProperty { public TextProperty() : base("text") { } @@ -70,7 +70,7 @@ public TextProperty() : base("text") { } } public class TextPropertyDescriptor - : PropertyDescriptorBase, ITextProperty, T>, ITextProperty + : CorePropertyDescriptorBase, ITextProperty, T>, ITextProperty where T : class { double? ITextProperty.Boost { get; set; } diff --git a/src/Nest/Mapping/Types/CorePropertyBase.cs b/src/Nest/Mapping/Types/CorePropertyBase.cs new file mode 100644 index 00000000000..dfb2ad36294 --- /dev/null +++ b/src/Nest/Mapping/Types/CorePropertyBase.cs @@ -0,0 +1,33 @@ +using Newtonsoft.Json; + +namespace Nest +{ + [JsonObject(MemberSerialization.OptIn)] + [ContractJsonConverter(typeof(PropertyJsonConverter))] + public interface ICoreProperty : IProperty + { + [JsonProperty("store")] + bool? Store { get; set; } + + [JsonProperty("fields", DefaultValueHandling = DefaultValueHandling.Ignore)] + IProperties Fields { get; set; } + + [JsonProperty("similarity")] + SimilarityOption? Similarity { get; set; } + + [JsonProperty("copy_to")] + Fields CopyTo { get; set; } + } + + public abstract class CorePropertyBase : PropertyBase, ICoreProperty + { + protected CorePropertyBase(TypeName typeName) : base(typeName) + { + } + + public Fields CopyTo { get; set; } + public IProperties Fields { get; set; } + public SimilarityOption? Similarity { get; set; } + public bool? Store { get; set; } + } +} diff --git a/src/Nest/Mapping/Types/CorePropertyDescriptorBase.cs b/src/Nest/Mapping/Types/CorePropertyDescriptorBase.cs new file mode 100644 index 00000000000..3d31694506c --- /dev/null +++ b/src/Nest/Mapping/Types/CorePropertyDescriptorBase.cs @@ -0,0 +1,26 @@ +using System; + +namespace Nest +{ + public abstract class CorePropertyDescriptorBase + : PropertyDescriptorBase, ICoreProperty + where TDescriptor : CorePropertyDescriptorBase, TInterface + where TInterface : class, ICoreProperty + where T : class + { + bool? ICoreProperty.Store { get; set; } + SimilarityOption? ICoreProperty.Similarity { get; set; } + Fields ICoreProperty.CopyTo { get; set; } + IProperties ICoreProperty.Fields { get; set; } + + protected CorePropertyDescriptorBase(string type) : base(type) {} + + public TDescriptor Store(bool store = true) => Assign(a => a.Store = store); + + public TDescriptor Fields(Func, IPromise> selector) => Assign(a => a.Fields = selector?.Invoke(new PropertiesDescriptor())?.Value); + + public TDescriptor Similarity(SimilarityOption similarity) => Assign(a => a.Similarity = similarity); + + public TDescriptor CopyTo(Func, IPromise> fields) => Assign(a => a.CopyTo = fields?.Invoke(new FieldsDescriptor())?.Value); + } +} diff --git a/src/Nest/Mapping/Types/DocValuesPropertyBase.cs b/src/Nest/Mapping/Types/DocValuesPropertyBase.cs new file mode 100644 index 00000000000..7ee690caae9 --- /dev/null +++ b/src/Nest/Mapping/Types/DocValuesPropertyBase.cs @@ -0,0 +1,21 @@ +using Newtonsoft.Json; + +namespace Nest +{ + [JsonObject(MemberSerialization.OptIn)] + [ContractJsonConverter(typeof(PropertyJsonConverter))] + public interface IDocValuesProperty : ICoreProperty + { + [JsonProperty("doc_values")] + bool? DocValues { get; set; } + } + + public abstract class DocValuesPropertyBase : CorePropertyBase, IDocValuesProperty + { + protected DocValuesPropertyBase(TypeName typeName) : base(typeName) + { + } + + public bool? DocValues { get; set; } + } +} diff --git a/src/Nest/Mapping/Types/DocValuesPropertyDescriptorBase.cs b/src/Nest/Mapping/Types/DocValuesPropertyDescriptorBase.cs new file mode 100644 index 00000000000..0281e94ac0d --- /dev/null +++ b/src/Nest/Mapping/Types/DocValuesPropertyDescriptorBase.cs @@ -0,0 +1,15 @@ +namespace Nest +{ + public abstract class DocValuesPropertyDescriptorBase + : CorePropertyDescriptorBase, IDocValuesProperty + where TDescriptor : DocValuesPropertyDescriptorBase, TInterface + where TInterface : class, IDocValuesProperty + where T : class + { + bool? IDocValuesProperty.DocValues { get; set; } + + protected DocValuesPropertyDescriptorBase(string type) : base(type) { } + + public TDescriptor DocValues(bool docValues = true) => Assign(a => a.DocValues = docValues); + } +} diff --git a/src/Nest/Mapping/Types/Geo/GeoPoint/GeoPointAttribute.cs b/src/Nest/Mapping/Types/Geo/GeoPoint/GeoPointAttribute.cs index fbb60af8d49..7619a6e3120 100644 --- a/src/Nest/Mapping/Types/Geo/GeoPoint/GeoPointAttribute.cs +++ b/src/Nest/Mapping/Types/Geo/GeoPoint/GeoPointAttribute.cs @@ -1,6 +1,6 @@ namespace Nest { - public class GeoPointAttribute : ElasticsearchPropertyAttributeBase, IGeoPointProperty + public class GeoPointAttribute : ElasticsearchDocValuesPropertyAttributeBase, IGeoPointProperty { IGeoPointProperty Self => this; diff --git a/src/Nest/Mapping/Types/Geo/GeoPoint/GeoPointProperty.cs b/src/Nest/Mapping/Types/Geo/GeoPoint/GeoPointProperty.cs index cb9be750ff6..378db4c68ad 100644 --- a/src/Nest/Mapping/Types/Geo/GeoPoint/GeoPointProperty.cs +++ b/src/Nest/Mapping/Types/Geo/GeoPoint/GeoPointProperty.cs @@ -4,7 +4,7 @@ namespace Nest { [JsonObject(MemberSerialization.OptIn)] - public interface IGeoPointProperty : IProperty + public interface IGeoPointProperty : IDocValuesProperty { [JsonProperty("lat_lon")] bool? LatLon { get; set; } @@ -43,7 +43,7 @@ public interface IGeoPointProperty : IProperty IGeoPointFielddata Fielddata { get; set; } } - public class GeoPointProperty : PropertyBase, IGeoPointProperty + public class GeoPointProperty : DocValuesPropertyBase, IGeoPointProperty { public GeoPointProperty() : base("geo_point") { } @@ -62,7 +62,7 @@ public GeoPointProperty() : base("geo_point") { } } public class GeoPointPropertyDescriptor - : PropertyDescriptorBase, IGeoPointProperty, T>, IGeoPointProperty + : DocValuesPropertyDescriptorBase, IGeoPointProperty, T>, IGeoPointProperty where T : class { bool? IGeoPointProperty.LatLon { get; set; } @@ -79,7 +79,7 @@ public class GeoPointPropertyDescriptor IGeoPointFielddata IGeoPointProperty.Fielddata { get; set; } public GeoPointPropertyDescriptor() : base("geo_point") { } - + public GeoPointPropertyDescriptor LatLon(bool latLon = true) => Assign(a => a.LatLon = latLon); public GeoPointPropertyDescriptor GeoHash(bool geoHash = true) => Assign(a => a.GeoHash = geoHash); @@ -105,4 +105,4 @@ public GeoPointPropertyDescriptor() : base("geo_point") { } public GeoPointPropertyDescriptor Fielddata(Func selector) => Assign(a => a.Fielddata = selector(new GeoPointFielddataDescriptor())); } -} \ No newline at end of file +} diff --git a/src/Nest/Mapping/Types/Geo/GeoShape/GeoShapeAttribute.cs b/src/Nest/Mapping/Types/Geo/GeoShape/GeoShapeAttribute.cs index 1b850362d32..b5ffb7e98b3 100644 --- a/src/Nest/Mapping/Types/Geo/GeoShape/GeoShapeAttribute.cs +++ b/src/Nest/Mapping/Types/Geo/GeoShape/GeoShapeAttribute.cs @@ -1,6 +1,6 @@ namespace Nest { - public class GeoShapeAttribute : ElasticsearchPropertyAttributeBase, IGeoShapeProperty + public class GeoShapeAttribute : ElasticsearchDocValuesPropertyAttributeBase, IGeoShapeProperty { IGeoShapeProperty Self => this; diff --git a/src/Nest/Mapping/Types/Geo/GeoShape/GeoShapeProperty.cs b/src/Nest/Mapping/Types/Geo/GeoShape/GeoShapeProperty.cs index cd4f27a108a..f6dc20413ab 100644 --- a/src/Nest/Mapping/Types/Geo/GeoShape/GeoShapeProperty.cs +++ b/src/Nest/Mapping/Types/Geo/GeoShape/GeoShapeProperty.cs @@ -3,7 +3,7 @@ namespace Nest { [JsonObject(MemberSerialization.OptIn)] - public interface IGeoShapeProperty : IProperty + public interface IGeoShapeProperty : IDocValuesProperty { [JsonProperty("tree")] GeoTree? Tree { get; set; } @@ -24,7 +24,7 @@ public interface IGeoShapeProperty : IProperty bool? PointsOnly { get; set; } } - public class GeoShapeProperty : PropertyBase, IGeoShapeProperty + public class GeoShapeProperty : DocValuesPropertyBase, IGeoShapeProperty { public GeoShapeProperty() : base("geo_shape") { } @@ -42,7 +42,7 @@ public GeoShapeProperty() : base("geo_shape") { } } public class GeoShapePropertyDescriptor - : PropertyDescriptorBase, IGeoShapeProperty, T>, IGeoShapeProperty + : DocValuesPropertyDescriptorBase, IGeoShapeProperty, T>, IGeoShapeProperty where T : class { GeoTree? IGeoShapeProperty.Tree { get; set; } @@ -63,9 +63,9 @@ public GeoShapePropertyDescriptor Precision(double precision, DistanceUnit un public GeoShapePropertyDescriptor Orientation(GeoOrientation orientation) => Assign(a => a.Orientation = orientation); - public GeoShapePropertyDescriptor DistanceErrorPercentage(double distanceErrorPercentage) => + public GeoShapePropertyDescriptor DistanceErrorPercentage(double distanceErrorPercentage) => Assign(a => a.DistanceErrorPercentage = distanceErrorPercentage); public GeoShapePropertyDescriptor PointsOnly(bool pointsOnly = true) => Assign(a => a.PointsOnly = pointsOnly); } -} \ No newline at end of file +} diff --git a/src/Nest/Mapping/Types/Properties.cs b/src/Nest/Mapping/Types/Properties.cs index 53cfc1659fd..d2c87826acc 100644 --- a/src/Nest/Mapping/Types/Properties.cs +++ b/src/Nest/Mapping/Types/Properties.cs @@ -55,6 +55,7 @@ TReturnType Nested(Func, INestedProp TReturnType GeoShape(Func, IGeoShapeProperty> selector); TReturnType Completion(Func, ICompletionProperty> selector); TReturnType Murmur3Hash(Func, IMurmur3HashProperty> selector); + TReturnType Percolator(Func, IPercolatorProperty> selector); } public class PropertiesDescriptor : IsADictionaryDescriptorBase, IProperties, PropertyName, IProperty>, IPropertiesDescriptor> @@ -97,6 +98,8 @@ public PropertiesDescriptor Nested(Func Murmur3Hash(Func, IMurmur3HashProperty> selector) => SetProperty(selector); + public PropertiesDescriptor Percolator(Func, IPercolatorProperty> selector) => SetProperty(selector); + public PropertiesDescriptor Custom(IProperty customType) => SetProperty(customType); private PropertiesDescriptor SetProperty(Func selector) diff --git a/src/Nest/Mapping/Types/PropertyBase.cs b/src/Nest/Mapping/Types/PropertyBase.cs index 3d2612ebd3f..f21b5d94e93 100644 --- a/src/Nest/Mapping/Types/PropertyBase.cs +++ b/src/Nest/Mapping/Types/PropertyBase.cs @@ -14,22 +14,6 @@ public interface IProperty : IFieldMapping [JsonProperty("index_name")] string IndexName { get; set; } - - [JsonProperty("store")] - bool? Store { get; set; } - - [JsonProperty("doc_values")] - bool? DocValues { get; set; } - - [JsonProperty("fields", DefaultValueHandling = DefaultValueHandling.Ignore)] - IProperties Fields { get; set; } - - [JsonProperty("similarity")] - SimilarityOption? Similarity { get; set; } - - [JsonProperty("copy_to")] - Fields CopyTo { get; set; } - } public interface IPropertyWithClrOrigin @@ -46,12 +30,7 @@ protected PropertyBase(TypeName typeName) public PropertyName Name { get; set; } public virtual TypeName Type { get; set; } - public Fields CopyTo { get; set; } - public bool? DocValues { get; set; } - public IProperties Fields { get; set; } public string IndexName { get; set; } - public SimilarityOption? Similarity { get; set; } - public bool? Store { get; set; } PropertyInfo IPropertyWithClrOrigin.ClrOrigin { get; set; } } } diff --git a/src/Nest/Mapping/Types/PropertyDescriptorBase.cs b/src/Nest/Mapping/Types/PropertyDescriptorBase.cs index 17cf1a7cd8e..d3a510ebb33 100644 --- a/src/Nest/Mapping/Types/PropertyDescriptorBase.cs +++ b/src/Nest/Mapping/Types/PropertyDescriptorBase.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq.Expressions; namespace Nest @@ -12,11 +12,6 @@ public abstract class PropertyDescriptorBase PropertyName IProperty.Name { get; set; } TypeName IProperty.Type { get; set; } string IProperty.IndexName { get; set; } - bool? IProperty.Store { get; set; } - bool? IProperty.DocValues { get; set; } - SimilarityOption? IProperty.Similarity { get; set; } - Fields IProperty.CopyTo { get; set; } - IProperties IProperty.Fields { get; set; } protected PropertyDescriptorBase(string type) { Self.Type = type; } @@ -25,15 +20,5 @@ public abstract class PropertyDescriptorBase public TDescriptor Name(Expression> objectPath) => Assign(a => a.Name = objectPath); public TDescriptor IndexName(string indexName) => Assign(a => a.IndexName = indexName); - - public TDescriptor Store(bool store = true) => Assign(a => a.Store = store); - - public TDescriptor DocValues(bool docValues = true) => Assign(a => a.DocValues = docValues); - - public TDescriptor Fields(Func, IPromise> selector) => Assign(a => a.Fields = selector?.Invoke(new PropertiesDescriptor())?.Value); - - public TDescriptor Similarity(SimilarityOption similarity) => Assign(a => a.Similarity = similarity); - - public TDescriptor CopyTo(Func, IPromise> fields) => Assign(a => a.CopyTo = fields?.Invoke(new FieldsDescriptor())?.Value); } -} +} \ No newline at end of file diff --git a/src/Nest/Mapping/Types/PropertyJsonConverter.cs b/src/Nest/Mapping/Types/PropertyJsonConverter.cs index b565de593a6..b36bfe7bacc 100644 --- a/src/Nest/Mapping/Types/PropertyJsonConverter.cs +++ b/src/Nest/Mapping/Types/PropertyJsonConverter.cs @@ -6,10 +6,7 @@ namespace Nest { internal class PropertyJsonConverter : JsonConverter { - public override bool CanWrite - { - get { return false; } - } + public override bool CanWrite => false; public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { @@ -18,14 +15,14 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { - JObject o = JObject.Load(reader); + var jObject = JObject.Load(reader); JToken typeToken; JToken propertiesToken; var type = string.Empty; - var hasType = o.TryGetValue("type", out typeToken); + var hasType = jObject.TryGetValue("type", out typeToken); if (hasType) type = typeToken.Value().ToLowerInvariant(); - else if (o.TryGetValue("properties", out propertiesToken)) + else if (jObject.TryGetValue("properties", out propertiesToken)) type = "object"; serializer.TypeNameHandling = TypeNameHandling.None; @@ -33,42 +30,44 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist switch (type) { case "text": - return o.ToObject(); + return jObject.ToObject(); case "keyword": - return o.ToObject(); + return jObject.ToObject(); case "string": - return o.ToObject(); + return jObject.ToObject(); case "float": case "double": case "byte": case "short": case "integer": case "long": - return o.ToObject(); + return jObject.ToObject(); case "date": - return o.ToObject(); + return jObject.ToObject(); case "boolean": - return o.ToObject(); + return jObject.ToObject(); case "binary": - return o.ToObject(); + return jObject.ToObject(); case "object": - return o.ToObject(); + return jObject.ToObject(); case "nested": - return o.ToObject(); + return jObject.ToObject(); case "ip": - return o.ToObject(); + return jObject.ToObject(); case "geo_point": - return o.ToObject(); + return jObject.ToObject(); case "geo_shape": - return o.ToObject(); + return jObject.ToObject(); case "attachment": - return o.ToObject(); + return jObject.ToObject(); case "completion": - return o.ToObject(); + return jObject.ToObject(); case "token_count": - return o.ToObject(); + return jObject.ToObject(); case "murmur3": - return o.ToObject(); + return jObject.ToObject(); + case "percolator": + return jObject.ToObject(); } return null; diff --git a/src/Nest/Mapping/Types/Specialized/Attachment/AttachmentAttribute.cs b/src/Nest/Mapping/Types/Specialized/Attachment/AttachmentAttribute.cs index 5f7eb78c755..fc22c34e7c3 100644 --- a/src/Nest/Mapping/Types/Specialized/Attachment/AttachmentAttribute.cs +++ b/src/Nest/Mapping/Types/Specialized/Attachment/AttachmentAttribute.cs @@ -1,7 +1,7 @@ namespace Nest { // TODO validate if these mappings still apply to 5.0 - public class AttachmentAttribute : ElasticsearchPropertyAttributeBase, IAttachmentProperty + public class AttachmentAttribute : ElasticsearchDocValuesPropertyAttributeBase, IAttachmentProperty { ITextProperty IAttachmentProperty.AuthorField { get; set; } INumberProperty IAttachmentProperty.ContentLengthField { get; set; } diff --git a/src/Nest/Mapping/Types/Specialized/Attachment/AttachmentProperty.cs b/src/Nest/Mapping/Types/Specialized/Attachment/AttachmentProperty.cs index dff3ef869f0..43184457927 100644 --- a/src/Nest/Mapping/Types/Specialized/Attachment/AttachmentProperty.cs +++ b/src/Nest/Mapping/Types/Specialized/Attachment/AttachmentProperty.cs @@ -5,7 +5,7 @@ namespace Nest { [JsonObject(MemberSerialization.OptIn)] - public interface IAttachmentProperty : IProperty + public interface IAttachmentProperty : IDocValuesProperty { IDateProperty DateField { get; set; } ITextProperty TitleField { get; set; } @@ -18,7 +18,7 @@ public interface IAttachmentProperty : IProperty ITextProperty LanguageField { get; set; } } - public class AttachmentProperty : PropertyBase, IAttachmentProperty + public class AttachmentProperty : DocValuesPropertyBase, IAttachmentProperty { public AttachmentProperty() : base("attachment") { } @@ -80,7 +80,7 @@ public ITextProperty TitleField } public class AttachmentPropertyDescriptor - : PropertyDescriptorBase, IAttachmentProperty, T>, IAttachmentProperty + : DocValuesPropertyDescriptorBase, IAttachmentProperty, T>, IAttachmentProperty where T : class { IDateProperty IAttachmentProperty.DateField { get; set; } diff --git a/src/Nest/Mapping/Types/Specialized/Completion/CompletionAttribute.cs b/src/Nest/Mapping/Types/Specialized/Completion/CompletionAttribute.cs index 63a0b172f04..9f16f5de6a2 100644 --- a/src/Nest/Mapping/Types/Specialized/Completion/CompletionAttribute.cs +++ b/src/Nest/Mapping/Types/Specialized/Completion/CompletionAttribute.cs @@ -2,7 +2,7 @@ namespace Nest { - public class CompletionAttribute : ElasticsearchPropertyAttributeBase, ICompletionProperty + public class CompletionAttribute : ElasticsearchDocValuesPropertyAttributeBase, ICompletionProperty { ICompletionProperty Self => this; diff --git a/src/Nest/Mapping/Types/Specialized/Completion/CompletionProperty.cs b/src/Nest/Mapping/Types/Specialized/Completion/CompletionProperty.cs index e911836d11b..3522a533262 100644 --- a/src/Nest/Mapping/Types/Specialized/Completion/CompletionProperty.cs +++ b/src/Nest/Mapping/Types/Specialized/Completion/CompletionProperty.cs @@ -6,7 +6,7 @@ namespace Nest { [JsonObject(MemberSerialization.OptIn)] - public interface ICompletionProperty : IProperty + public interface ICompletionProperty : IDocValuesProperty { [JsonProperty("search_analyzer")] string SearchAnalyzer { get; set; } @@ -28,7 +28,7 @@ public interface ICompletionProperty : IProperty } [JsonObject(MemberSerialization.OptIn)] - public class CompletionProperty : PropertyBase, ICompletionProperty + public class CompletionProperty : DocValuesPropertyBase, ICompletionProperty { public CompletionProperty() : base("completion") { } @@ -41,7 +41,7 @@ public CompletionProperty() : base("completion") { } } public class CompletionPropertyDescriptor - : PropertyDescriptorBase, ICompletionProperty, T>, ICompletionProperty + : DocValuesPropertyDescriptorBase, ICompletionProperty, T>, ICompletionProperty where T : class { string ICompletionProperty.SearchAnalyzer { get; set; } diff --git a/src/Nest/Mapping/Types/Specialized/Ip/IpAttribute.cs b/src/Nest/Mapping/Types/Specialized/Ip/IpAttribute.cs index c5ac22d4d11..043c82d84b5 100644 --- a/src/Nest/Mapping/Types/Specialized/Ip/IpAttribute.cs +++ b/src/Nest/Mapping/Types/Specialized/Ip/IpAttribute.cs @@ -1,6 +1,6 @@ namespace Nest { - public class IpAttribute : ElasticsearchPropertyAttributeBase, IIpProperty + public class IpAttribute : ElasticsearchDocValuesPropertyAttributeBase, IIpProperty { IIpProperty Self => this; diff --git a/src/Nest/Mapping/Types/Specialized/Ip/IpProperty.cs b/src/Nest/Mapping/Types/Specialized/Ip/IpProperty.cs index f264e1eec95..3ad34fc7d55 100644 --- a/src/Nest/Mapping/Types/Specialized/Ip/IpProperty.cs +++ b/src/Nest/Mapping/Types/Specialized/Ip/IpProperty.cs @@ -3,7 +3,7 @@ namespace Nest { [JsonObject(MemberSerialization.OptIn)] - public interface IIpProperty : IProperty + public interface IIpProperty : IDocValuesProperty { [JsonProperty("index")] bool? Index { get; set; } @@ -21,7 +21,7 @@ public interface IIpProperty : IProperty bool? IncludeInAll { get; set; } } - public class IpProperty : PropertyBase, IIpProperty + public class IpProperty : DocValuesPropertyBase, IIpProperty { public IpProperty() : base("ip") { } @@ -33,7 +33,7 @@ public IpProperty() : base("ip") { } } public class IpPropertyDescriptor - : PropertyDescriptorBase, IIpProperty, T>, IIpProperty + : DocValuesPropertyDescriptorBase, IIpProperty, T>, IIpProperty where T : class { bool? IIpProperty.Index { get; set; } diff --git a/src/Nest/Mapping/Types/Specialized/Murmur3Hash/Murmur3HashAttribute.cs b/src/Nest/Mapping/Types/Specialized/Murmur3Hash/Murmur3HashAttribute.cs index cea7ef16763..260263b2d6b 100644 --- a/src/Nest/Mapping/Types/Specialized/Murmur3Hash/Murmur3HashAttribute.cs +++ b/src/Nest/Mapping/Types/Specialized/Murmur3Hash/Murmur3HashAttribute.cs @@ -1,6 +1,6 @@ namespace Nest { - public class Murmur3HashAttribute : ElasticsearchPropertyAttributeBase, IMurmur3HashProperty + public class Murmur3HashAttribute : ElasticsearchDocValuesPropertyAttributeBase, IMurmur3HashProperty { public Murmur3HashAttribute() : base("murmur3") { } } diff --git a/src/Nest/Mapping/Types/Specialized/Murmur3Hash/Murmur3HashProperty.cs b/src/Nest/Mapping/Types/Specialized/Murmur3Hash/Murmur3HashProperty.cs index 78ecdd01554..247af5c390e 100644 --- a/src/Nest/Mapping/Types/Specialized/Murmur3Hash/Murmur3HashProperty.cs +++ b/src/Nest/Mapping/Types/Specialized/Murmur3Hash/Murmur3HashProperty.cs @@ -4,17 +4,17 @@ namespace Nest { [JsonObject(MemberSerialization.OptIn)] - public interface IMurmur3HashProperty : IProperty + public interface IMurmur3HashProperty : IDocValuesProperty { } - public class Murmur3HashProperty : PropertyBase, IMurmur3HashProperty + public class Murmur3HashProperty : DocValuesPropertyBase, IMurmur3HashProperty { public Murmur3HashProperty() : base("murmur3") { } } - public class Murmur3HashPropertyDescriptor - : PropertyDescriptorBase, IMurmur3HashProperty, T>, IMurmur3HashProperty + public class Murmur3HashPropertyDescriptor + : DocValuesPropertyDescriptorBase, IMurmur3HashProperty, T>, IMurmur3HashProperty where T : class { public Murmur3HashPropertyDescriptor() : base("murmur3") { } diff --git a/src/Nest/Nest.csproj b/src/Nest/Nest.csproj index 39eae46306a..aa2ab43f99a 100644 --- a/src/Nest/Nest.csproj +++ b/src/Nest/Nest.csproj @@ -746,6 +746,7 @@ + @@ -773,6 +774,7 @@ + @@ -785,6 +787,8 @@ + + @@ -800,6 +804,7 @@ + @@ -1005,6 +1010,7 @@ + diff --git a/src/Nest/QueryDsl/Abstractions/Container/IQueryContainer.cs b/src/Nest/QueryDsl/Abstractions/Container/IQueryContainer.cs index 76b1923c328..4532cdb61bd 100644 --- a/src/Nest/QueryDsl/Abstractions/Container/IQueryContainer.cs +++ b/src/Nest/QueryDsl/Abstractions/Container/IQueryContainer.cs @@ -147,6 +147,9 @@ public interface IQueryContainer [JsonProperty("type")] ITypeQuery Type { get; set; } + [JsonProperty("percolator")] + IPercolateQuery Percolate { get; set; } + void Accept(IQueryVisitor visitor); } } diff --git a/src/Nest/QueryDsl/Abstractions/Container/QueryContainer-Assignments.cs b/src/Nest/QueryDsl/Abstractions/Container/QueryContainer-Assignments.cs index 89d92fd5989..2ed60d9c142 100644 --- a/src/Nest/QueryDsl/Abstractions/Container/QueryContainer-Assignments.cs +++ b/src/Nest/QueryDsl/Abstractions/Container/QueryContainer-Assignments.cs @@ -49,7 +49,8 @@ public partial class QueryContainer : IQueryContainer, IDescriptor private IExistsQuery _exists; private IMissingQuery _missing; private ITypeQuery _type; - private IRawQuery _rawQuery; + private IRawQuery _raw; + private IPercolateQuery _percolate; private IQueryContainer Self => this; internal IQuery ContainedQuery { get; set; } @@ -62,7 +63,7 @@ private T Set(T value) where T : IQuery return value; } - IRawQuery IQueryContainer.RawQuery { get { return _rawQuery; } set { _rawQuery = Set(value); } } + IRawQuery IQueryContainer.RawQuery { get { return _raw; } set { _raw = Set(value); } } IBoolQuery IQueryContainer.Bool { get { return _b; } set { _b = Set(value); } } IMatchAllQuery IQueryContainer.MatchAll { get { return _matchAllQuery; } set { _matchAllQuery = Set(value); } } ITermQuery IQueryContainer.Term { get { return _term; } set { _term = Set(value); } } @@ -107,8 +108,6 @@ private T Set(T value) where T : IQuery IExistsQuery IQueryContainer.Exists { get { return _exists; } set { _exists = Set(value); } } IMissingQuery IQueryContainer.Missing { get { return _missing; } set { _missing = Set(value); } } ITypeQuery IQueryContainer.Type { get { return _type; } set { _type = Set(value); } } - - + IPercolateQuery IQueryContainer.Percolate { get { return _percolate; } set { _percolate = Set(value); } } } - } diff --git a/src/Nest/QueryDsl/Abstractions/Container/QueryContainer-Dsl.cs b/src/Nest/QueryDsl/Abstractions/Container/QueryContainer-Dsl.cs index 05e36e02145..59f1e4dc96e 100644 --- a/src/Nest/QueryDsl/Abstractions/Container/QueryContainer-Dsl.cs +++ b/src/Nest/QueryDsl/Abstractions/Container/QueryContainer-Dsl.cs @@ -4,7 +4,7 @@ namespace Nest { internal static class QueryContainerExtensions { - public static bool IsConditionless(this QueryContainer q) => q == null || q.IsConditionless; + internal static bool IsConditionless(this QueryContainer q) => q == null || q.IsConditionless; } public partial class QueryContainer : IQueryContainer, IDescriptor @@ -21,25 +21,25 @@ public partial class QueryContainer : IQueryContainer, IDescriptor public QueryContainer() { } - + public QueryContainer(QueryBase query) : this() { query?.WrapInContainer(this); } - + public static QueryContainer operator &(QueryContainer leftContainer, QueryContainer rightContainer) { QueryContainer queryContainer; - return IfEitherIsEmptyReturnTheOtherOrEmpty(leftContainer, rightContainer, out queryContainer) - ? queryContainer + return IfEitherIsEmptyReturnTheOtherOrEmpty(leftContainer, rightContainer, out queryContainer) + ? queryContainer : leftContainer.CombineAsMust(rightContainer); } - + public static QueryContainer operator |(QueryContainer leftContainer, QueryContainer rightContainer) { QueryContainer queryContainer; - return IfEitherIsEmptyReturnTheOtherOrEmpty(leftContainer, rightContainer, out queryContainer) - ? queryContainer + return IfEitherIsEmptyReturnTheOtherOrEmpty(leftContainer, rightContainer, out queryContainer) + ? queryContainer : leftContainer.CombineAsShould(rightContainer); } diff --git a/src/Nest/QueryDsl/Abstractions/Container/QueryContainerDescriptor.cs b/src/Nest/QueryDsl/Abstractions/Container/QueryContainerDescriptor.cs index 42957ee69f7..78cbc51869d 100644 --- a/src/Nest/QueryDsl/Abstractions/Container/QueryContainerDescriptor.cs +++ b/src/Nest/QueryDsl/Abstractions/Container/QueryContainerDescriptor.cs @@ -459,7 +459,9 @@ public QueryContainer Regexp(Func, IRegexpQuery> select this.Assign(selector, (query, container) => container.Regexp = query); /// - /// Function score query + /// The function_score query allows you to modify the score of documents that are retrieved by a query. + /// This can be useful if, for example, a score function is computationally expensive and it is + /// sufficient to compute the score on a filtered set of documents. /// /// public QueryContainer FunctionScore(Func, IFunctionScoreQuery> selector) => @@ -480,7 +482,14 @@ public QueryContainer Missing(Func, IMissingQuery> sel public QueryContainer Type(Func selector) => this.Assign(selector, (query, container) => container.Type = query); - public QueryContainer Type() => this.Type(q => q.Value()); - + public QueryContainer Type() => this.Type(q => q.Value()); + + /// + /// percolate query can be used to match queries stored in an index. + /// The percolate query itself contains the document that will be used as query + /// to match with the stored queries. + /// + public QueryContainer Percolate(Func, IPercolateQuery> selector) => + this.Assign(selector, (query, container) => container.Percolate = query); } } diff --git a/src/Nest/QueryDsl/Abstractions/FieldName/FieldNameQueryJsonConverter.cs b/src/Nest/QueryDsl/Abstractions/FieldName/FieldNameQueryJsonConverter.cs index 5121a82b85b..e1da4aa47b4 100644 --- a/src/Nest/QueryDsl/Abstractions/FieldName/FieldNameQueryJsonConverter.cs +++ b/src/Nest/QueryDsl/Abstractions/FieldName/FieldNameQueryJsonConverter.cs @@ -32,13 +32,11 @@ protected override void SerializeJson(JsonWriter writer, object value, IFieldNam if (field.IsNullOrEmpty()) return; writer.WriteStartObject(); - { - writer.WritePropertyName(field); - { - this.Reserialize(writer, value, serializer); - } - writer.WriteEndObject(); - } + writer.WritePropertyName(field); + + this.Reserialize(writer, value, serializer); + + writer.WriteEndObject(); } } -} \ No newline at end of file +} diff --git a/src/Nest/QueryDsl/Query.cs b/src/Nest/QueryDsl/Query.cs index 3b712bbd89e..d475ec4bcd0 100644 --- a/src/Nest/QueryDsl/Query.cs +++ b/src/Nest/QueryDsl/Query.cs @@ -5,7 +5,6 @@ namespace Nest { - // TODO: Write a unit test for these using reflection to make sure all queries are covered public static class Query where T : class { public static QueryContainer Bool(Func, IBoolQuery> selector) => @@ -113,6 +112,9 @@ public static QueryContainer MultiMatch(Func, IMult public static QueryContainer Nested(Func, INestedQuery> selector) => new QueryContainerDescriptor().Nested(selector); + public static QueryContainer Percolate(Func, IPercolateQuery> selector) => + new QueryContainerDescriptor().Percolate(selector); + public static QueryContainer Prefix(Expression> fieldDescriptor, string value, double? boost = null, RewriteMultiTerm? rewrite = null, string name = null) => new QueryContainerDescriptor().Prefix(fieldDescriptor, value, boost, rewrite, name); diff --git a/src/Nest/QueryDsl/Specialized/Percolate/PercolateQuery.cs b/src/Nest/QueryDsl/Specialized/Percolate/PercolateQuery.cs new file mode 100644 index 00000000000..6773ef10d6e --- /dev/null +++ b/src/Nest/QueryDsl/Specialized/Percolate/PercolateQuery.cs @@ -0,0 +1,224 @@ +using Newtonsoft.Json; + +namespace Nest +{ + /// + /// The percolate query can be used to match queries stored in an index + /// + [JsonConverter(typeof(ReadAsTypeJsonConverter))] + [JsonObject(MemberSerialization = MemberSerialization.OptIn)] + public interface IPercolateQuery : IQuery + { + /// + /// The type / mapping of the document to percolate. This is a required parameter. + /// + [JsonProperty(PropertyName = "document_type")] + TypeName DocumentType { get; set; } + + /// + /// The source of the document to percolate. + /// + [JsonProperty(PropertyName = "document")] + object Document { get; set; } + + /// + /// The id of the document to fetch for percolation. + /// Can be specified to percolate an existing document instead of providing + /// + [JsonProperty(PropertyName = "id")] + Id Id { get; set; } + + /// + /// The index the document resides in for percolation. + /// Can be specified to percolate an existing document instead of providing + /// + [JsonProperty(PropertyName = "index")] + IndexName Index { get; set; } + + /// + /// The type of the document to fetch for percolation. + /// Can be specified to percolate an existing document instead of providing + /// + [JsonProperty(PropertyName = "type")] + TypeName Type { get; set; } + + /// + /// Routing to be used to fetch the document to percolate. + /// Can be specified to percolate an existing document instead of providing + /// + [JsonProperty(PropertyName = "routing")] + string Routing { get; set; } + + /// + /// Preference to be used to fetch the document to percolate. + /// Can be specified to percolate an existing document instead of providing + /// + [JsonProperty(PropertyName = "preference")] + string Preference { get; set; } + + /// + /// The expected version of the document to be fetched for percolation. + /// Can be specified to percolate an existing document instead of providing + /// + [JsonProperty(PropertyName = "version")] + long? Version { get; set; } + } + + /// + /// The percolate query can be used to match queries stored in an index + /// + public class PercolateQuery : QueryBase, IPercolateQuery + { + protected override bool Conditionless => IsConditionless(this); + + internal override void WrapInContainer(IQueryContainer c) => c.Percolate = this; + + internal static bool IsConditionless(IPercolateQuery q) + { + var docFields = q.DocumentType.IsConditionless() || q.Document == null; + + if (!docFields) + { + return false; + } + + return q.DocumentType.IsConditionless() || + q.Type.IsConditionless() || + q.Index == null || + q.Id.IsConditionless(); + } + + /// + /// The type / mapping of the document to percolate. This is a required parameter. + /// + public TypeName DocumentType { get; set; } + + /// + /// The source of the document to percolate. + /// + public object Document { get; set; } + + /// + /// The id of the document to fetch for percolation. + /// Can be specified to percolate an existing document instead of providing + /// + public Id Id { get; set; } + + /// + /// The index the document resides in for percolation. + /// Can be specified to percolate an existing document instead of providing + /// + public IndexName Index { get; set; } + + /// + /// The type of the document to fetch for percolation. + /// Can be specified to percolate an existing document instead of providing + /// + public TypeName Type { get; set; } + + /// + /// Routing to be used to fetch the document to percolate. + /// Can be specified to percolate an existing document instead of providing + /// + public string Routing { get; set; } + + /// + /// Preference to be used to fetch the document to percolate. + /// Can be specified to percolate an existing document instead of providing + /// + public string Preference { get; set; } + + /// + /// The expected version of the document to be fetched for percolation. + /// Can be specified to percolate an existing document instead of providing + /// + public long? Version { get; set; } + } + + /// + /// The percolate query can be used to match queries stored in an index + /// + /// + public class PercolateQueryDescriptor + : QueryDescriptorBase, IPercolateQuery> + , IPercolateQuery where T : class + { + TypeName IPercolateQuery.DocumentType { get; set; } + object IPercolateQuery.Document { get; set; } + Id IPercolateQuery.Id { get; set; } + IndexName IPercolateQuery.Index { get; set; } + TypeName IPercolateQuery.Type { get; set; } + string IPercolateQuery.Routing { get; set; } + string IPercolateQuery.Preference { get; set; } + long? IPercolateQuery.Version { get; set; } + + /// + /// Determines if the query is conditionless and should not be serialized + /// in the request + /// + protected override bool Conditionless => PercolateQuery.IsConditionless(this); + + /// + /// The type / mapping of the document to percolate. This is a required parameter. + /// + public PercolateQueryDescriptor DocumentType(TypeName type) => Assign(a => a.DocumentType = type); + + /// + /// The type / mapping of the document to percolate. This is a required parameter. + /// + public PercolateQueryDescriptor DocumentType() => Assign(a => a.DocumentType = typeof(TDocument)); + + /// + /// The source of the document to percolate. + /// + public PercolateQueryDescriptor Document(TDocument document) => Assign(a => a.Document = document); + + /// + /// The id of the document to fetch for percolation. + /// Can be specified to percolate an existing document instead of providing + /// + public PercolateQueryDescriptor Id(string id) => Assign(a => a.Id = id); + + /// + /// The index the document resides in for percolation. + /// Can be specified to percolate an existing document instead of providing + /// + public PercolateQueryDescriptor Index(IndexName index) => Assign(a => a.Index = index); + + /// + /// The index the document resides in for percolation. + /// Can be specified to percolate an existing document instead of providing + /// + public PercolateQueryDescriptor Index() => Assign(a => a.Index = typeof(TDocument)); + + /// + /// The type of the document to fetch for percolation. + /// Can be specified to percolate an existing document instead of providing + /// + public PercolateQueryDescriptor Type(TypeName type) => Assign(a => a.Type = type); + + /// + /// The type of the document to fetch for percolation. + /// Can be specified to percolate an existing document instead of providing + /// + public PercolateQueryDescriptor Type() => Assign(a => a.Type = typeof(TDocument)); + + /// + /// Routing to be used to fetch the document to percolate. + /// Can be specified to percolate an existing document instead of providing + /// + public PercolateQueryDescriptor Routing(string routing) => Assign(a => a.Routing = routing); + + /// + /// Preference to be used to fetch the document to percolate. + /// Can be specified to percolate an existing document instead of providing + /// + public PercolateQueryDescriptor Preference(string preference) => Assign(a => a.Preference = preference); + + /// + /// The expected version of the document to be fetched for percolation. + /// Can be specified to percolate an existing document instead of providing + /// + public PercolateQueryDescriptor Version(long version) => Assign(a => a.Version = version); + } +} diff --git a/src/Nest/QueryDsl/TermLevel/Fuzzy/FuzzyQueryJsonConverter.cs b/src/Nest/QueryDsl/TermLevel/Fuzzy/FuzzyQueryJsonConverter.cs index a3f5df03a7e..8bb4802a91a 100644 --- a/src/Nest/QueryDsl/TermLevel/Fuzzy/FuzzyQueryJsonConverter.cs +++ b/src/Nest/QueryDsl/TermLevel/Fuzzy/FuzzyQueryJsonConverter.cs @@ -53,15 +53,15 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist Fuzziness = GetPropValue(jo, "fuzziness") }; } - else return null; + else return null; - fq.PrefixLength = GetPropValue(jo, "prefix_length"); + fq.PrefixLength = GetPropValue(jo, "prefix_length"); fq.MaxExpansions = GetPropValue(jo, "max_expansions"); fq.Transpositions = GetPropValue(jo, "transpositions"); var rewriteString = GetPropValue(jo, "rewrite"); if (!rewriteString.IsNullOrEmpty()) fq.Rewrite = rewriteString.ToEnum(); - + fq.Name = GetPropValue(jo, "_name"); fq.Boost = GetPropValue(jo, "boost"); fq.Field = field; @@ -69,19 +69,20 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist return fq; } - public TReturn GetPropObject(JObject jObject, string field) + private TReturn GetPropObject(JObject jObject, string field) { - JToken jToken = null; - return !jObject.TryGetValue(field, out jToken) - ? default(TReturn) + JToken jToken; + return !jObject.TryGetValue(field, out jToken) + ? default(TReturn) : jToken.ToObject(); } - public TReturn GetPropValue(JObject jObject, string field) + + private TReturn GetPropValue(JObject jObject, string field) { - JToken jToken = null; - return !jObject.TryGetValue(field, out jToken) - ? default(TReturn) + JToken jToken; + return !jObject.TryGetValue(field, out jToken) + ? default(TReturn) : jToken.Value(); } } -} \ No newline at end of file +} diff --git a/src/Nest/QueryDsl/TermLevel/Range/RangeQueryJsonConverter.cs b/src/Nest/QueryDsl/TermLevel/Range/RangeQueryJsonConverter.cs index dc8377395eb..469d5bc491a 100644 --- a/src/Nest/QueryDsl/TermLevel/Range/RangeQueryJsonConverter.cs +++ b/src/Nest/QueryDsl/TermLevel/Range/RangeQueryJsonConverter.cs @@ -25,22 +25,22 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist var field = firstProp.Name; var jo = firstProp.Value.Value(); if (jo == null) return null; - + var isNumeric = !jo.Properties().Any(p=>p.Name == "format" || p.Name == "time_zone") && jo.Properties().Any(p=> _rangeKeys.Contains(p.Name) && (p.Value.Type == JTokenType.Integer || p.Value.Type == JTokenType.Float)); - + IRangeQuery fq; if (isNumeric) { fq = FromJson.ReadAs(jo.CreateReader(), objectType, existingValue, serializer); } - else + else { fq = FromJson.ReadAs(jo.CreateReader(), objectType, existingValue, serializer); } - + fq.Name = GetPropValue(jo, "_name"); fq.Boost = GetPropValue(jo, "boost"); fq.Field = field; @@ -48,19 +48,12 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist return fq; } - public TReturn GetPropObject(JObject jObject, string field) - { - JToken jToken = null; - return !jObject.TryGetValue(field, out jToken) - ? default(TReturn) - : jToken.ToObject(); - } - public TReturn GetPropValue(JObject jObject, string field) + private static TReturn GetPropValue(JObject jObject, string field) { JToken jToken = null; - return !jObject.TryGetValue(field, out jToken) - ? default(TReturn) + return !jObject.TryGetValue(field, out jToken) + ? default(TReturn) : jToken.Value(); } } -} \ No newline at end of file +} diff --git a/src/Nest/QueryDsl/Visitor/DslPrettyPrintVisitor.cs b/src/Nest/QueryDsl/Visitor/DslPrettyPrintVisitor.cs index be19fc87872..833089b5e02 100644 --- a/src/Nest/QueryDsl/Visitor/DslPrettyPrintVisitor.cs +++ b/src/Nest/QueryDsl/Visitor/DslPrettyPrintVisitor.cs @@ -180,6 +180,8 @@ private void Write(string queryType, Field field = null) public void Visit(IScriptQuery filter) => Write("script"); - public void Visit(IRawQuery filter) => Write("script"); + public void Visit(IRawQuery filter) => Write("raw"); + + public void Visit(IPercolateQuery filter) => Write("percolate"); } } diff --git a/src/Nest/QueryDsl/Visitor/QueryVisitor.cs b/src/Nest/QueryDsl/Visitor/QueryVisitor.cs index 8e583ebd111..40dffca5937 100644 --- a/src/Nest/QueryDsl/Visitor/QueryVisitor.cs +++ b/src/Nest/QueryDsl/Visitor/QueryVisitor.cs @@ -74,7 +74,6 @@ public interface IQueryVisitor void Visit(ISpanContainingQuery query); void Visit(ISpanWithinQuery query); void Visit(ISpanMultiTermQuery query); - void Visit(IGeoIndexedShapeQuery query); void Visit(IGeoShapeQuery query); void Visit(IGeoShapeMultiPointQuery query); @@ -86,6 +85,7 @@ public interface IQueryVisitor void Visit(IGeoShapeEnvelopeQuery query); void Visit(IGeoShapeCircleQuery query); void Visit(IRawQuery query); + void Visit(IPercolateQuery query); } public class QueryVisitor : IQueryVisitor @@ -125,8 +125,11 @@ public virtual void Visit(ITermRangeQuery query) { } public virtual void Visit(IFunctionScoreQuery query) { } public virtual void Visit(IFuzzyQuery query) { } + public virtual void Visit(IFuzzyStringQuery query) { } + public virtual void Visit(IFuzzyNumericQuery query) { } + public virtual void Visit(IFuzzyDateQuery query) { } public virtual void Visit(IGeoShapeQuery query) { } @@ -218,5 +221,7 @@ public virtual void Visit(IGeoBoundingBoxQuery query) { } public virtual void Visit(IExistsQuery query) { } public virtual void Visit(IRawQuery query) { } + + public virtual void Visit(IPercolateQuery query) { } } } diff --git a/src/Nest/QueryDsl/Visitor/QueryWalker.cs b/src/Nest/QueryDsl/Visitor/QueryWalker.cs index 5852dc0ebd7..38058999b50 100644 --- a/src/Nest/QueryDsl/Visitor/QueryWalker.cs +++ b/src/Nest/QueryDsl/Visitor/QueryWalker.cs @@ -61,6 +61,7 @@ public void Walk(IQueryContainer qd, IQueryVisitor visitor) VisitQuery(qd.GeoHashCell, visitor, (v, d) => v.Visit(d)); VisitQuery(qd.Template, visitor, (v, d) => v.Visit(d)); VisitQuery(qd.RawQuery, visitor, (v, d) => v.Visit(d)); + VisitQuery(qd.Percolate, visitor, (v, d) => v.Visit(d)); VisitQuery(qd.Bool, visitor, (v, d) => { diff --git a/src/Nest/Search/Percolator/MultiPercolate/ElasticClient-MultiPercolate.cs b/src/Nest/Search/Percolator/MultiPercolate/ElasticClient-MultiPercolate.cs index 2b5156dbb49..c4231d161df 100644 --- a/src/Nest/Search/Percolator/MultiPercolate/ElasticClient-MultiPercolate.cs +++ b/src/Nest/Search/Percolator/MultiPercolate/ElasticClient-MultiPercolate.cs @@ -7,42 +7,49 @@ namespace Nest public partial interface IElasticClient { /// - /// The multi percolate API allows to bundle multiple percolate requests into a single request, + /// The multi percolate API allows to bundle multiple percolate requests into a single request, /// similar to what the multi search API does to search requests. - /// https://www.elastic.co/guide/en/elasticsearch/reference/current/search-percolate.html#_multi_percolate_api /// /// A descriptor to describe the multi percolate operation + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with multi search api")] IMultiPercolateResponse MultiPercolate(Func selector); /// + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with multi search api")] IMultiPercolateResponse MultiPercolate(IMultiPercolateRequest request); /// + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with multi search api")] Task MultiPercolateAsync(Func selector); /// + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with multi search api")] Task MultiPercolateAsync(IMultiPercolateRequest request); } public partial class ElasticClient { /// + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with multi search api")] public IMultiPercolateResponse MultiPercolate(Func selector) => this.MultiPercolate(selector?.Invoke(new MultiPercolateDescriptor())); /// - public IMultiPercolateResponse MultiPercolate(IMultiPercolateRequest request) => + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with multi search api")] + public IMultiPercolateResponse MultiPercolate(IMultiPercolateRequest request) => this.Dispatcher.Dispatch( request, this.LowLevelDispatch.MpercolateDispatch ); /// - public Task MultiPercolateAsync(Func selector) => + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with multi search api")] + public Task MultiPercolateAsync(Func selector) => this.MultiPercolateAsync(selector?.Invoke(new MultiPercolateDescriptor())); /// - public Task MultiPercolateAsync(IMultiPercolateRequest request) => + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with multi search api")] + public Task MultiPercolateAsync(IMultiPercolateRequest request) => this.Dispatcher.DispatchAsync( request, this.LowLevelDispatch.MpercolateDispatchAsync ); } -} \ No newline at end of file +} diff --git a/src/Nest/Search/Percolator/MultiPercolate/IPercolateOperation.cs b/src/Nest/Search/Percolator/MultiPercolate/IPercolateOperation.cs index fa54bc3c35d..8352c200687 100644 --- a/src/Nest/Search/Percolator/MultiPercolate/IPercolateOperation.cs +++ b/src/Nest/Search/Percolator/MultiPercolate/IPercolateOperation.cs @@ -1,10 +1,12 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Elasticsearch.Net; using Newtonsoft.Json; namespace Nest { [JsonObject(MemberSerialization = MemberSerialization.OptIn)] + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with multi search api")] public interface IPercolateOperation { [JsonIgnore] @@ -33,4 +35,4 @@ public interface IPercolateOperation IRequestParameters GetRequestParameters(); } -} \ No newline at end of file +} diff --git a/src/Nest/Search/Percolator/MultiPercolate/MultiPercolateJsonConverter.cs b/src/Nest/Search/Percolator/MultiPercolate/MultiPercolateJsonConverter.cs index 11d7267f9b1..91689adbce8 100644 --- a/src/Nest/Search/Percolator/MultiPercolate/MultiPercolateJsonConverter.cs +++ b/src/Nest/Search/Percolator/MultiPercolate/MultiPercolateJsonConverter.cs @@ -4,6 +4,7 @@ namespace Nest { + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with multi search api")] internal class MultiPercolateJsonConverter : JsonConverter { public override bool CanRead => false; diff --git a/src/Nest/Search/Percolator/MultiPercolate/MultiPercolateRequest.cs b/src/Nest/Search/Percolator/MultiPercolate/MultiPercolateRequest.cs index 186fdcb1b28..a3f25de8b19 100644 --- a/src/Nest/Search/Percolator/MultiPercolate/MultiPercolateRequest.cs +++ b/src/Nest/Search/Percolator/MultiPercolate/MultiPercolateRequest.cs @@ -5,22 +5,25 @@ namespace Nest { [JsonConverter(typeof(MultiPercolateJsonConverter))] - public partial interface IMultiPercolateRequest + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with multi search api")] + public partial interface IMultiPercolateRequest { IList Percolations { get; set; } } - public partial class MultiPercolateRequest + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with multi search api")] + public partial class MultiPercolateRequest { public IList Percolations { get; set; } } [DescriptorFor("Mpercolate")] - public partial class MultiPercolateDescriptor + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with multi search api")] + public partial class MultiPercolateDescriptor { IList IMultiPercolateRequest.Percolations { get; set; } = new SynchronizedCollection(); - public MultiPercolateDescriptor Percolate(Func, IPercolateOperation> percolateSelector) + public MultiPercolateDescriptor Percolate(Func, IPercolateOperation> percolateSelector) where T : class { var percolation = percolateSelector.InvokeOrDefault((new PercolateDescriptor(typeof(T), typeof(T)))); @@ -39,7 +42,7 @@ public MultiPercolateDescriptor PercolateMany(IEnumerable sources, Func(Func, IPercolateOperation> countSelector) + public MultiPercolateDescriptor Count(Func, IPercolateOperation> countSelector) where T : class { var percolation = countSelector.InvokeOrDefault(new PercolateCountDescriptor(typeof(T), typeof(T))); diff --git a/src/Nest/Search/Percolator/MultiPercolate/MultiPercolateResponse.cs b/src/Nest/Search/Percolator/MultiPercolate/MultiPercolateResponse.cs index db40785a4b6..db04567d219 100644 --- a/src/Nest/Search/Percolator/MultiPercolate/MultiPercolateResponse.cs +++ b/src/Nest/Search/Percolator/MultiPercolate/MultiPercolateResponse.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Text; using Elasticsearch.Net; @@ -7,12 +8,14 @@ namespace Nest { [JsonObject(MemberSerialization.OptIn)] + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with multi search api")] public interface IMultiPercolateResponse : IResponse { IEnumerable Responses { get; } } [JsonObject(MemberSerialization.OptIn)] + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with multi search api")] public class MultiPercolateResponse : ResponseBase, IMultiPercolateResponse { public override bool IsValid => base.IsValid && this.Responses.All(r => r.IsValid); @@ -29,7 +32,7 @@ protected override void DebugIsValid(StringBuilder sb) IEnumerable IMultiPercolateResponse.Responses => this.Responses; - private IEnumerable _allResponses() + private IEnumerable _allResponses() { foreach (var r in this.AllResponses) { diff --git a/src/Nest/Search/Percolator/Percolate/ElasticClient-Percolate.cs b/src/Nest/Search/Percolator/Percolate/ElasticClient-Percolate.cs index 593d69a0fbe..2e75344b85d 100644 --- a/src/Nest/Search/Percolator/Percolate/ElasticClient-Percolate.cs +++ b/src/Nest/Search/Percolator/Percolate/ElasticClient-Percolate.cs @@ -8,22 +8,25 @@ public partial interface IElasticClient { /// /// Percolate a document - /// http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-percolate.html /// /// The type to infer the index/type from, and of the object that is being percolated /// An optional descriptor describing the percolate operation further + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with search api")] IPercolateResponse Percolate(Func, IPercolateRequest> selector) where T : class; /// + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with search api")] IPercolateResponse Percolate(IPercolateRequest request) where T : class; /// + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with search api")] Task PercolateAsync(Func, IPercolateRequest> selector) where T : class; /// + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with search api")] Task PercolateAsync(IPercolateRequest request) where T : class; } @@ -31,29 +34,33 @@ Task PercolateAsync(IPercolateRequest request) public partial class ElasticClient { /// + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with search api")] public IPercolateResponse Percolate(Func, IPercolateRequest> selector) where T : class => this.Percolate(selector?.Invoke(new PercolateDescriptor(typeof(T), typeof(T)))); /// + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with search api")] public IPercolateResponse Percolate(IPercolateRequest request) - where T : class => + where T : class => this.Dispatcher.Dispatch, PercolateRequestParameters, PercolateResponse>( request, this.LowLevelDispatch.PercolateDispatch ); /// + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with search api")] public Task PercolateAsync(Func, IPercolateRequest> selector) - where T : class => + where T : class => this.PercolateAsync(selector?.Invoke(new PercolateDescriptor(typeof(T), typeof(T)))); /// + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with search api")] public Task PercolateAsync(IPercolateRequest request) - where T : class => + where T : class => this.Dispatcher.DispatchAsync, PercolateRequestParameters, PercolateResponse, IPercolateResponse>( request, this.LowLevelDispatch.PercolateDispatchAsync ); } -} \ No newline at end of file +} diff --git a/src/Nest/Search/Percolator/Percolate/PercolateRequest.cs b/src/Nest/Search/Percolator/Percolate/PercolateRequest.cs index a652f0e55d4..1b6df3c6073 100644 --- a/src/Nest/Search/Percolator/Percolate/PercolateRequest.cs +++ b/src/Nest/Search/Percolator/Percolate/PercolateRequest.cs @@ -5,6 +5,7 @@ namespace Nest { + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with search api")] public partial interface IPercolateRequest : IPercolateOperation where TDocument : class { @@ -12,6 +13,7 @@ public partial interface IPercolateRequest : IPercolateOperation TDocument Document { get; set; } } + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with search api")] public partial class PercolateRequest where TDocument : class { @@ -23,12 +25,12 @@ public PercolateRequest(Id id) : this(typeof(TDocument), typeof(TDocument), id) public QueryContainer Query { get; set; } public QueryContainer Filter { get; set; } public AggregationDictionary Aggregations { get; set; } - + public int? Size { get; set; } /// - /// Whether the _score is included for each match. The _score is based on the query and represents - /// how the query matched the percolate query’s metadata, not how the document (that is being percolated) + /// Whether the _score is included for each match. The _score is based on the query and represents + /// how the query matched the percolate query’s metadata, not how the document (that is being percolated) /// matched the query. The option is required for this option. /// public bool? TrackScores { get; set; } @@ -39,10 +41,10 @@ public PercolateRequest(Id id) : this(typeof(TDocument), typeof(TDocument), id) public TDocument Document { get; set; } /// - /// Define a sort specification like in the search API. Currently only sorting _score reverse - /// (default relevancy) is supported. Other sort fields will throw an exception. - /// The and option are required for this setting. Like - /// the score is based on the query and represents how the query matched to the percolate query’s metadata + /// Define a sort specification like in the search API. Currently only sorting _score reverse + /// (default relevancy) is supported. Other sort fields will throw an exception. + /// The and option are required for this setting. Like + /// the score is based on the query and represents how the query matched to the percolate query’s metadata /// and not how the document being percolated matched to the query. /// public IList Sort { get; set; } @@ -57,6 +59,7 @@ partial void DocumentFromPath(TDocument document) } } + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with search api")] public partial class PercolateDescriptor : IPercolateRequest where TDocument : class { @@ -68,7 +71,7 @@ public partial class PercolateDescriptor : IPercolateRequest.Document { get; set; } IList IPercolateOperation.Sort { get; set; } AggregationDictionary IPercolateOperation.Aggregations { get; set; } @@ -76,13 +79,13 @@ public partial class PercolateDescriptor : IPercolateRequest "percolate"; /// - /// The object to perculate + /// The object to percolate /// public PercolateDescriptor Document(TDocument @object) => Assign(a => a.Document = @object); /// - /// Whether the _score is included for each match. The _score is based on the query and represents - /// how the query matched the percolate query’s metadata, not how the document (that is being percolated) + /// Whether the _score is included for each match. The _score is based on the query and represents + /// how the query matched the percolate query’s metadata, not how the document (that is being percolated) /// matched the query. The option is required for this option. /// public PercolateDescriptor TrackScores(bool? trackScores = true) => Assign(a => a.TrackScores = trackScores); @@ -91,7 +94,7 @@ public PercolateDescriptor Aggregations(Func a.Aggregations = aggregationsSelector(new AggregationContainerDescriptor())?.Aggregations); /// - /// Allow to highlight search results on one or more fields. + /// Allow to highlight search results on one or more fields. /// public PercolateDescriptor Highlight(Func, IHighlight> highlightDescriptor) => Assign(a => a.Highlight = highlightDescriptor?.Invoke(new HighlightDescriptor())); @@ -99,10 +102,10 @@ public PercolateDescriptor Highlight(Func Size(int? size) => Assign(a => a.Size = size); /// - /// Define a sort specification like in the search API. Currently only sorting _score reverse - /// (default relevancy) is supported. Other sort fields will throw an exception. - /// The and option are required for this setting. Like - /// the score is based on the query and represents how the query matched to the percolate query’s metadata + /// Define a sort specification like in the search API. Currently only sorting _score reverse + /// (default relevancy) is supported. Other sort fields will throw an exception. + /// The and option are required for this setting. Like + /// the score is based on the query and represents how the query matched to the percolate query’s metadata /// and not how the document being percolated matched to the query. /// public PercolateDescriptor Sort(Func, IPromise>> selector) => Assign(a => a.Sort = selector?.Invoke(new SortDescriptor())?.Value); diff --git a/src/Nest/Search/Percolator/Percolate/PercolateResponse.cs b/src/Nest/Search/Percolator/Percolate/PercolateResponse.cs index 03ea72d3fda..0954d59f00f 100644 --- a/src/Nest/Search/Percolator/Percolate/PercolateResponse.cs +++ b/src/Nest/Search/Percolator/Percolate/PercolateResponse.cs @@ -1,21 +1,25 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Elasticsearch.Net; using Newtonsoft.Json; namespace Nest { + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with search api")] public interface IPercolateCountResponse : IResponse { int Took { get; } long Total { get; } } + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with search api")] public interface IPercolateResponse : IPercolateCountResponse { IEnumerable Matches { get; } } [JsonObject] + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with search api")] public class PercolateCountResponse : ResponseBase, IPercolateCountResponse { [JsonProperty(PropertyName = "took")] @@ -23,10 +27,10 @@ public class PercolateCountResponse : ResponseBase, IPercolateCountResponse [JsonProperty(PropertyName = "total")] public long Total { get; internal set; } - + [JsonProperty(PropertyName = "_shards")] public ShardsMetaData Shards { get; internal set; } - + /// /// The individual error for separate requests on the _mpercolate API /// @@ -37,6 +41,7 @@ public class PercolateCountResponse : ResponseBase, IPercolateCountResponse } [JsonObject] + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with search api")] public class PercolateResponse : PercolateCountResponse, IPercolateResponse { @@ -44,6 +49,7 @@ public class PercolateResponse : PercolateCountResponse, IPercolateResponse public IEnumerable Matches { get; internal set; } } + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with search api")] public class PercolatorMatch { [JsonProperty(PropertyName = "highlight")] @@ -58,5 +64,4 @@ public class PercolatorMatch [JsonProperty(PropertyName = "_score")] public double Score { get; set; } } - -} \ No newline at end of file +} diff --git a/src/Nest/Search/Percolator/PercolateCount/ElasticClient-PercolateCount.cs b/src/Nest/Search/Percolator/PercolateCount/ElasticClient-PercolateCount.cs index 5757d64ad24..cfc59940483 100644 --- a/src/Nest/Search/Percolator/PercolateCount/ElasticClient-PercolateCount.cs +++ b/src/Nest/Search/Percolator/PercolateCount/ElasticClient-PercolateCount.cs @@ -7,17 +7,21 @@ namespace Nest public partial interface IElasticClient { /// + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with search api")] IPercolateCountResponse PercolateCount(Func, IPercolateCountRequest> selector = null) where T : class; /// + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with search api")] IPercolateCountResponse PercolateCount(IPercolateCountRequest request) where T : class; + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with search api")] Task PercolateCountAsync(Func, IPercolateCountRequest> selector = null) where T : class; /// + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with search api")] Task PercolateCountAsync(IPercolateCountRequest request) where T : class; } @@ -26,29 +30,33 @@ public partial class ElasticClient { /// + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with search api")] public IPercolateCountResponse PercolateCount(Func, IPercolateCountRequest> selector = null) where T : class => this.PercolateCount(selector?.Invoke(new PercolateCountDescriptor(typeof(T), typeof(T)))); /// + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with search api")] public IPercolateCountResponse PercolateCount(IPercolateCountRequest request) - where T : class => + where T : class => this.Dispatcher.Dispatch, PercolateCountRequestParameters, PercolateCountResponse>( request, this.LowLevelDispatch.CountPercolateDispatch ); /// + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with search api")] public Task PercolateCountAsync(Func, IPercolateCountRequest> selector = null) - where T : class => + where T : class => this.PercolateCountAsync(selector?.Invoke(new PercolateCountDescriptor(typeof(T), typeof(T)))); /// + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with search api")] public Task PercolateCountAsync(IPercolateCountRequest request) - where T : class => + where T : class => this.Dispatcher.DispatchAsync, PercolateCountRequestParameters, PercolateCountResponse, IPercolateCountResponse>( request, this.LowLevelDispatch.CountPercolateDispatchAsync ); } -} \ No newline at end of file +} diff --git a/src/Nest/Search/Percolator/PercolateCount/PercolateCountRequest.cs b/src/Nest/Search/Percolator/PercolateCount/PercolateCountRequest.cs index 4cdc1893b73..3faad7766bd 100644 --- a/src/Nest/Search/Percolator/PercolateCount/PercolateCountRequest.cs +++ b/src/Nest/Search/Percolator/PercolateCount/PercolateCountRequest.cs @@ -5,6 +5,7 @@ namespace Nest { + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with search api")] public partial interface IPercolateCountRequest : IPercolateOperation where TDocument : class { @@ -12,6 +13,7 @@ public partial interface IPercolateCountRequest : IPercolateOperation TDocument Document { get; set; } } + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with search api")] public partial class PercolateCountRequest where TDocument : class { public string MultiPercolateName => "count"; @@ -42,6 +44,7 @@ IRequestParameters IPercolateOperation.GetRequestParameters() } [DescriptorFor("CountPercolate")] + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with search api")] public partial class PercolateCountDescriptor : IPercolateCountRequest where TDocument : class { @@ -59,7 +62,7 @@ public partial class PercolateCountDescriptor : IPercolateCountReques string IPercolateOperation.MultiPercolateName => "count"; - IRequestParameters IPercolateOperation.GetRequestParameters() => + IRequestParameters IPercolateOperation.GetRequestParameters() => this.Self.RequestParameters; /// diff --git a/src/Nest/Search/Percolator/RegisterPercolator/ElasticClient-RegisterPecolator.cs b/src/Nest/Search/Percolator/RegisterPercolator/ElasticClient-RegisterPecolator.cs index 980580e3987..b1d096d7ed2 100644 --- a/src/Nest/Search/Percolator/RegisterPercolator/ElasticClient-RegisterPecolator.cs +++ b/src/Nest/Search/Percolator/RegisterPercolator/ElasticClient-RegisterPecolator.cs @@ -8,49 +8,56 @@ public partial interface IElasticClient { /// /// Register a percolator - /// http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-percolate.html /// /// The type to infer the index/type from, will also be used to strongly type the query /// The name for the percolator /// An optional descriptor describing the register percolator operation further + [Obsolete("Deprecated. Will be removed in the next major release. Index a document containing a field mapped with percolator type")] IRegisterPercolatorResponse RegisterPercolator(Name name, Func, IRegisterPercolatorRequest> selector) where T : class; /// + [Obsolete("Deprecated. Will be removed in the next major release. Index a document containing a field mapped with percolator type")] IRegisterPercolatorResponse RegisterPercolator(IRegisterPercolatorRequest request); /// + [Obsolete("Deprecated. Will be removed in the next major release. Index a document containing a field mapped with percolator type")] Task RegisterPercolatorAsync(Name name, Func, IRegisterPercolatorRequest> selector) where T : class; /// + [Obsolete("Deprecated. Will be removed in the next major release. Index a document containing a field mapped with percolator type")] Task RegisterPercolatorAsync(IRegisterPercolatorRequest request); } public partial class ElasticClient { /// + [Obsolete("Deprecated. Will be removed in the next major release. Index a document containing a field mapped with percolator type")] public IRegisterPercolatorResponse RegisterPercolator(Name name, Func, IRegisterPercolatorRequest> selector) where T : class => this.RegisterPercolator(selector.InvokeOrDefault(new RegisterPercolatorDescriptor(name))); /// - public IRegisterPercolatorResponse RegisterPercolator(IRegisterPercolatorRequest request) => + [Obsolete("Deprecated. Will be removed in the next major release. Index a document containing a field mapped with percolator type")] + public IRegisterPercolatorResponse RegisterPercolator(IRegisterPercolatorRequest request) => this.Dispatcher.Dispatch( request, this.LowLevelDispatch.IndexDispatch ); /// + [Obsolete("Deprecated. Will be removed in the next major release. Index a document containing a field mapped with percolator type")] public Task RegisterPercolatorAsync(Name name, Func, IRegisterPercolatorRequest> selector) - where T : class => + where T : class => this.RegisterPercolatorAsync(selector.InvokeOrDefault(new RegisterPercolatorDescriptor(name))); /// - public Task RegisterPercolatorAsync(IRegisterPercolatorRequest request) => + [Obsolete("Deprecated. Will be removed in the next major release. Index a document containing a field mapped with percolator type")] + public Task RegisterPercolatorAsync(IRegisterPercolatorRequest request) => this.Dispatcher.DispatchAsync( request, this.LowLevelDispatch.IndexDispatchAsync ); } -} \ No newline at end of file +} diff --git a/src/Nest/Search/Percolator/RegisterPercolator/RegisterPercolatorJsonConverter.cs b/src/Nest/Search/Percolator/RegisterPercolator/RegisterPercolatorJsonConverter.cs index d9f7c5e59bf..0f9fdac0ea3 100644 --- a/src/Nest/Search/Percolator/RegisterPercolator/RegisterPercolatorJsonConverter.cs +++ b/src/Nest/Search/Percolator/RegisterPercolator/RegisterPercolatorJsonConverter.cs @@ -7,6 +7,7 @@ namespace Nest { + [Obsolete("Deprecated. Will be removed in the next major release. Index a document with a percolator type")] internal class RegisterPercolatorJsonConverter : JsonConverter { public override bool CanConvert(Type objectType) => objectType == typeof(IRegisterPercolatorRequest); diff --git a/src/Nest/Search/Percolator/RegisterPercolator/RegisterPercolatorRequest.cs b/src/Nest/Search/Percolator/RegisterPercolator/RegisterPercolatorRequest.cs index 05d81a439f7..d1d71c3b2e6 100644 --- a/src/Nest/Search/Percolator/RegisterPercolator/RegisterPercolatorRequest.cs +++ b/src/Nest/Search/Percolator/RegisterPercolator/RegisterPercolatorRequest.cs @@ -9,13 +9,15 @@ namespace Nest [JsonObject(MemberSerialization = MemberSerialization.OptIn)] [JsonConverter(typeof(RegisterPercolatorJsonConverter))] - public interface IRegisterPercolatorRequest : IRequest + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with search api")] + public interface IRegisterPercolatorRequest : IRequest { IDictionary Metadata { get; set; } QueryContainer Query { get; set; } } + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with search api")] public class RegisterPercolatorRequest : RequestBase, IRegisterPercolatorRequest { internal RegisterPercolatorRequest() { } @@ -23,17 +25,18 @@ internal RegisterPercolatorRequest() { } public IDictionary Metadata { get; set; } public QueryContainer Query { get; set; } - public RegisterPercolatorRequest(IndexName index, Name name) + public RegisterPercolatorRequest(IndexName index, Name name) : base(r=>r.Required("index", index).Required("type", (TypeName)".percolator").Required("id", name)) { } } - public class RegisterPercolatorDescriptor + [Obsolete("Deprecated. Will be removed in the next major release. Use a percolate query with search api")] + public class RegisterPercolatorDescriptor : RequestDescriptorBase, IndexRequestParameters, IRegisterPercolatorRequest>, IRegisterPercolatorRequest where T : class { internal RegisterPercolatorDescriptor() { } - public RegisterPercolatorDescriptor(Name name) + public RegisterPercolatorDescriptor(Name name) : base(r=>r.Required("index", (IndexName)typeof(T)).Required("type", (TypeName)".percolator").Required("id", name)) { } public RegisterPercolatorDescriptor Index(IndexName index) => Assign(a => a.RouteValues.Required("index", index)); diff --git a/src/Nest/Search/Percolator/RegisterPercolator/RegisterPercolatorResponse.cs b/src/Nest/Search/Percolator/RegisterPercolator/RegisterPercolatorResponse.cs index a7179c1a67b..e1e9a1f8673 100644 --- a/src/Nest/Search/Percolator/RegisterPercolator/RegisterPercolatorResponse.cs +++ b/src/Nest/Search/Percolator/RegisterPercolator/RegisterPercolatorResponse.cs @@ -1,7 +1,9 @@ -using Newtonsoft.Json; +using System; +using Newtonsoft.Json; namespace Nest { + [Obsolete("Deprecated. Will be removed in the next major release. Index a document containing a field mapped with percolator type")] public interface IRegisterPercolatorResponse : IResponse { bool Created { get; } @@ -12,6 +14,7 @@ public interface IRegisterPercolatorResponse : IResponse } [JsonObject] + [Obsolete("Deprecated. Will be removed in the next major release. Index a document containing a field mapped with percolator type")] public class RegisterPercolatorResponse : ResponseBase, IRegisterPercolatorResponse { [JsonProperty(PropertyName = "created")] diff --git a/src/Nest/Search/Percolator/UnregisterPercolator/ElasticClient-UnregisterPercolator.cs b/src/Nest/Search/Percolator/UnregisterPercolator/ElasticClient-UnregisterPercolator.cs index a27f552b997..9c0b4e5a436 100644 --- a/src/Nest/Search/Percolator/UnregisterPercolator/ElasticClient-UnregisterPercolator.cs +++ b/src/Nest/Search/Percolator/UnregisterPercolator/ElasticClient-UnregisterPercolator.cs @@ -8,49 +8,55 @@ public partial interface IElasticClient { /// /// Unregister a percolator - /// http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-percolate.html /// /// The name for the percolator /// An optional descriptor describing the unregister percolator operation further + [Obsolete("Deprecated. Will be removed in the next major release. Index a document containing a field mapped with percolator type")] IUnregisterPercolatorResponse UnregisterPercolator(Name name, Func, IUnregisterPercolatorRequest> selector = null) where T : class; /// + [Obsolete("Deprecated. Will be removed in the next major release. Index a document containing a field mapped with percolator type")] IUnregisterPercolatorResponse UnregisterPercolator(IUnregisterPercolatorRequest request); /// + [Obsolete("Deprecated. Will be removed in the next major release. Index a document containing a field mapped with percolator type")] Task UnregisterPercolatorAsync(Name name, Func, IUnregisterPercolatorRequest> selector = null) where T : class; /// + [Obsolete("Deprecated. Will be removed in the next major release. Index a document containing a field mapped with percolator type")] Task UnregisterPercolatorAsync(IUnregisterPercolatorRequest request); } public partial class ElasticClient { - /// + [Obsolete("Deprecated. Will be removed in the next major release. Index a document containing a field mapped with percolator type")] public IUnregisterPercolatorResponse UnregisterPercolator(Name name, Func, IUnregisterPercolatorRequest> selector = null) where T : class => this.UnregisterPercolator(selector.InvokeOrDefault(new UnregisterPercolatorDescriptor(name))); /// - public IUnregisterPercolatorResponse UnregisterPercolator(IUnregisterPercolatorRequest request) => + [Obsolete("Deprecated. Will be removed in the next major release. Index a document containing a field mapped with percolator type")] + public IUnregisterPercolatorResponse UnregisterPercolator(IUnregisterPercolatorRequest request) => this.Dispatcher.Dispatch( request, (p, d) => this.LowLevelDispatch.DeleteDispatch(p) ); /// + [Obsolete("Deprecated. Will be removed in the next major release. Index a document containing a field mapped with percolator type")] public Task UnregisterPercolatorAsync(Name name, Func, IUnregisterPercolatorRequest> selector = null) - where T : class => + where T : class => this.UnregisterPercolatorAsync(selector.InvokeOrDefault(new UnregisterPercolatorDescriptor(name))); /// - public Task UnregisterPercolatorAsync(IUnregisterPercolatorRequest request) => + [Obsolete("Deprecated. Will be removed in the next major release. Index a document containing a field mapped with percolator type")] + public Task UnregisterPercolatorAsync(IUnregisterPercolatorRequest request) => this.Dispatcher.DispatchAsync( request, (p, d) => this.LowLevelDispatch.DeleteDispatchAsync(p) ); } -} \ No newline at end of file +} diff --git a/src/Nest/Search/Percolator/UnregisterPercolator/UnregisterPercolatorRequest.cs b/src/Nest/Search/Percolator/UnregisterPercolator/UnregisterPercolatorRequest.cs index d062bda3626..e4b856010de 100644 --- a/src/Nest/Search/Percolator/UnregisterPercolator/UnregisterPercolatorRequest.cs +++ b/src/Nest/Search/Percolator/UnregisterPercolator/UnregisterPercolatorRequest.cs @@ -1,20 +1,24 @@ -using Elasticsearch.Net; +using System; +using Elasticsearch.Net; namespace Nest { + [Obsolete("Deprecated. Will be removed in the next major release. Index a document containing a field mapped with percolator type")] public interface IUnregisterPercolatorRequest : IRequest { } + [Obsolete("Deprecated. Will be removed in the next major release. Index a document containing a field mapped with percolator type")] public class UnregisterPercolatorRequest : RequestBase, IUnregisterPercolatorRequest { - public UnregisterPercolatorRequest(IndexName index, Name name) + public UnregisterPercolatorRequest(IndexName index, Name name) : base(r=>r.Required("index", index).Required("type", (TypeName)".percolator").Required("id", name)) { } } + [Obsolete("Deprecated. Will be removed in the next major release. Index a document containing a field mapped with percolator type")] public class UnregisterPercolatorDescriptor : RequestDescriptorBase, DeleteRequestParameters, IUnregisterPercolatorRequest>, IUnregisterPercolatorRequest where T : class { - public UnregisterPercolatorDescriptor(Name name) + public UnregisterPercolatorDescriptor(Name name) : base(r=>r.Required("index", (IndexName)typeof(T)).Required("type", (TypeName)".percolator").Required("id", name)) { } public UnregisterPercolatorDescriptor Index(IndexName index) => Assign(a => a.RouteValues.Required("index", index)); diff --git a/src/Nest/Search/Percolator/UnregisterPercolator/UnregisterPercolatorResponse.cs b/src/Nest/Search/Percolator/UnregisterPercolator/UnregisterPercolatorResponse.cs index b37290cde2a..ae2d949d7fa 100644 --- a/src/Nest/Search/Percolator/UnregisterPercolator/UnregisterPercolatorResponse.cs +++ b/src/Nest/Search/Percolator/UnregisterPercolator/UnregisterPercolatorResponse.cs @@ -1,7 +1,9 @@ -using Newtonsoft.Json; +using System; +using Newtonsoft.Json; namespace Nest { + [Obsolete("Deprecated. Will be removed in the next major release. Index a document containing a field mapped with percolator type")] public interface IUnregisterPercolatorResponse : IResponse { bool Found { get; } @@ -12,6 +14,7 @@ public interface IUnregisterPercolatorResponse : IResponse } [JsonObject] + [Obsolete("Deprecated. Will be removed in the next major release. Index a document containing a field mapped with percolator type")] public class UnregisterPercolatorResponse : ResponseBase, IUnregisterPercolatorResponse { [JsonProperty(PropertyName = "found")] diff --git a/src/Tests/Framework/ApiTestBase.cs b/src/Tests/Framework/ApiTestBase.cs index c6431cd16d3..d9bfc574359 100644 --- a/src/Tests/Framework/ApiTestBase.cs +++ b/src/Tests/Framework/ApiTestBase.cs @@ -89,7 +89,6 @@ Func> requestAsync this._usage.CalledSetup = true; } - var dict = new Dictionary(); _uniqueValues.CurrentView = ClientMethod.Fluent; diff --git a/src/Tests/Framework/Integration/Bootstrappers/Seeder.cs b/src/Tests/Framework/Integration/Bootstrappers/Seeder.cs index 3b2cd9df227..a3f0a392c7f 100644 --- a/src/Tests/Framework/Integration/Bootstrappers/Seeder.cs +++ b/src/Tests/Framework/Integration/Bootstrappers/Seeder.cs @@ -39,7 +39,9 @@ public void DeleteIndicesAndTemplates() if (this.Client.IndexExists(Indices()).Exists) this.Client.DeleteIndex(typeof(Project)); if (this.Client.IndexExists(Indices()).Exists) - this.Client.DeleteIndex(typeof(Developer)); + this.Client.DeleteIndex(typeof(Developer)); + if (this.Client.IndexExists(Indices()).Exists) + this.Client.DeleteIndex(typeof(PercolatedQuery)); } public void CreateIndices() @@ -47,13 +49,19 @@ public void CreateIndices() CreateIndexTemplate(); CreateProjectIndex(); CreateDeveloperIndex(); + CreatePercolatorIndex(); } private void SeedIndexData() { this.Client.IndexMany(Project.Projects); this.Client.IndexMany(Developer.Developers); - this.Client.Refresh(Nest.Indices.Index().And()); + this.Client.Index(new PercolatedQuery + { + Id = "1", + Query = new QueryContainer(new MatchAllQuery()) + }); + this.Client.Refresh(Nest.Indices.Index(typeof(Project), typeof(Developer), typeof(PercolatedQuery))); } private void CreateIndicesAndSeedIndexData() @@ -138,6 +146,20 @@ private void CreateProjectIndex() createProjectIndex.IsValid.Should().BeTrue(); } + private void CreatePercolatorIndex() + { + var createPercolatedIndex = this.Client.CreateIndex(typeof(PercolatedQuery), c => c + .Mappings(map => map + .Map(m => m + .AutoMap() + .Properties(PercolatedQueryProperties) + ) + ) + ); + + createPercolatedIndex.IsValid.Should().BeTrue(); + } + public static PropertiesDescriptor ProjectProperties(PropertiesDescriptor props) => props .Keyword(s => s .Name(p => p.Name) @@ -226,5 +248,10 @@ private static PropertiesDescriptor DeveloperProperties(PropertiesDes .Name(p => p.Location) .LatLon() ); + + public static PropertiesDescriptor PercolatedQueryProperties(PropertiesDescriptor props) => props + .Percolator(pp => pp + .Name(n => n.Query) + ); } } diff --git a/src/Tests/Framework/MockData/PercolatedQuery.cs b/src/Tests/Framework/MockData/PercolatedQuery.cs new file mode 100644 index 00000000000..f66123f7fba --- /dev/null +++ b/src/Tests/Framework/MockData/PercolatedQuery.cs @@ -0,0 +1,11 @@ +using Nest; + +namespace Tests.Framework.MockData +{ + public class PercolatedQuery + { + public string Id { get; set; } + + public QueryContainer Query { get; set; } + } +} diff --git a/src/Tests/Framework/TestClient.cs b/src/Tests/Framework/TestClient.cs index 9c925d67a15..c45f6bb3feb 100644 --- a/src/Tests/Framework/TestClient.cs +++ b/src/Tests/Framework/TestClient.cs @@ -34,6 +34,11 @@ private static ConnectionSettings DefaultSettings(ConnectionSettings settings) = .Ignore(p => p.PrivateValue) .Rename(p => p.OnlineHandle, "nickname") ) + .InferMappingFor(map => map + .IndexName("queries") + // TODO: required to have this type name for 5.0.0-alpha1. Change for alpha2 + .TypeName(".percolator") + ) //We try and fetch the test name during integration tests when running fiddler to send the name //as the TestMethod header, this allows us to quickly identify which test sent which request .GlobalHeaders(new NameValueCollection diff --git a/src/Tests/Mapping/Types/Core/Percolator/PercolatorMappingTests.cs b/src/Tests/Mapping/Types/Core/Percolator/PercolatorMappingTests.cs new file mode 100644 index 00000000000..294fc93e434 --- /dev/null +++ b/src/Tests/Mapping/Types/Core/Percolator/PercolatorMappingTests.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Nest; + +namespace Tests.Mapping.Types.Core.Percolator +{ + public class PercolatorTest + { + [Percolator] + public QueryContainer Query { get; set; } + } + + public class PercolatorMappingTests : TypeMappingTestBase + { + protected override object ExpectJson => new + { + properties = new + { + query = new + { + type = "percolator" + } + } + }; + + protected override Func, IPromise> FluentProperties => p => p + .Percolator(s => s + .Name(o => o.Query) + ); + } +} diff --git a/src/Tests/Mapping/Types/Specialized/Attachment/AttachmentMappingTests.cs b/src/Tests/Mapping/Types/Specialized/Attachment/AttachmentMappingTests.cs index 7219f38c657..bc791c4436c 100644 --- a/src/Tests/Mapping/Types/Specialized/Attachment/AttachmentMappingTests.cs +++ b/src/Tests/Mapping/Types/Specialized/Attachment/AttachmentMappingTests.cs @@ -46,7 +46,6 @@ public class AttachmentMappingTests : TypeMappingTestBase d .Name(n => n.Language) - .DocValues() .Index(false) ) .NameField(d => d diff --git a/src/Tests/QueryDsl/Compound/FunctionScore/FunctionScoreQueryUsageTests.cs b/src/Tests/QueryDsl/Compound/FunctionScore/FunctionScoreQueryUsageTests.cs index 863f647b4ea..f7e65543ab1 100644 --- a/src/Tests/QueryDsl/Compound/FunctionScore/FunctionScoreQueryUsageTests.cs +++ b/src/Tests/QueryDsl/Compound/FunctionScore/FunctionScoreQueryUsageTests.cs @@ -8,6 +8,13 @@ namespace Tests.QueryDsl.Compound.FunctionScore { + /* + * The function_score allows you to modify the score of documents that are retrieved by a query. + * This can be useful if, for example, a score function is computationally expensive and it is + * sufficient to compute the score on a filtered set of documents. + * + * See the Elasticsearch documentation on {ref_current}/query-dsl-function-score-query.html[function score query] for more details. + */ public class FunctionScoreQueryUsageTests : QueryDslUsageTestsBase { public FunctionScoreQueryUsageTests(ReadOnlyCluster i, EndpointUsage usage) : base(i, usage) { } diff --git a/src/Tests/QueryDsl/QueryDslUsageTestsBase.cs b/src/Tests/QueryDsl/QueryDslUsageTestsBase.cs index a49b2cda8b7..685f4c5abb1 100644 --- a/src/Tests/QueryDsl/QueryDslUsageTestsBase.cs +++ b/src/Tests/QueryDsl/QueryDslUsageTestsBase.cs @@ -105,9 +105,6 @@ public void NullQueryDoesNotCauseANullReferenceException() query.ShouldNotThrow(); } - - private void IsConditionless(IQueryContainer q, bool be) => q.IsConditionless.Should().Be(be); - } public abstract class ConditionlessWhen : List> diff --git a/src/Tests/QueryDsl/Specialized/Percolate/PercolateQueryUsageTests.cs b/src/Tests/QueryDsl/Specialized/Percolate/PercolateQueryUsageTests.cs new file mode 100644 index 00000000000..f10ea964a34 --- /dev/null +++ b/src/Tests/QueryDsl/Specialized/Percolate/PercolateQueryUsageTests.cs @@ -0,0 +1,235 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Elasticsearch.Net; +using FluentAssertions; +using Nest; +using Tests.Framework; +using Tests.Framework.Integration; +using Tests.Framework.MockData; +using Xunit; + +namespace Tests.QueryDsl.Specialized.Percolate +{ + /** + * The percolate query can be used to match queries stored in an index. + * The percolate query itself contains the document that will be used as query to match with the stored queries. + * + * IMPORTANT: In order for the percolate query to work, the index in which your stored queries reside must contain + * a mapping for documents that you wish to percolate, so that they are parsed correctly at query time. + * + * See the Elasticsearch documentation on {ref_current}/query-dsl-percolate-query.html[percolate query] for more details. + * + * In this example, we have a document stored with a `query` field that is mapped as a `percolator` type. This field + * contains a `match` query. + */ + [Collection(IntegrationContext.Indexing)] + public class PercolateQueryUsageTests : ApiIntegrationTestBase, ISearchRequest, SearchDescriptor, SearchRequest> + { + private static readonly string PercolatorId = RandomString(); + + protected override LazyResponses ClientUsage() => Calls( + fluent: (client, f) => client.Search(f), + fluentAsync: (client, f) => client.SearchAsync(f), + request: (client, r) => client.Search(r), + requestAsync: (client, r) => client.SearchAsync(r) + ); + + protected override string UrlPath => $"{this.CallIsolatedValue}/_search"; + protected override int ExpectStatusCode => 200; + protected override bool ExpectIsValid => true; + protected override HttpMethod HttpMethod => HttpMethod.POST; + + public PercolateQueryUsageTests(IndexingCluster i, EndpointUsage usage) : base(i, usage) { } + + protected override void IntegrationSetup(IElasticClient client, CallUniqueValues values) + { + foreach (var index in values.Values) + { + this.Client.CreateIndex(index, c => c + .Mappings(m => m + .Map(mm => mm.AutoMap() + .Properties(Seeder.ProjectProperties) + ) + .Map(mm => mm.AutoMap() + .Properties(Seeder.PercolatedQueryProperties) + ) + ) + ); + + this.Client.Index(new PercolatedQuery + { + Id = PercolatorId, + Query = new QueryContainer(new MatchQuery + { + Field = Infer.Field(f => f.LeadDeveloper.FirstName), + Query = "Martijn" + }) + }, d => d.Index(index)); + + this.Client.Refresh(index); + } + } + + protected object QueryJson => new + { + percolator = new + { + document_type = "project", + document = Project.InstanceAnonymous + } + }; + + protected override Func, ISearchRequest> Fluent => f => + f.Query(QueryFluent).Index(CallIsolatedValue).AllTypes(); + + protected override SearchRequest Initializer => + new SearchRequest(CallIsolatedValue, Types.All) + { + Query = this.QueryInitializer + }; + + protected QueryContainer QueryInitializer => new PercolateQuery + { + DocumentType = typeof(Project), + Document = Project.Instance, + }; + + protected QueryContainer QueryFluent(QueryContainerDescriptor q) => q + .Percolate(p => p + .DocumentType(typeof(Project)) + .Document(Project.Instance) + ); + + protected override void ExpectResponse(ISearchResponse response) + { + response.Total.Should().BeGreaterThan(0); + response.Hits.Should().NotBeNull(); + response.Hits.Count().Should().BeGreaterThan(0); + var match = response.Documents.First(); + match.Id.Should().Be(PercolatorId); + ((IQueryContainer)match.Query).Match.Should().NotBeNull(); + } + + protected ConditionlessWhen ConditionlessWhen => new ConditionlessWhen(a => a.Percolate) + { + q => { + q.DocumentType = null; + }, + q => { + q.Document = null; + } + }; + } + + /**[float] + * == Percolate an existing document + * Instead of specifying a the source of the document being percolated, the source can also be + * retrieved from an already stored document. The percolate query will then internally execute a get request to fetch that document. + * + * The required fields to percolate an existing document are: + * - `index` in which the document resides + * - `type` of the document + * - `id` of the document + * - `document_type` type / mapping of the document + * + * See the Elasticsearch documentation on {ref_current}/query-dsl-percolate-query.html[percolate query] for more details. + */ + [Collection(IntegrationContext.Indexing)] + public class PercolateQueryExistingDocumentUsageTests : ApiIntegrationTestBase, ISearchRequest, SearchDescriptor, SearchRequest> + { + private static readonly string PercolatorId = RandomString(); + + protected override LazyResponses ClientUsage() => Calls( + fluent: (client, f) => client.Search(f), + fluentAsync: (client, f) => client.SearchAsync(f), + request: (client, r) => client.Search(r), + requestAsync: (client, r) => client.SearchAsync(r) + ); + + protected override string UrlPath => $"{this.CallIsolatedValue}/_search"; + protected override int ExpectStatusCode => 200; + protected override bool ExpectIsValid => true; + protected override HttpMethod HttpMethod => HttpMethod.POST; + + public PercolateQueryExistingDocumentUsageTests(IndexingCluster i, EndpointUsage usage) : base(i, usage) { } + + protected override void IntegrationSetup(IElasticClient client, CallUniqueValues values) + { + foreach (var index in values.Values) + { + this.Client.CreateIndex(index, c => c + .Mappings(m => m + .Map(mm => mm.AutoMap() + .Properties(Seeder.ProjectProperties) + ) + .Map(mm => mm.AutoMap() + .Properties(Seeder.PercolatedQueryProperties) + ) + ) + ); + + this.Client.Index(new PercolatedQuery + { + Id = PercolatorId, + Query = new QueryContainer(new MatchQuery + { + Field = Infer.Field(f => f.LeadDeveloper.FirstName), + Query = "Martijn" + }) + }, d => d.Index(index)); + + this.Client.Index(Project.Instance); + this.Client.Refresh(Nest.Indices.Index(index).And()); + } + } + + protected object QueryJson => new + { + percolator = new + { + type = "project", + index = "project", + id = Project.Instance.Name, + document_type = "project" + } + }; + + protected override Func, ISearchRequest> Fluent => f => + f.Query(QueryFluent).Index(CallIsolatedValue).AllTypes(); + + protected override SearchRequest Initializer => + new SearchRequest(CallIsolatedValue, Types.All) + { + Query = this.QueryInitializer + }; + + protected QueryContainer QueryInitializer => new PercolateQuery + { + Type = typeof(Project), + Index = IndexName.From(), + Id = Project.Instance.Name, + DocumentType = typeof(Project) + }; + + protected QueryContainer QueryFluent(QueryContainerDescriptor q) => q + .Percolate(p => p + .Type() + .Index() + .Id(Project.Instance.Name) + .DocumentType() // <1> specify the `type`, `index`, `id` and `document_type` of the document to fetch, to percolate. + ); + + protected override void ExpectResponse(ISearchResponse response) + { + response.Total.Should().BeGreaterThan(0); + response.Hits.Should().NotBeNull(); + response.Hits.Count().Should().BeGreaterThan(0); + var match = response.Documents.First(); + match.Id.Should().Be(PercolatorId); + ((IQueryContainer)match.Query).Match.Should().NotBeNull(); + } + } +} diff --git a/src/Tests/Search/MultiSearch/MultiSearchApiTests.cs b/src/Tests/Search/MultiSearch/MultiSearchApiTests.cs index 1738c1efcaf..410920be2ef 100644 --- a/src/Tests/Search/MultiSearch/MultiSearchApiTests.cs +++ b/src/Tests/Search/MultiSearch/MultiSearchApiTests.cs @@ -40,7 +40,12 @@ protected override LazyResponses ClientUsage() => Calls( new { index = "devs", type = "developer" }, new { from = 0, size = 5, query = new { match_all = new {} } }, new { index = "devs", type = "developer" }, - new { from = 0, size = 5, query = new { match_all = new {} } } + new { from = 0, size = 5, query = new { match_all = new {} } }, + new { index = "queries", type = ".percolator" }, + // TODO: Remove .percolator type in 5.0.0-alpha2 + new { query = new { percolator = new { document_type = "project", document = Project.InstanceAnonymous } } }, + new { index = "queries", type = ".percolator" }, + new { query = new { percolator = new { index = "project", type = "project", id = Project.Projects.First().Name, version = 1, document_type = "project" } } }, }; protected override Func Fluent => ms => ms @@ -49,7 +54,26 @@ protected override LazyResponses ClientUsage() => Calls( .Search("10projects",s => s.Query(q => q.MatchAll()).From(0).Size(10)) .Search("dfs_projects", s => s.SearchType(SearchType.DfsQueryThenFetch)) .Search("5developers", s => s.Query(q => q.MatchAll()).From(0).Size(5)) - .Search("infer_type_name", s => s.Index("devs").From(0).Size(5).MatchAll()); + .Search("infer_type_name", s => s.Index("devs").From(0).Size(5).MatchAll()) + .Search("percolate_document", s => s + .Index().Type(".percolator").Query(q => q + .Percolate(p => p + .DocumentType() + .Document(Project.Instance) + ) + ) + ) + .Search("percolate_existing_document", s => s + .Index().Type(".percolator").Query(q => q + .Percolate(p => p + .Index() + .Type() + .Id(Project.Projects.First().Name) + .Version(1) + .DocumentType() + ) + ) + ); protected override MultiSearchRequest Initializer => new MultiSearchRequest(typeof(Project), typeof(Project)) { @@ -58,19 +82,40 @@ protected override LazyResponses ClientUsage() => Calls( { "10projects", new SearchRequest { From = 0, Size = 10, Query = new QueryContainer(new MatchAllQuery()) } }, { "dfs_projects", new SearchRequest { SearchType = SearchType.DfsQueryThenFetch} }, { "5developers", new SearchRequest { From = 0, Size = 5, Query = new QueryContainer(new MatchAllQuery()) } }, - { "infer_type_name", new SearchRequest("devs") { From = 0, Size = 5, Query = new QueryContainer(new MatchAllQuery()) } }, + { "infer_type_name", new SearchRequest("devs") { From = 0, Size = 5, Query = new QueryContainer(new MatchAllQuery()) } }, + { "percolate_document", new SearchRequest(typeof(PercolatedQuery), ".percolator") + { + Query = new QueryContainer(new PercolateQuery + { + DocumentType = typeof(Project), + Document = Project.Instance + }) + } + }, + { "percolate_existing_document", new SearchRequest(typeof(PercolatedQuery), ".percolator") + { + Query = new QueryContainer(new PercolateQuery + { + Index = typeof(Project), + Type = typeof(Project), + Id = Project.Projects.First().Name, + Version = 1, + DocumentType = typeof(Project) + }) + } + }, } }; [I] public Task AssertResponse() => AssertOnAllResponses(r => { - r.TotalResponses.Should().Be(4); + r.TotalResponses.Should().Be(6); var invalidResponses = r.GetInvalidResponses(); invalidResponses.Should().BeEmpty(); var allResponses = r.AllResponses.ToList(); - allResponses.Should().NotBeEmpty().And.HaveCount(4).And.OnlyContain(rr => rr.IsValid); + allResponses.Should().NotBeEmpty().And.HaveCount(6).And.OnlyContain(rr => rr.IsValid); var projects= r.GetResponse("10projects"); projects.IsValid.Should().BeTrue(); @@ -86,7 +131,15 @@ [I] public Task AssertResponse() => AssertOnAllResponses(r => var inferredTypeName = r.GetResponse("infer_type_name"); inferredTypeName.IsValid.Should().BeTrue(); - inferredTypeName.Documents.Should().HaveCount(5); + inferredTypeName.Documents.Should().HaveCount(5); + + var percolateDocument = r.GetResponse("percolate_document"); + percolateDocument.IsValid.Should().BeTrue(); + percolateDocument.Documents.Should().HaveCount(1); + + var percolateExistingDocument = r.GetResponse("percolate_existing_document"); + percolateExistingDocument.IsValid.Should().BeTrue(); + percolateExistingDocument.Documents.Should().HaveCount(1); }); } } diff --git a/src/Tests/Search/Percolator/MultiPercolate/MultiPercolateApiTests.cs b/src/Tests/Search/Percolator/MultiPercolate/MultiPercolateApiTests.cs index 37fb38177b2..dd46d9db366 100644 --- a/src/Tests/Search/Percolator/MultiPercolate/MultiPercolateApiTests.cs +++ b/src/Tests/Search/Percolator/MultiPercolate/MultiPercolateApiTests.cs @@ -7,8 +7,10 @@ using Tests.Framework; using Tests.Framework.Integration; using Tests.Framework.MockData; -using Xunit; - +using Xunit; + +#pragma warning disable 618 // testing deprecated percolate APIs + namespace Tests.Search.Percolator.MultiPercolate { [Collection(IntegrationContext.Indexing)] @@ -31,6 +33,8 @@ protected override void OnBeforeCall(IElasticClient client) .Index(this.Index) .Query(q => q.MatchAll()) ); + + this.Client.Refresh(this.Index); } protected override LazyResponses ClientUsage() => Calls( diff --git a/src/Tests/Search/Percolator/MultiPercolate/MultiPercolateInvalidApiTests.cs b/src/Tests/Search/Percolator/MultiPercolate/MultiPercolateInvalidApiTests.cs index abe668664cd..cf8dbb2a1d2 100644 --- a/src/Tests/Search/Percolator/MultiPercolate/MultiPercolateInvalidApiTests.cs +++ b/src/Tests/Search/Percolator/MultiPercolate/MultiPercolateInvalidApiTests.cs @@ -7,8 +7,10 @@ using Tests.Framework; using Tests.Framework.Integration; using Tests.Framework.MockData; -using Xunit; - +using Xunit; + +#pragma warning disable 618 // testing deprecated percolate APIs + namespace Tests.Search.Percolator.MultiPercolate { [Collection(IntegrationContext.ReadOnly)] diff --git a/src/Tests/Search/Percolator/MultiPercolate/MultiPercolateUrlTests.cs b/src/Tests/Search/Percolator/MultiPercolate/MultiPercolateUrlTests.cs index 9fe6ceb20ba..75d9e0ab10e 100644 --- a/src/Tests/Search/Percolator/MultiPercolate/MultiPercolateUrlTests.cs +++ b/src/Tests/Search/Percolator/MultiPercolate/MultiPercolateUrlTests.cs @@ -4,6 +4,8 @@ using Tests.Framework.MockData; using static Tests.Framework.UrlTester; +#pragma warning disable 618 // testing deprecated percolate APIs + namespace Tests.Search.Percolator.MultiPercolate { public class MultiPercolateUrlTests diff --git a/src/Tests/Search/Percolator/Percolate/PercolateApiTests.cs b/src/Tests/Search/Percolator/Percolate/PercolateApiTests.cs index 9a57565f52e..d8c520e5a2c 100644 --- a/src/Tests/Search/Percolator/Percolate/PercolateApiTests.cs +++ b/src/Tests/Search/Percolator/Percolate/PercolateApiTests.cs @@ -9,8 +9,10 @@ using Tests.Framework.Integration; using Tests.Framework.MockData; using Xunit; -using static Nest.Infer; - +using static Nest.Infer; + +#pragma warning disable 618 // testing deprecated percolate APIs + namespace Tests.Search.Percolator.Percolate { [Collection(IntegrationContext.Indexing)] diff --git a/src/Tests/Search/Percolator/Percolate/PercolateUrlTests.cs b/src/Tests/Search/Percolator/Percolate/PercolateUrlTests.cs index 711fad3b98f..3c9fec2fa73 100644 --- a/src/Tests/Search/Percolator/Percolate/PercolateUrlTests.cs +++ b/src/Tests/Search/Percolator/Percolate/PercolateUrlTests.cs @@ -4,6 +4,8 @@ using Tests.Framework.MockData; using static Tests.Framework.UrlTester; +#pragma warning disable 618 // testing deprecated percolate APIs + namespace Tests.Search.Percolator.Percolate { public class PercolateUrlTests diff --git a/src/Tests/Search/Percolator/PercolateCount/PercolateCountApiTests.cs b/src/Tests/Search/Percolator/PercolateCount/PercolateCountApiTests.cs index 0dec91f74d8..4535bdc0882 100644 --- a/src/Tests/Search/Percolator/PercolateCount/PercolateCountApiTests.cs +++ b/src/Tests/Search/Percolator/PercolateCount/PercolateCountApiTests.cs @@ -7,6 +7,8 @@ using Tests.Framework.MockData; using Xunit; +#pragma warning disable 618 // testing deprecated percolate APIs + namespace Tests.Search.Percolator.PercolateCount { [Collection(IntegrationContext.ReadOnly)] diff --git a/src/Tests/Search/Percolator/PercolateCount/PercolateCountUrlTests.cs b/src/Tests/Search/Percolator/PercolateCount/PercolateCountUrlTests.cs index 671071caef4..64ef0ceca08 100644 --- a/src/Tests/Search/Percolator/PercolateCount/PercolateCountUrlTests.cs +++ b/src/Tests/Search/Percolator/PercolateCount/PercolateCountUrlTests.cs @@ -4,6 +4,8 @@ using Tests.Framework.MockData; using static Tests.Framework.UrlTester; +#pragma warning disable 618 // testing deprecated percolate APIs + namespace Tests.Search.Percolator.PercolateCount { public class CountPercolateUrlTests diff --git a/src/Tests/Search/Percolator/RegisterPercolator/RegisterPercolatorApiTests.cs b/src/Tests/Search/Percolator/RegisterPercolator/RegisterPercolatorApiTests.cs index cb45b89e7f1..e832e8371a6 100644 --- a/src/Tests/Search/Percolator/RegisterPercolator/RegisterPercolatorApiTests.cs +++ b/src/Tests/Search/Percolator/RegisterPercolator/RegisterPercolatorApiTests.cs @@ -6,8 +6,10 @@ using Tests.Framework; using Tests.Framework.Integration; using Tests.Framework.MockData; -using Xunit; - +using Xunit; + +#pragma warning disable 618 // testing deprecated percolate APIs + namespace Tests.Search.Percolator.RegisterPercolator { [Collection(IntegrationContext.Indexing)] @@ -39,7 +41,7 @@ protected override LazyResponses ClientUsage() => Calls( protected override string UrlPath => $"/{CallIsolatedValue}-index/.percolator/{this.CallIsolatedValue}"; protected override RegisterPercolatorDescriptor NewDescriptor() => new RegisterPercolatorDescriptor(this.CallIsolatedValue); - + protected override object ExpectJson => new { query = new diff --git a/src/Tests/Search/Percolator/RegisterPercolator/RegisterPercolatorUrlTests.cs b/src/Tests/Search/Percolator/RegisterPercolator/RegisterPercolatorUrlTests.cs index 67addb58c5f..789ad1c8be0 100644 --- a/src/Tests/Search/Percolator/RegisterPercolator/RegisterPercolatorUrlTests.cs +++ b/src/Tests/Search/Percolator/RegisterPercolator/RegisterPercolatorUrlTests.cs @@ -4,6 +4,8 @@ using Tests.Framework.MockData; using static Tests.Framework.UrlTester; +#pragma warning disable 618 // testing deprecated percolate APIs + namespace Tests.Search.Percolator.RegisterPercolator { public class RegisterPercolatorUrlTests diff --git a/src/Tests/Search/Percolator/UnregisterPercolator/UnregisterPercolatorApiTests.cs b/src/Tests/Search/Percolator/UnregisterPercolator/UnregisterPercolatorApiTests.cs index 68f288e719b..48c94e3f70f 100644 --- a/src/Tests/Search/Percolator/UnregisterPercolator/UnregisterPercolatorApiTests.cs +++ b/src/Tests/Search/Percolator/UnregisterPercolator/UnregisterPercolatorApiTests.cs @@ -5,8 +5,10 @@ using Tests.Framework; using Tests.Framework.Integration; using Tests.Framework.MockData; -using Xunit; - +using Xunit; + +#pragma warning disable 618 // testing deprecated percolate APIs + namespace Tests.Search.Percolator.UnregisterPercolator { [Collection(IntegrationContext.Indexing)] @@ -14,7 +16,7 @@ public class UnregisterPercolatorApiTests : ApiIntegrationTestBase + @@ -333,6 +334,7 @@ + @@ -529,6 +531,7 @@ +