From 72f142158b218a05f8f569baa7db2174dc8289e6 Mon Sep 17 00:00:00 2001 From: gmarz Date: Tue, 8 Mar 2016 16:42:12 -0500 Subject: [PATCH] Fix #1868 add filter option to _termvectors and _mtermvectors --- .../MultiTermVectorOperation.cs | 7 +++ .../Single/TermVectors/TermVectorFilter.cs | 44 +++++++++++++++++++ .../Single/TermVectors/TermVectorsRequest.cs | 14 +++++- .../MultiTermVectorsApiTests.cs | 29 ++++++++++-- .../Single/TermVectors/TermVectorsApiTests.cs | 28 ++++++++++-- src/Tests/tests.yaml | 4 +- 6 files changed, 116 insertions(+), 10 deletions(-) create mode 100644 src/Nest/Document/Single/TermVectors/TermVectorFilter.cs diff --git a/src/Nest/Document/Multiple/MultiTermVectors/MultiTermVectorOperation.cs b/src/Nest/Document/Multiple/MultiTermVectors/MultiTermVectorOperation.cs index bfa6a2cd107..ac002499012 100644 --- a/src/Nest/Document/Multiple/MultiTermVectors/MultiTermVectorOperation.cs +++ b/src/Nest/Document/Multiple/MultiTermVectors/MultiTermVectorOperation.cs @@ -25,6 +25,8 @@ public interface IMultiTermVectorOperation bool? TermStatistics { get; set; } [JsonProperty("field_statistics")] bool? FieldStatistics { get; set; } + [JsonProperty("filter")] + ITermVectorFilter Filter { get; set; } } public class MultiTermVectorOperation : IMultiTermVectorOperation @@ -47,6 +49,7 @@ public MultiTermVectorOperation(Id id) public bool? Positions { get; set; } public bool? TermStatistics { get; set; } public bool? FieldStatistics { get; set; } + public ITermVectorFilter Filter { get; set; } } public class MultiTermVectorOperationDescriptor : DescriptorBase, IMultiTermVectorOperation>, IMultiTermVectorOperation @@ -62,6 +65,7 @@ public class MultiTermVectorOperationDescriptor : DescriptorBase Fields(Func, IPromise> fields) => Assign(a => a.Fields = fields?.Invoke(new FieldsDescriptor())?.Value); @@ -77,5 +81,8 @@ public MultiTermVectorOperationDescriptor Fields(Func, IP public MultiTermVectorOperationDescriptor TermStatistics(bool termStatistics = true) => Assign(a => a.TermStatistics = termStatistics); public MultiTermVectorOperationDescriptor FieldStatistics(bool fieldStatistics = true) => Assign(a => a.FieldStatistics = fieldStatistics); + + public MultiTermVectorOperationDescriptor Filter(Func filterSelector) => + Assign(a => a.Filter = filterSelector?.Invoke(new TermVectorFilterDescriptor())); } } \ No newline at end of file diff --git a/src/Nest/Document/Single/TermVectors/TermVectorFilter.cs b/src/Nest/Document/Single/TermVectors/TermVectorFilter.cs new file mode 100644 index 00000000000..b0ee5ed5e1f --- /dev/null +++ b/src/Nest/Document/Single/TermVectors/TermVectorFilter.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Nest +{ + [JsonObject(MemberSerialization.OptIn)] + public interface ITermVectorFilter + { + [JsonProperty("max_num_terms")] + int? MaximumNumberOfTerms { get; set; } + + [JsonProperty("min_term_freq")] + int? MinimumTermFrequency { get; set; } + + [JsonProperty("min_doc_freq")] + int? MinimumDocumentFrequency { get; set; } + } + + public class TermVectorFilter : ITermVectorFilter + { + public int? MaximumNumberOfTerms { get; set; } + + public int? MinimumTermFrequency { get; set; } + + public int? MinimumDocumentFrequency { get; set; } + } + + public class TermVectorFilterDescriptor + : DescriptorBase, ITermVectorFilter + { + int? ITermVectorFilter.MaximumNumberOfTerms { get; set; } + + int? ITermVectorFilter.MinimumDocumentFrequency { get; set; } + + int? ITermVectorFilter.MinimumTermFrequency { get; set; } + + public TermVectorFilterDescriptor MaximimumNumberOfTerms(int maxNumTerms) => Assign(a => a.MaximumNumberOfTerms = maxNumTerms); + + public TermVectorFilterDescriptor MinimumDocumentFrequency(int minDocFreq) => Assign(a => a.MinimumDocumentFrequency = minDocFreq); + + public TermVectorFilterDescriptor MinimumTermFrequency(int minTermFreq) => Assign(a => a.MinimumTermFrequency = minTermFreq); + } +} diff --git a/src/Nest/Document/Single/TermVectors/TermVectorsRequest.cs b/src/Nest/Document/Single/TermVectors/TermVectorsRequest.cs index aaaec135bcd..b7dd0dba458 100644 --- a/src/Nest/Document/Single/TermVectors/TermVectorsRequest.cs +++ b/src/Nest/Document/Single/TermVectors/TermVectorsRequest.cs @@ -16,17 +16,22 @@ public partial interface ITermVectorsRequest [JsonProperty("per_field_analyzer")] IPerFieldAnalyzer PerFieldAnalyzer { get; set; } + + [JsonProperty("filter")] + ITermVectorFilter Filter { get; set; } } public partial class TermVectorsRequest where TDocument : class { - HttpMethod IRequest.HttpMethod => this.Document == null ? HttpMethod.GET : HttpMethod.POST; + HttpMethod IRequest.HttpMethod => (this.Document != null || this.Filter != null) ? HttpMethod.POST : HttpMethod.GET; public TDocument Document { get; set; } public IPerFieldAnalyzer PerFieldAnalyzer { get; set; } + public ITermVectorFilter Filter { get; set; } + partial void DocumentFromPath(TDocument document) { Self.Document = document; @@ -38,15 +43,20 @@ partial void DocumentFromPath(TDocument document) [DescriptorFor("Termvectors")] public partial class TermVectorsDescriptor where TDocument : class { - HttpMethod IRequest.HttpMethod => Self.Document == null ? HttpMethod.GET : HttpMethod.POST; + HttpMethod IRequest.HttpMethod => (Self.Document != null || Self.Filter != null) ? HttpMethod.POST : HttpMethod.GET; TDocument ITermVectorsRequest.Document { get; set; } IPerFieldAnalyzer ITermVectorsRequest.PerFieldAnalyzer { get; set; } + ITermVectorFilter ITermVectorsRequest.Filter { get; set; } + public TermVectorsDescriptor Document(TDocument document) => Assign(a => a.Document = document); public TermVectorsDescriptor PerFieldAnalyzer(Func, IPromise> analyzerSelector) => Assign(a => a.PerFieldAnalyzer = analyzerSelector?.Invoke(new PerFieldAnalyzerDescriptor())?.Value); + + public TermVectorsDescriptor Filter(Func filterSelector) => + Assign(a => a.Filter = filterSelector?.Invoke(new TermVectorFilterDescriptor())); } } diff --git a/src/Tests/Document/Multiple/MultiTermVectors/MultiTermVectorsApiTests.cs b/src/Tests/Document/Multiple/MultiTermVectors/MultiTermVectorsApiTests.cs index 2996c10c3ae..0629cfe9a4f 100644 --- a/src/Tests/Document/Multiple/MultiTermVectors/MultiTermVectorsApiTests.cs +++ b/src/Tests/Document/Multiple/MultiTermVectors/MultiTermVectorsApiTests.cs @@ -42,7 +42,13 @@ protected override LazyResponses ClientUsage() => Calls( field_statistics = true, term_statistics = true, positions = true, - offsets = true + offsets = true, + filter = new + { + max_num_terms = 3, + min_term_freq = 1, + min_doc_freq = 1 + } }).Take(2) }; @@ -77,7 +83,18 @@ protected override void ExpectResponse(IMultiTermVectorsResponse response) protected override Func Fluent => d => d .Index() - .GetMany(Developer.Developers.Select(p => p.Id).Take(2), (p, i) => p.FieldStatistics().Payloads().TermStatistics().Positions().Offsets()) + .GetMany(Developer.Developers.Select(p => p.Id).Take(2), (p, i) => p + .FieldStatistics() + .Payloads() + .TermStatistics() + .Positions() + .Offsets() + .Filter(f => f + .MaximimumNumberOfTerms(3) + .MinimumTermFrequency(1) + .MinimumDocumentFrequency(1) + ) + ) ; protected override MultiTermVectorsRequest Initializer => new MultiTermVectorsRequest(Index()) @@ -89,7 +106,13 @@ protected override void ExpectResponse(IMultiTermVectorsResponse response) Payloads = true, TermStatistics = true, Positions = true, - Offsets = true + Offsets = true, + Filter = new TermVectorFilter + { + MaximumNumberOfTerms = 3, + MinimumTermFrequency = 1, + MinimumDocumentFrequency = 1 + } }) }; } diff --git a/src/Tests/Document/Single/TermVectors/TermVectorsApiTests.cs b/src/Tests/Document/Single/TermVectors/TermVectorsApiTests.cs index 9a15c5d4e7e..906433ca4a0 100644 --- a/src/Tests/Document/Single/TermVectors/TermVectorsApiTests.cs +++ b/src/Tests/Document/Single/TermVectors/TermVectorsApiTests.cs @@ -9,10 +9,10 @@ namespace Tests.Document.Single.TermVectors { - [Collection(IntegrationContext.Indexing)] + [Collection(IntegrationContext.ReadOnly)] public class TermVectorsApiTests : ApiIntegrationTestBase, TermVectorsDescriptor, TermVectorsRequest> { - public TermVectorsApiTests(IndexingCluster cluster, EndpointUsage usage) : base(cluster, usage) { } + public TermVectorsApiTests(ReadOnlyCluster cluster, EndpointUsage usage) : base(cluster, usage) { } protected override LazyResponses ClientUsage() => Calls( fluent: (client, f) => client.TermVectors(f), fluentAsync: (client, f) => client.TermVectorsAsync(f), @@ -22,20 +22,42 @@ protected override LazyResponses ClientUsage() => Calls( protected override bool ExpectIsValid => true; protected override int ExpectStatusCode => 200; - protected override HttpMethod HttpMethod => HttpMethod.GET; + protected override HttpMethod HttpMethod => HttpMethod.POST; protected override string UrlPath => $"/project/project/{Uri.EscapeDataString(Project.Instance.Name)}/_termvectors?offsets=true"; protected override bool SupportsDeserialization => false; + protected override object ExpectJson => new + { + filter = new + { + max_num_terms = 3, + min_term_freq = 1, + min_doc_freq = 1 + } + }; + protected override TermVectorsDescriptor NewDescriptor() => new TermVectorsDescriptor(typeof (Project), typeof (Project)); protected override Func, ITermVectorsRequest> Fluent => d=>d .Id(Id(Project.Instance)) .Offsets() + .Filter(f => f + .MaximimumNumberOfTerms(3) + .MinimumTermFrequency(1) + .MinimumDocumentFrequency(1) + ) ; + protected override TermVectorsRequest Initializer => new TermVectorsRequest(Project.Instance.Name) { Offsets = true, + Filter = new TermVectorFilter + { + MaximumNumberOfTerms = 3, + MinimumTermFrequency = 1, + MinimumDocumentFrequency = 1 + } }; } } diff --git a/src/Tests/tests.yaml b/src/Tests/tests.yaml index 0bf5e1a4827..74cf2393ae3 100644 --- a/src/Tests/tests.yaml +++ b/src/Tests/tests.yaml @@ -1,7 +1,7 @@ # mode either u (unit test), i (integration test) or m (mixed mode) -mode: u +mode: m # the elasticsearch version that should be started -elasticsearch_version: 2.0.1 +elasticsearch_version: 2.2.0 # whether we want to forcefully reseed on the node, if you are starting the tests with a node already running force_reseed: true # do not spawn nodes as part of the test setup but rely on a manually started es node being up