diff --git a/src/Nest/Document/Multiple/MultiTermVectors/ElasticClient-MultiTermVectors.cs b/src/Nest/Document/Multiple/MultiTermVectors/ElasticClient-MultiTermVectors.cs
index a592e6acf18..889cda86a14 100644
--- a/src/Nest/Document/Multiple/MultiTermVectors/ElasticClient-MultiTermVectors.cs
+++ b/src/Nest/Document/Multiple/MultiTermVectors/ElasticClient-MultiTermVectors.cs
@@ -14,13 +14,13 @@ public partial interface IElasticClient
/// The descriptor describing the multi termvectors operation
IMultiTermVectorsResponse MultiTermVectors(Func selector = null);
- ///
+ ///
IMultiTermVectorsResponse MultiTermVectors(IMultiTermVectorsRequest request);
- ///
+ ///
Task MultiTermVectorsAsync(Func selector = null, CancellationToken cancellationToken = default(CancellationToken));
- ///
+ ///
Task MultiTermVectorsAsync(IMultiTermVectorsRequest request, CancellationToken cancellationToken = default(CancellationToken));
}
diff --git a/src/Nest/Document/Multiple/MultiTermVectors/MultiTermVectorOperation.cs b/src/Nest/Document/Multiple/MultiTermVectors/MultiTermVectorOperation.cs
index 938f6aee29f..e5ca292d491 100644
--- a/src/Nest/Document/Multiple/MultiTermVectors/MultiTermVectorOperation.cs
+++ b/src/Nest/Document/Multiple/MultiTermVectors/MultiTermVectorOperation.cs
@@ -4,42 +4,121 @@
namespace Nest
{
+ ///
+ /// An operation to define the calculation of
+ /// term vectors when using Multi termvectors API
+ ///
public interface IMultiTermVectorOperation
{
+ ///
+ /// The index in which the document resides
+ ///
[JsonProperty("_index")]
IndexName Index { get; set; }
+
+ ///
+ /// The type of the document
+ ///
[JsonProperty("_type")]
TypeName Type { get; set; }
+
+ ///
+ /// The id of the document
+ ///
[JsonProperty("_id")]
Id Id { get; set; }
+
+ ///
+ /// A document not indexed in Elasticsearch,
+ /// to generate term vectors for
+ ///
[JsonProperty("doc")]
[JsonConverter(typeof(SourceConverter))]
object Document { get; set; }
+
+ ///
+ /// The document field to generate term
+ /// vectors for
+ ///
[JsonProperty("fields")]
+ // TODO: Rename to Fields in 7.x
Fields StoredFields { get; set; }
+
+ ///
+ /// Whether to include the start and end offsets.
+ /// Default is true.
+ ///
[JsonProperty("offsets")]
bool? Offsets { get; set; }
+
+ ///
+ /// Whether to include the term payloads as
+ /// base64 encoded bytes. Default is true
+ ///
[JsonProperty("payloads")]
bool? Payloads { get; set; }
+
+ ///
+ /// Whether to include the term positions.
+ /// Default is true
+ ///
[JsonProperty("positions")]
bool? Positions { get; set; }
+
+ ///
+ /// Whether to include term statistics. When set to true,
+ /// - total term frequency (how often a term occurs in all documents)
+ /// - document frequency (the number of documents containing the current term)
+ /// will be returned. Default is false since
+ /// term statistics can have a large performance impact.
+ ///
[JsonProperty("term_statistics")]
bool? TermStatistics { get; set; }
+
+ ///
+ /// Whether to include field statistics. When set to false,
+ /// - document count (how many documents contain this field)
+ /// - sum of document frequencies (the sum of document frequencies for all terms in this field)
+ /// - sum of total term frequencies (the sum of total term frequencies of each term in this field)
+ /// will be omitted. Default is true.
+ ///
[JsonProperty("field_statistics")]
bool? FieldStatistics { get; set; }
+
+ ///
+ /// Filter terms based on their tf-idf scores.
+ /// This can be useful in order find out a good characteristic
+ /// vector of a document.
+ ///
[JsonProperty("filter")]
ITermVectorFilter Filter { get; set; }
+
+ ///
+ /// The version number
+ ///
[JsonProperty("version")]
long? Version { get; set; }
+
+ ///
+ /// The type of version
+ ///
[JsonProperty("version_type")]
VersionType? VersionType { get; set; }
+
+ ///
+ /// When requesting term vectors for ,
+ /// a shard to get the statistics from is randomly selected.
+ /// Use only to hit a particular shard.
+ ///
[JsonProperty("routing")]
Routing Routing { get; set; }
}
+ ///
public class MultiTermVectorOperation : IMultiTermVectorOperation
where T : class
{
+ private Routing _routing;
public MultiTermVectorOperation(Id id)
{
@@ -48,21 +127,33 @@ public MultiTermVectorOperation(Id id)
this.Type = typeof (T);
}
+ ///
public IndexName Index { get; set; }
+ ///
public TypeName Type { get; set; }
+ ///
public Id Id { get; set; }
+ ///
public object Document { get; set; }
+ ///
public Fields StoredFields { get; set; }
+ ///
public bool? Offsets { get; set; }
+ ///
public bool? Payloads { get; set; }
+ ///
public bool? Positions { get; set; }
+ ///
public bool? TermStatistics { get; set; }
+ ///
public bool? FieldStatistics { get; set; }
+ ///
public ITermVectorFilter Filter { get; set; }
+ ///
public long? Version { get; set; }
+ ///
public VersionType? VersionType { get; set; }
-
- private Routing _routing;
+ ///
public Routing Routing
{
get => _routing ?? (Document == null ? null : new Routing(Document));
@@ -70,9 +161,12 @@ public Routing Routing
}
}
+ ///
public class MultiTermVectorOperationDescriptor : DescriptorBase, IMultiTermVectorOperation>, IMultiTermVectorOperation
where T : class
{
+ private Routing _routing;
+
IndexName IMultiTermVectorOperation.Index { get; set; } = typeof (T);
TypeName IMultiTermVectorOperation.Type { get; set; } = typeof (T);
Id IMultiTermVectorOperation.Id { get; set; }
@@ -86,40 +180,59 @@ public class MultiTermVectorOperationDescriptor : DescriptorBase _routing ?? (Self.Document == null ? null : new Routing(Self.Document));
set => _routing = value;
}
+ ///
+ // TODO: Rename to Fields in 7.x
public MultiTermVectorOperationDescriptor StoredFields(Func, IPromise> fields) =>
Assign(a => a.StoredFields = fields?.Invoke(new FieldsDescriptor())?.Value);
+ ///
+ // TODO: Rename to Fields in 7.x
public MultiTermVectorOperationDescriptor StoredFields(Fields fields) => Assign(a => a.StoredFields = fields);
- public MultiTermVectorOperationDescriptor Id(Id id) => Assign(a=>a.Id = id);
+ ///
+ public MultiTermVectorOperationDescriptor Id(Id id) => Assign(a=> a.Id = id);
+
+ ///
+ public MultiTermVectorOperationDescriptor Index(IndexName index) => Assign(a => a.Index = index);
+
+ ///
+ public MultiTermVectorOperationDescriptor Type(TypeName type) => Assign(a=> a.Type = type);
+ ///
public MultiTermVectorOperationDescriptor Document(T document) => Assign(a => a.Document = document);
+ ///
public MultiTermVectorOperationDescriptor Offsets(bool? offsets = true) => Assign(a => a.Offsets = offsets);
+ ///
public MultiTermVectorOperationDescriptor Payloads(bool? payloads = true) => Assign(a => a.Payloads = payloads);
+ ///
public MultiTermVectorOperationDescriptor Positions(bool? positions = true) => Assign(a => a.Positions = positions);
+ ///
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()));
+ ///
public MultiTermVectorOperationDescriptor Version(long? version) => Assign(a => a.Version = version);
+ ///
public MultiTermVectorOperationDescriptor VersionType(VersionType? versionType) => Assign(a => a.VersionType = versionType);
+ ///
public MultiTermVectorOperationDescriptor Routing(Routing routing) => Assign(a => a.Routing = routing);
}
}
diff --git a/src/Nest/Document/Multiple/MultiTermVectors/MultiTermVectorsRequest.cs b/src/Nest/Document/Multiple/MultiTermVectors/MultiTermVectorsRequest.cs
index 6e4f9274f4b..c385adb4d35 100644
--- a/src/Nest/Document/Multiple/MultiTermVectors/MultiTermVectorsRequest.cs
+++ b/src/Nest/Document/Multiple/MultiTermVectors/MultiTermVectorsRequest.cs
@@ -5,43 +5,84 @@
namespace Nest
{
+ ///
+ /// A Multi termvectors API request
+ ///
public partial interface IMultiTermVectorsRequest
{
+ ///
+ /// The documents for which to generate term vectors
+ ///
[JsonProperty("docs")]
IEnumerable Documents { get; set; }
+
+ ///
+ /// The ids of documents within the same index and type
+ /// for which to generate term vectors. Must be used in
+ /// conjunction with and
+ ///
+ [JsonProperty("ids")]
+ IEnumerable Ids { get; set; }
}
+ ///
public partial class MultiTermVectorsRequest
{
+ ///
public IEnumerable Documents { get; set; }
+
+ ///
+ public IEnumerable Ids { get; set; }
}
+ ///
[DescriptorFor("Mtermvectors")]
public partial class MultiTermVectorsDescriptor
{
- private List _operations = new List();
+ private List _operations;
+
+ private List Operations =>
+ this._operations ?? (this._operations = new List());
+
IEnumerable IMultiTermVectorsRequest.Documents
{
- get { return this._operations; }
- set { this._operations = value?.ToList(); }
+ get => this._operations;
+ set => this._operations = value?.ToList();
}
+ IEnumerable IMultiTermVectorsRequest.Ids { get; set; }
+
+ // TODO: Rename to Documents in 7.x
+ ///
+ /// A document for which to generate term vectors
+ ///
public MultiTermVectorsDescriptor Get(Func, IMultiTermVectorOperation> getSelector)
where T : class =>
- Assign(a => this._operations.AddIfNotNull(getSelector?.Invoke(new MultiTermVectorOperationDescriptor())));
+ Assign(a => this.Operations.AddIfNotNull(getSelector?.Invoke(new MultiTermVectorOperationDescriptor())));
+ // TODO: Rename to Documents in 7.x
+ ///
public MultiTermVectorsDescriptor GetMany(IEnumerable ids,
Func, long, IMultiTermVectorOperation> getSelector = null)
where T : class =>
- Assign(a => this._operations.AddRange(ids.Select(id => getSelector.InvokeOrDefault(new MultiTermVectorOperationDescriptor().Id(id), id))));
+ Assign(a => this.Operations.AddRange(ids.Select(id => getSelector.InvokeOrDefault(new MultiTermVectorOperationDescriptor().Id(id), id))));
+ // TODO: Rename to Documents in 7.x
+ ///
public MultiTermVectorsDescriptor GetMany(IEnumerable ids, Func, string, IMultiTermVectorOperation> getSelector = null)
where T : class =>
- Assign(a => this._operations.AddRange(ids.Select(id => getSelector.InvokeOrDefault(new MultiTermVectorOperationDescriptor().Id(id), id))));
+ Assign(a => this.Operations.AddRange(ids.Select(id => getSelector.InvokeOrDefault(new MultiTermVectorOperationDescriptor().Id(id), id))));
+ // TODO: Rename to Documents in 7.x
+ ///
public MultiTermVectorsDescriptor GetMany(IEnumerable ids, Func, Id, IMultiTermVectorOperation> getSelector = null)
where T : class =>
- Assign(a => this._operations.AddRange(ids.Select(id => getSelector.InvokeOrDefault(new MultiTermVectorOperationDescriptor().Id(id), id))));
+ Assign(a => this.Operations.AddRange(ids.Select(id => getSelector.InvokeOrDefault(new MultiTermVectorOperationDescriptor().Id(id), id))));
+
+ ///
+ public MultiTermVectorsDescriptor Ids(IEnumerable ids) => Assign(a => a.Ids = ids);
+ ///
+ public MultiTermVectorsDescriptor Ids(params Id[] ids) => Assign(a => a.Ids = ids);
}
}
diff --git a/src/Tests/Tests/Document/Multiple/MultiTermVectors/MultiTermVectorsApiTests.cs b/src/Tests/Tests/Document/Multiple/MultiTermVectors/MultiTermVectorsApiTests.cs
index 32f5e3e4951..936e23a5793 100644
--- a/src/Tests/Tests/Document/Multiple/MultiTermVectors/MultiTermVectorsApiTests.cs
+++ b/src/Tests/Tests/Document/Multiple/MultiTermVectors/MultiTermVectorsApiTests.cs
@@ -14,9 +14,9 @@
namespace Tests.Document.Multiple.MultiTermVectors
{
- public class MultiTermVectorsApiTests : ApiIntegrationTestBase
+ public class MultiTermVectorsDocsApiTests : ApiIntegrationTestBase
{
- public MultiTermVectorsApiTests(ReadOnlyCluster cluster, EndpointUsage usage) : base(cluster, usage) { }
+ public MultiTermVectorsDocsApiTests(ReadOnlyCluster cluster, EndpointUsage usage) : base(cluster, usage) { }
protected override LazyResponses ClientUsage() => Calls(
fluent: (client, f) => client.MultiTermVectors(f),
fluentAsync: (client, f) => client.MultiTermVectorsAsync(f),
@@ -123,4 +123,84 @@ private static void AssertTermVectors(TermVector vectors)
})
};
}
+
+ public class MultiTermVectorsIdsApiTests : ApiIntegrationTestBase
+ {
+ public MultiTermVectorsIdsApiTests(ReadOnlyCluster cluster, EndpointUsage usage) : base(cluster, usage) { }
+ protected override LazyResponses ClientUsage() => Calls(
+ fluent: (client, f) => client.MultiTermVectors(f),
+ fluentAsync: (client, f) => client.MultiTermVectorsAsync(f),
+ request: (client, r) => client.MultiTermVectors(r),
+ requestAsync: (client, r) => client.MultiTermVectorsAsync(r)
+ );
+
+ protected override bool ExpectIsValid => true;
+ protected override int ExpectStatusCode => 200;
+ protected override HttpMethod HttpMethod => HttpMethod.POST;
+ protected override string UrlPath =>
+ $"/devs/developer/_mtermvectors?field_statistics=true&payloads=true&term_statistics=true&positions=true&offsets=true";
+
+ protected override bool SupportsDeserialization => false;
+
+ protected override object ExpectJson { get; } = new
+ {
+ ids = Developer.Developers.Select(p => (Id)p.Id).Take(2)
+ };
+
+ protected override void ExpectResponse(IMultiTermVectorsResponse response)
+ {
+ response.ShouldBeValid();
+ response.Documents.Should().NotBeEmpty().And.HaveCount(2).And.OnlyContain(d => d.Found);
+ var termvectorDoc = response.Documents.FirstOrDefault(d => d.TermVectors.Count > 0);
+
+ termvectorDoc.Should().NotBeNull();
+ termvectorDoc.Index.Should().NotBeNull();
+ termvectorDoc.Type.Should().NotBeNull();
+ termvectorDoc.Id.Should().NotBeNull();
+
+ termvectorDoc.TermVectors.Should().NotBeEmpty().And.ContainKey("firstName");
+ var vectors = termvectorDoc.TermVectors["firstName"];
+ AssertTermVectors(vectors);
+
+ vectors = termvectorDoc.TermVectors[Field(p=>p.FirstName)];
+ AssertTermVectors(vectors);
+ }
+
+ private static void AssertTermVectors(TermVector vectors)
+ {
+ vectors.Terms.Should().NotBeEmpty();
+ foreach (var vectorTerm in vectors.Terms)
+ {
+ vectorTerm.Key.Should().NotBeNullOrWhiteSpace();
+ vectorTerm.Value.Should().NotBeNull();
+ vectorTerm.Value.TermFrequency.Should().BeGreaterThan(0);
+ vectorTerm.Value.TotalTermFrequency.Should().BeGreaterThan(0);
+ vectorTerm.Value.Tokens.Should().NotBeEmpty();
+
+ var token = vectorTerm.Value.Tokens.First();
+ token.EndOffset.Should().BeGreaterThan(0);
+ }
+ }
+
+ protected override Func Fluent => d => d
+ .Index()
+ .Type()
+ .Ids(Developer.Developers.Select(p => (Id)p.Id).Take(2))
+ .FieldStatistics()
+ .Payloads()
+ .TermStatistics()
+ .Positions()
+ .Offsets()
+ ;
+
+ protected override MultiTermVectorsRequest Initializer => new MultiTermVectorsRequest(Index(), Type())
+ {
+ Ids = Developer.Developers.Select(p => (Id)p.Id).Take(2),
+ FieldStatistics = true,
+ Payloads = true,
+ TermStatistics = true,
+ Positions = true,
+ Offsets = true
+ };
+ }
}