From 08819b300c28675a4f33f75f56c4fa5732ffc07f Mon Sep 17 00:00:00 2001 From: Martijn Laarman Date: Wed, 26 Feb 2020 11:18:15 +0100 Subject: [PATCH] Fix GetMany when no default index is set https://github.com/elastic/elasticsearch-net/pull/4353 Fixed an issue with the GetMany helpers that returned the cartesian product of all ids specified rather then creating a distinct list if more then one index was targeted. This PR also updated the routine in the serializer to omit the index name from each item if the index is already specified on the url in case of multiple indices This updated routine in the `7.6.0` could throw if you are calling: client.GetMany(ids, "indexName"); Without configuring `ConnectionSettings()` with either a default index for T or a global default index. --- .../Multiple/Bulk/ElasticClient-DeleteMany.cs | 2 +- .../MultiGet/ElasticClient-GetMany.cs | 15 ++++-- .../MultiGet/ElasticClient-SourceMany.cs | 16 ++++-- tests/Tests.Reproduce/GitHubIssue4462.cs | 53 +++++++++++++++++++ 4 files changed, 79 insertions(+), 7 deletions(-) create mode 100644 tests/Tests.Reproduce/GitHubIssue4462.cs diff --git a/src/Nest/Document/Multiple/Bulk/ElasticClient-DeleteMany.cs b/src/Nest/Document/Multiple/Bulk/ElasticClient-DeleteMany.cs index fb677db1d7a..915e652f001 100644 --- a/src/Nest/Document/Multiple/Bulk/ElasticClient-DeleteMany.cs +++ b/src/Nest/Document/Multiple/Bulk/ElasticClient-DeleteMany.cs @@ -6,7 +6,7 @@ namespace Nest { /// - /// Provides GetMany extensions that make it easier to get many documents given a list of ids + /// Provides DeleteMany extensions that make it easier to get many documents given a list of ids /// public static class DeleteManyExtensions { diff --git a/src/Nest/Document/Multiple/MultiGet/ElasticClient-GetMany.cs b/src/Nest/Document/Multiple/MultiGet/ElasticClient-GetMany.cs index a538c52d804..b61d4629072 100644 --- a/src/Nest/Document/Multiple/MultiGet/ElasticClient-GetMany.cs +++ b/src/Nest/Document/Multiple/MultiGet/ElasticClient-GetMany.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Threading; @@ -11,6 +12,14 @@ namespace Nest /// public static class GetManyExtensions { + private static Func, string, IMultiGetOperation> Lookup(IndexName index) + where T : class + { + if (index == null) return null; + + return (d, id) => d.Index(index); + } + /// /// Multi GET API allows to get multiple documents based on an index, type (optional) and id (and possibly routing). /// The response includes a docs array with all the fetched documents, each element similar in structure to a document @@ -29,7 +38,7 @@ public static IEnumerable> GetMany(this IElasticClient client var result = client.MultiGet(s => s .Index(index) .RequestConfiguration(r => r.ThrowExceptions()) - .GetMany(ids) + .GetMany(ids, Lookup(index)) ); return result.GetMany(ids); } @@ -68,7 +77,7 @@ public static async Task>> GetManyAsync( var response = await client.MultiGetAsync(s => s .Index(index) .RequestConfiguration(r => r.ThrowExceptions()) - .GetMany(ids), + .GetMany(ids, Lookup(index)), cancellationToken ) .ConfigureAwait(false); diff --git a/src/Nest/Document/Multiple/MultiGet/ElasticClient-SourceMany.cs b/src/Nest/Document/Multiple/MultiGet/ElasticClient-SourceMany.cs index 8c43fd152f0..4d282dda13a 100644 --- a/src/Nest/Document/Multiple/MultiGet/ElasticClient-SourceMany.cs +++ b/src/Nest/Document/Multiple/MultiGet/ElasticClient-SourceMany.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Threading; @@ -11,6 +12,15 @@ namespace Nest /// public static class SourceManyExtensions { + + private static Func, string, IMultiGetOperation> Lookup(IndexName index) + where T : class + { + if (index == null) return null; + + return (d, id) => d.Index(index); + } + /// /// SourceMany allows you to get a list of T documents out of Elasticsearch, internally it calls into MultiGet() /// @@ -31,7 +41,7 @@ public static IEnumerable SourceMany(this IElasticClient client, IEnumerab var result = client.MultiGet(s => s .Index(index) .RequestConfiguration(r => r.ThrowExceptions()) - .GetMany(ids, (gs, i) => gs ) + .GetMany(ids, Lookup(index)) ); return result.SourceMany(ids); } @@ -75,7 +85,7 @@ public static async Task> SourceManyAsync( var response = await client.MultiGetAsync(s => s .Index(index) .RequestConfiguration(r => r.ThrowExceptions()) - .GetMany(ids, (gs, i) => gs), cancellationToken) + .GetMany(ids, Lookup(index)), cancellationToken) .ConfigureAwait(false); return response.SourceMany(ids); } diff --git a/tests/Tests.Reproduce/GitHubIssue4462.cs b/tests/Tests.Reproduce/GitHubIssue4462.cs new file mode 100644 index 00000000000..d921322c9b9 --- /dev/null +++ b/tests/Tests.Reproduce/GitHubIssue4462.cs @@ -0,0 +1,53 @@ +using System; +using System.Text; +using Elastic.Xunit.XunitPlumbing; +using Elasticsearch.Net; +using FluentAssertions; +using Nest; +using Tests.Domain; + +namespace Tests.Reproduce +{ + /* + * https://github.com/elastic/elasticsearch-net/pull/4353 + * Fixed an issue with the GetMany helpers that returned the cartesian product of all ids specified rather + * then creating a distinct list if more then one index was targeted. + * + * This PR also updated the routine in the serializer to omit the index name from each item if the index is + * already specified on the url in case of multiple indices + * + * This updated routine in the `7.6.0` could throw if you are calling: + * + * client.GetMany(ids, "indexName"); + * + * Without configuring `ConnectionSettings()` with either a default index for T or a global default index. + */ + public class GitHubIssue4462 + { + [U] public void GetManyShouldNotThrowIfIndexIsProvided() + { + var json = "{}"; + + var bytes = Encoding.UTF8.GetBytes(json); + var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200")); + var connectionSettings = new ConnectionSettings(pool, new InMemoryConnection(bytes)); + var client = new ElasticClient(connectionSettings); + + var response = client.GetMany(new long[] {1, 2, 3}, "indexName"); + response.Should().NotBeNull(); + } + + [U] public void SourceManyShouldNotThrowIfIndexIsProvided() + { + var json = "{}"; + + var bytes = Encoding.UTF8.GetBytes(json); + var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200")); + var connectionSettings = new ConnectionSettings(pool, new InMemoryConnection(bytes)); + var client = new ElasticClient(connectionSettings); + + var response = client.SourceMany(new long[] {1, 2, 3}, "indexName"); + response.Should().NotBeNull(); + } + } +}