diff --git a/.gitignore b/.gitignore index b3140a14fe6..8970d6c10d8 100644 --- a/.gitignore +++ b/.gitignore @@ -75,7 +75,8 @@ launchSettings.json # https://github.com/elastic/elasticsearch-net/pull/1822#issuecomment-183722698 *.project.lock.json project.lock.json +/src/.vs +/src/.vs/* .idea/ *.sln.iml -/src/.vs/restore.dg diff --git a/.vs/config/applicationhost.config b/.vs/config/applicationhost.config deleted file mode 100644 index c2abfb4801d..00000000000 --- a/.vs/config/applicationhost.config +++ /dev/null @@ -1,1030 +0,0 @@ - - - - - - - - -
-
-
-
-
-
-
-
- - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
- -
-
-
-
-
-
- -
-
-
-
-
- -
-
-
- -
-
- -
-
- -
-
-
- - -
-
-
-
-
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/aggregations/writing-aggregations.asciidoc b/docs/aggregations/writing-aggregations.asciidoc index 3c4327c4afe..5e1c43c35e3 100644 --- a/docs/aggregations/writing-aggregations.asciidoc +++ b/docs/aggregations/writing-aggregations.asciidoc @@ -172,6 +172,7 @@ return s => s ); ---- <1> a list of aggregation functions to apply + <2> Using LINQ's `Aggregate()` function to accumulate/apply all of the aggregation functions Combining multiple `AggregationDescriptor` is also possible using the bitwise `&&` operator @@ -237,5 +238,6 @@ var maxPerChild = childAggregation.Max("max_per_child"); maxPerChild.Should().NotBeNull(); <2> ---- <1> Do something with the average per child. Here we just assert it's not null + <2> Do something with the max per child. Here we just assert it's not null diff --git a/docs/client-concepts/certificates/working-with-certificates.asciidoc b/docs/client-concepts/certificates/working-with-certificates.asciidoc index 29edd81616c..8b82d82eea0 100644 --- a/docs/client-concepts/certificates/working-with-certificates.asciidoc +++ b/docs/client-concepts/certificates/working-with-certificates.asciidoc @@ -144,8 +144,11 @@ public class PkiCluster : CertgenCaCluster } ---- <1> Set the client certificate on `ConnectionSettings` + <2> The path to the `.cer` file + <3> The path to the `.key` file + <4> The password for the private key Or per request on `RequestConfiguration` which will take precedence over the ones defined on `ConnectionConfiguration` diff --git a/docs/client-concepts/connection-pooling/exceptions/unexpected-exceptions.asciidoc b/docs/client-concepts/connection-pooling/exceptions/unexpected-exceptions.asciidoc index 84d54d1f276..d84f33033eb 100644 --- a/docs/client-concepts/connection-pooling/exceptions/unexpected-exceptions.asciidoc +++ b/docs/client-concepts/connection-pooling/exceptions/unexpected-exceptions.asciidoc @@ -60,8 +60,11 @@ audit = await audit.TraceUnexpectedException( ); ---- <1> set up a cluster with 10 nodes + <2> where node 2 on port 9201 always throws an exception + <3> The first call to 9200 returns a healthy response + <4> ...but the second call, to 9201, returns a bad response Sometimes, an unexpected exception happens further down in the pipeline. In this scenario, we @@ -100,7 +103,9 @@ audit = await audit.TraceUnexpectedException( ); ---- <1> calls on 9200 set up to throw a `WebException` + <2> calls on 9201 set up to throw an `Exception` + <3> Assert that the audit trail for the client call includes the bad response from 9200 and 9201 An unexpected hard exception on ping and sniff is something we *do* try to recover from and failover to retrying on the next node. @@ -145,6 +150,8 @@ audit = await audit.TraceUnexpectedException( ); ---- <1> `InnerException` is the exception that brought the request down + <2> The hard exception that happened on ping is still available though + <3> An exception can be hard to relate back to a point in time, so the exception is also available on the audit trail diff --git a/docs/client-concepts/connection-pooling/exceptions/unrecoverable-exceptions.asciidoc b/docs/client-concepts/connection-pooling/exceptions/unrecoverable-exceptions.asciidoc index 46a7a8dfd87..18d6565e8c9 100644 --- a/docs/client-concepts/connection-pooling/exceptions/unrecoverable-exceptions.asciidoc +++ b/docs/client-concepts/connection-pooling/exceptions/unrecoverable-exceptions.asciidoc @@ -68,6 +68,7 @@ var audit = new Auditor(() => Framework.Cluster ); ---- <1> Always succeed on ping + <2> ...but always fail on calls with a 401 Bad Authentication response Now, let's make a client call. We'll see that the first audit event is a successful ping @@ -88,7 +89,9 @@ audit = await audit.TraceElasticsearchException( ); ---- <1> First call results in a successful ping + <2> Second call results in a bad response + <3> The reason for the bad response is Bad Authentication When a bad authentication response occurs, the client does not attempt to deserialize the response body returned; @@ -122,6 +125,7 @@ audit = await audit.TraceElasticsearchException( ); ---- <1> Always return a 401 bad response with a HTML response on client calls + <2> Assert that the response body bytes are null Now in this example, by turning on `DisableDirectStreaming()` on `ConnectionSettings`, we see the same behaviour exhibited @@ -154,5 +158,6 @@ audit = await audit.TraceElasticsearchException( ); ---- <1> Response bytes are set on the response + <2> Assert that the response contains `"nginx/"` diff --git a/docs/client-concepts/connection-pooling/request-overrides/disable-sniff-ping-per-request.asciidoc b/docs/client-concepts/connection-pooling/request-overrides/disable-sniff-ping-per-request.asciidoc index d30752053b2..3e3fb4f9af7 100644 --- a/docs/client-concepts/connection-pooling/request-overrides/disable-sniff-ping-per-request.asciidoc +++ b/docs/client-concepts/connection-pooling/request-overrides/disable-sniff-ping-per-request.asciidoc @@ -67,8 +67,11 @@ audit = await audit.TraceCalls( ); ---- <1> disable sniffing + <2> first call is a successful ping + <3> sniff on startup call happens here, on the second call + <4> No sniff on startup again Now, let's disable pinging on the request @@ -92,6 +95,7 @@ audit = await audit.TraceCall( ); ---- <1> disable ping + <2> No ping after sniffing Finally, let's demonstrate disabling both sniff and ping on the request @@ -113,5 +117,6 @@ audit = await audit.TraceCall( ); ---- <1> diable ping and sniff + <2> no ping or sniff before the call diff --git a/docs/client-concepts/connection-pooling/round-robin/skip-dead-nodes.asciidoc b/docs/client-concepts/connection-pooling/round-robin/skip-dead-nodes.asciidoc index cf83a1e8fd2..d79270b7321 100644 --- a/docs/client-concepts/connection-pooling/round-robin/skip-dead-nodes.asciidoc +++ b/docs/client-concepts/connection-pooling/round-robin/skip-dead-nodes.asciidoc @@ -142,7 +142,9 @@ await audit.TraceCalls( ); ---- <1> The first call goes to 9200 which succeeds + <2> The 2nd call does a ping on 9201 because its used for the first time. It fails so we wrap over to node 9202 + <3> The next call goes to 9203 which fails so we should wrap over A cluster with 2 nodes where the second node fails on ping @@ -192,5 +194,6 @@ await audit.TraceCalls( ); ---- <1> All the calls fail + <2> After all our registered nodes are marked dead we want to sample a single dead node each time to quickly see if the cluster is back up. We do not want to retry all 4 nodes diff --git a/docs/client-concepts/high-level/analysis/writing-analyzers.asciidoc b/docs/client-concepts/high-level/analysis/writing-analyzers.asciidoc index 486b090d039..91d5a699824 100644 --- a/docs/client-concepts/high-level/analysis/writing-analyzers.asciidoc +++ b/docs/client-concepts/high-level/analysis/writing-analyzers.asciidoc @@ -102,6 +102,7 @@ var createIndexResponse = client.CreateIndex("my-index", c => c ); ---- <1> Pre-defined list of English stopwords within Elasticsearch + <2> Use the `standard_english` analyzer configured [source,javascript] @@ -267,6 +268,7 @@ var createIndexResponse = client.CreateIndex("questions", c => c ); ---- <1> Use an analyzer at index time that strips HTML tags + <2> Use an analyzer at search time that does not strip HTML tags With this in place, the text of a question body will be analyzed with the `index_question` analyzer diff --git a/docs/client-concepts/high-level/getting-started.asciidoc b/docs/client-concepts/high-level/getting-started.asciidoc index 36e41d7707e..6150fd3dc33 100644 --- a/docs/client-concepts/high-level/getting-started.asciidoc +++ b/docs/client-concepts/high-level/getting-started.asciidoc @@ -109,6 +109,7 @@ var indexResponse = client.Index(person); <1> var asyncIndexResponse = await client.IndexAsync(person); <2> ---- <1> synchronous method that returns an `IIndexResponse` + <2> asynchronous method that returns a `Task` that can be awaited NOTE: All methods available within NEST are exposed as both synchronous and asynchronous versions, diff --git a/docs/client-concepts/high-level/inference/field-inference.asciidoc b/docs/client-concepts/high-level/inference/field-inference.asciidoc index 867467dd8d5..c7a24d33ca7 100644 --- a/docs/client-concepts/high-level/inference/field-inference.asciidoc +++ b/docs/client-concepts/high-level/inference/field-inference.asciidoc @@ -473,9 +473,13 @@ class Precedence } ---- <1> Even though this property has a NEST property mapping _and_ a `JsonProperty` attribute, We are going to provide a hard rename for it on ConnectionSettings later that should win. + <2> This property has both a NEST attribute and a `JsonProperty`, NEST should win. + <3> We should take the json property into account by itself + <4> This property we are going to special case in our custom serializer to resolve to ask + <5> We are going to register a DefaultFieldNameInferrer on ConnectionSettings that will uppercase all properties. Here we create a custom serializer that renames any property named `AskSerializer` to `ask` diff --git a/docs/client-concepts/high-level/inference/indices-paths.asciidoc b/docs/client-concepts/high-level/inference/indices-paths.asciidoc index 2b7fe31b5cd..21227fd346a 100644 --- a/docs/client-concepts/high-level/inference/indices-paths.asciidoc +++ b/docs/client-concepts/high-level/inference/indices-paths.asciidoc @@ -90,6 +90,7 @@ singleIndexFromIndexName.Match( ); ---- <1> `_all` will override any specific index names here + <2> The `Project` type has been mapped to a specific index name using <`>> [[nest-indices]] @@ -120,7 +121,9 @@ ISearchRequest singleTypedRequest = new SearchDescriptor().Index(single var invalidSingleString = Nest.Indices.Index("name1, name2"); <3> ---- <1> specifying a single index using a string + <2> specifying a single index using a type + <3> an **invalid** single index name ===== Multiple indices @@ -145,7 +148,9 @@ manyStringRequest = new SearchDescriptor().Type(new[] { "name1", "name2 ((IUrlParameter)manyStringRequest.Type).GetString(client.ConnectionSettings).Should().Be("name1,name2"); ---- <1> specifying multiple indices using strings + <2> specifying multiple indices using types + <3> The index names here come from the Connection Settings passed to `TestClient`. See the documentation on <> for more details. ===== All Indices diff --git a/docs/client-concepts/high-level/mapping/auto-map.asciidoc b/docs/client-concepts/high-level/mapping/auto-map.asciidoc index db661474b52..9a5cb1530f8 100644 --- a/docs/client-concepts/high-level/mapping/auto-map.asciidoc +++ b/docs/client-concepts/high-level/mapping/auto-map.asciidoc @@ -58,6 +58,7 @@ var descriptor = new CreateIndexDescriptor("myindex") ); ---- <1> Auto map `Company` + <2> Auto map `Employee` [source,javascript] diff --git a/docs/client-concepts/high-level/mapping/fluent-mapping.asciidoc b/docs/client-concepts/high-level/mapping/fluent-mapping.asciidoc index 1f8e87be255..0e5b365058f 100644 --- a/docs/client-concepts/high-level/mapping/fluent-mapping.asciidoc +++ b/docs/client-concepts/high-level/mapping/fluent-mapping.asciidoc @@ -277,8 +277,11 @@ var descriptor = new CreateIndexDescriptor("myindex") ); ---- <1> Automap company + <2> Override company inferred mappings + <3> Auto map employee + <4> Override employee inferred mappings [source,javascript] @@ -401,8 +404,11 @@ var descriptor = new CreateIndexDescriptor("myindex") ); ---- <1> Automap `Company` + <2> Override specific `Company` mappings + <3> Automap `Employees` property + <4> Override specific `Employee` properties [source,javascript] diff --git a/docs/client-concepts/high-level/mapping/multi-fields.asciidoc b/docs/client-concepts/high-level/mapping/multi-fields.asciidoc index c23e0393877..91abaa792b5 100644 --- a/docs/client-concepts/high-level/mapping/multi-fields.asciidoc +++ b/docs/client-concepts/high-level/mapping/multi-fields.asciidoc @@ -65,7 +65,9 @@ var descriptor = new CreateIndexDescriptor("myindex") ); ---- <1> Use the stop analyzer on this sub field + <2> Use a custom analyzer named "named_shingles" that is configured in the index + <3> Index as not analyzed [source,javascript] @@ -135,6 +137,7 @@ var searchResponse = client.Search(s => s ); ---- <1> Use the shingles subfield on `Name` + <2> Use the keyword subfield on `Name` [source,javascript] diff --git a/docs/client-concepts/high-level/mapping/visitor-pattern-mapping.asciidoc b/docs/client-concepts/high-level/mapping/visitor-pattern-mapping.asciidoc index 02f352dafb8..b797938b62f 100644 --- a/docs/client-concepts/high-level/mapping/visitor-pattern-mapping.asciidoc +++ b/docs/client-concepts/high-level/mapping/visitor-pattern-mapping.asciidoc @@ -73,6 +73,7 @@ public class DisableDocValuesPropertyVisitor : NoopPropertyVisitor } ---- <1> Override the `Visit` method on `INumberProperty` and set `DocValues = false` + <2> Similarily, override the `Visit` method on `IBooleanProperty` and set `DocValues = false` Now we can pass an instance of our custom visitor to `.AutoMap()` diff --git a/docs/client-concepts/low-level/connecting.asciidoc b/docs/client-concepts/low-level/connecting.asciidoc index 0e212e37fec..404f870fc44 100644 --- a/docs/client-concepts/low-level/connecting.asciidoc +++ b/docs/client-concepts/low-level/connecting.asciidoc @@ -86,7 +86,9 @@ var client = new ElasticLowLevelClient(config); var result = client.Search>(new { size = 12 }); ---- <1> Disable automatic proxy detection. When called, defaults to `true`. + <2> Enable compressed request and responses from Elasticsearch (Note that nodes need to be configured to allow this. See the {ref_current}/modules-http.html[http module settings] for more info). + <3> By default responses are deserialized directly from the response stream to the object you tell it to. For debugging purposes, it can be very useful to keep a copy of the raw response on the result object, which is what calling this method will do. `.ResponseBodyInBytes` will only have a value if the client configuration has `DisableDirectStreaming` set @@ -124,10 +126,15 @@ config = config .BasicAuthentication("username", "password"); <6> ---- <1> Allows you to set querystring parameters that have to be added to every request. For instance, if you use a hosted elasticserch provider, and you need need to pass an `apiKey` parameter onto every request. + <2> Sets proxy information on the connection. + <3> [[request-timeout]] Sets the global maximum time a connection may take. Please note that this is the request timeout, the builtin .NET `WebRequest` has no way to set connection timeouts (see http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.timeout(v=vs.110).aspx[the MSDN documentation on `HttpWebRequest.Timeout` Property]). + <4> As an alternative to the C/go like error checking on `response.IsValid`, you can instead tell the client to <>. + <5> forces all serialization to be indented and appends `pretty=true` to all the requests so that the responses are indented as well + <6> sets the HTTP basic authentication credentials to specify with all requests. NOTE: Basic authentication credentials can alternatively be specified on the node URI directly: @@ -309,7 +316,9 @@ public class MyJsonNetSerializer : JsonNetSerializer } ---- <1> Call this constructor if you only need access to `JsonSerializerSettings` without local state + <2> Call OverwriteDefaultSerializers if you need access to `JsonSerializerSettings` with local state + <3> You can inject contract resolved converters by implementing the ContractConverters property. This can be much faster then registering them on `JsonSerializerSettings.Converters` You can then register a factory on `ConnectionSettings` to create an instance of your subclass instead. diff --git a/docs/client-concepts/low-level/getting-started.asciidoc b/docs/client-concepts/low-level/getting-started.asciidoc index c23bd167bd4..de6ccf1a725 100644 --- a/docs/client-concepts/low-level/getting-started.asciidoc +++ b/docs/client-concepts/low-level/getting-started.asciidoc @@ -108,6 +108,7 @@ var asyncIndexResponse = await lowlevelClient.IndexAsync("people", "pers string responseString = asyncIndexResponse.Body; ---- <1> synchronous method that returns an `IIndexResponse` + <2> asynchronous method that returns a `Task` that can be awaited NOTE: All available methods within Elasticsearch.Net are exposed as both synchronous and asynchronous versions, @@ -243,8 +244,11 @@ var serverError = searchResponse.ServerError; <3> var exception = searchResponse.OriginalException; <4> ---- <1> Response is in the 200 range, or an expected response for the given request + <2> Response is successful, or has a response code between 400-599 that indicates the request cannot be retried. + <3> Details of any error returned from Elasticsearch + <4> If the response is unsuccessful, will hold the original exception. Using these details, it is possible to make decisions around what should be done in your application. diff --git a/docs/client-concepts/troubleshooting/logging-with-on-request-completed.asciidoc b/docs/client-concepts/troubleshooting/logging-with-on-request-completed.asciidoc index e91d5a94823..b2d9c6a4347 100644 --- a/docs/client-concepts/troubleshooting/logging-with-on-request-completed.asciidoc +++ b/docs/client-concepts/troubleshooting/logging-with-on-request-completed.asciidoc @@ -39,7 +39,9 @@ await client.RootNodeInfoAsync(); <3> counter.Should().Be(2); ---- <1> Construct a client + <2> Make a synchronous call and assert the counter is incremented + <3> Make an asynchronous call and assert the counter is incremented `OnRequestCompleted` is called even when an exception is thrown, so it can be used even if the client is @@ -63,7 +65,9 @@ await Assert.ThrowsAsync(async () => await client. counter.Should().Be(2); ---- <1> Configure a client with a connection that **always returns a HTTP 500 response + <2> Always throw exceptions when a call results in an exception + <3> Assert an exception is thrown and the counter is incremented Here's an example using `OnRequestCompleted()` for more complex logging @@ -144,10 +148,15 @@ list.ShouldAllBeEquivalentTo(new[] <6> }); ---- <1> Here we use `InMemoryConnection` but in a real application, you'd use an `IConnection` that _actually_ sends the request, such as `HttpConnection` + <2> Disable direct streaming so we can capture the request and response bytes + <3> Perform some action when a request completes. Here, we're just adding to a list, but in your application you may be logging to a file. + <4> Make a synchronous call + <5> Make an asynchronous call + <6> Assert the list contains the contents written in the delegate passed to `OnRequestCompleted` When running an application in production, you probably don't want to disable direct streaming for _all_ @@ -227,7 +236,10 @@ list.ShouldAllBeEquivalentTo(new[] }); ---- <1> Make a synchronous call where the request and response bytes will not be buffered + <2> Make an asynchronous call where `DisableDirectStreaming()` is enabled + <3> Only the method and url for the first request is captured + <4> the body of the second request is captured diff --git a/docs/code-standards/elastic-client.asciidoc b/docs/code-standards/elastic-client.asciidoc index 5e538a1c105..0a9c81491af 100644 --- a/docs/code-standards/elastic-client.asciidoc +++ b/docs/code-standards/elastic-client.asciidoc @@ -105,15 +105,15 @@ private class MethodWithRequestParameter { public string Name { get; } - public MethodInfo MethodInfo { get; } + public MethodInfo MethodInfo { get; } public bool IsAsync { get; } public ClientMethodType MethodType { get; } - public ParameterInfo Parameter { get; } + public ParameterInfo Parameter { get; } - public MethodWithRequestParameter(MethodInfo methodInfo) + public MethodWithRequestParameter(MethodInfo methodInfo) { Name = methodInfo.Name.EndsWith("Async") ? methodInfo.Name.Substring(0, methodInfo.Name.Length - "Async".Length) diff --git a/docs/search/returned-fields.asciidoc b/docs/search/returned-fields.asciidoc index b7196ea9a54..63300584cae 100644 --- a/docs/search/returned-fields.asciidoc +++ b/docs/search/returned-fields.asciidoc @@ -113,7 +113,9 @@ var searchResponse = client.Search(s => s ); ---- <1> **Include** the following fields + <2> **Exclude** the following fields + <3> Fields can be included or excluded through patterns With source filtering specified on the request, `.Documents` will diff --git a/docs/search/writing-queries.asciidoc b/docs/search/writing-queries.asciidoc index c29fc7e6978..f3900cbd7bd 100644 --- a/docs/search/writing-queries.asciidoc +++ b/docs/search/writing-queries.asciidoc @@ -279,7 +279,9 @@ var searchResponse = client.Search(s => s ); ---- <1> match documents where lead developer first name contains Russ + <2> ...and where the lead developer last name contains Cam + <3> ...and where the project started in 2017 which yields the following query JSON @@ -354,6 +356,7 @@ searchResponse = client.Search(s => s ); ---- <1> combine queries using the binary `&&` operator + <2> wrap a query in a `bool` query filter clause using the unary `+` operator and combine using the binary `&&` operator Take a look at the dedicated section on <> for more detail diff --git a/src/Nest/CommonAbstractions/DictionaryLike/IsADictionaryBase.cs b/src/Nest/CommonAbstractions/DictionaryLike/IsADictionaryBase.cs index 79fc358491f..707e9a74721 100644 --- a/src/Nest/CommonAbstractions/DictionaryLike/IsADictionaryBase.cs +++ b/src/Nest/CommonAbstractions/DictionaryLike/IsADictionaryBase.cs @@ -11,7 +11,7 @@ public abstract class IsADictionaryBase : IIsADictionary BackingDictionary { get; } private IDictionary Self => BackingDictionary; - protected IsADictionaryBase() { this.BackingDictionary = new Dictionary(); } + protected IsADictionaryBase() => this.BackingDictionary = new Dictionary(); //protected IsADictionaryBase(Dictionary backingDictionary) { this.BackingDictionary = backingDictionary; } protected IsADictionaryBase(IDictionary backingDictionary) { @@ -22,9 +22,9 @@ protected IsADictionaryBase(IDictionary backingDictionary) ? new Dictionary(backingDictionary) : new Dictionary(); } + IDictionaryEnumerator IDictionary.GetEnumerator() => Self?.GetEnumerator(); void IDictionary.Clear() => this.BackingDictionary.Clear(); - IDictionaryEnumerator IDictionary.GetEnumerator() => Self?.GetEnumerator(); void IDictionary.Remove(object key) => Self?.Remove(key); object IDictionary.this[object key] { @@ -36,27 +36,27 @@ object IDictionary.this[object key] void IDictionary.Add(object key, object value) => Self?.Add(key, value); bool IDictionary.IsReadOnly=> (Self?.IsReadOnly).GetValueOrDefault(false); bool IDictionary.IsFixedSize=> (Self?.IsFixedSize).GetValueOrDefault(false); - ICollection IDictionary.Keys => Self?.Keys; + bool ICollection>.Remove(KeyValuePair item) => ((ICollection>)this.BackingDictionary).Remove(item); IEnumerator IEnumerable.GetEnumerator() => this.BackingDictionary.GetEnumerator(); + void ICollection>.Add(KeyValuePair item) + { + ValidateKey(item.Key); + ((ICollection>)this.BackingDictionary).Add(item); + } IEnumerator> IEnumerable>.GetEnumerator() => this.BackingDictionary.GetEnumerator(); //public IEnumerator> GetEnumerator() => this.BackingDictionary.GetEnumerator(); void ICollection>.Clear() => this.BackingDictionary.Clear(); + void ICollection.CopyTo(Array array, int index) => Self?.CopyTo(array, index); [EditorBrowsable(EditorBrowsableState.Never)] bool ICollection>.Contains(KeyValuePair item) => Self?.Contains(item) ?? false; + bool ICollection>.IsReadOnly => Self?.IsReadOnly ?? false; void ICollection>.CopyTo( KeyValuePair[] array, int arrayIndex) => Self?.CopyTo(array, arrayIndex); - void ICollection.CopyTo(Array array, int index) => Self?.CopyTo(array, index); + ICollection IDictionary.Keys => Self?.Keys; int ICollection>.Count => this.BackingDictionary.Count; - bool ICollection>.IsReadOnly => Self?.IsReadOnly ?? false; - bool ICollection>.Remove(KeyValuePair item) => ((ICollection>)this.BackingDictionary).Remove(item); - void ICollection>.Add(KeyValuePair item) - { - ValidateKey(item.Key); - ((ICollection>)this.BackingDictionary).Add(item); - } int ICollection.Count => (Self?.Count).GetValueOrDefault(0); object ICollection.SyncRoot => Self?.SyncRoot; @@ -67,26 +67,22 @@ void ICollection>.Add(KeyValuePair item bool IDictionary.ContainsKey(TKey key) => this.BackingDictionary.ContainsKey(key); void IDictionary.Add(TKey key, TValue value) => this.BackingDictionary.Add(ValidateKey(key), value); bool IDictionary.Remove(TKey key) => this.BackingDictionary.Remove(key); - bool IDictionary.TryGetValue(TKey key, out TValue value) => this.BackingDictionary.TryGetValue(key, out value); ICollection IDictionary.Keys => this.BackingDictionary.Keys; ICollection IDictionary.Values => this.BackingDictionary.Values; + bool IDictionary.TryGetValue(TKey key, out TValue value) => this.BackingDictionary.TryGetValue(key, out value); public virtual TKey ValidateKey(TKey key) => key; TValue IDictionary.this[TKey key] { - get { return this.BackingDictionary[key]; } - set { this.BackingDictionary[ValidateKey(key)] = value; } + get => this.BackingDictionary[key]; + set => this.BackingDictionary[ValidateKey(key)] = value; } public TValue this[TKey key] { - get { return this.BackingDictionary[key]; } - set { this.BackingDictionary[ValidateKey(key)] = value; } + get => this.BackingDictionary[key]; + set => this.BackingDictionary[ValidateKey(key)] = value; } - - } - - } diff --git a/src/Nest/IndexModules/IndexSettings/IndexState.cs b/src/Nest/IndexModules/IndexSettings/IndexState.cs index 7e745d09815..e9bcbf33fe8 100644 --- a/src/Nest/IndexModules/IndexSettings/IndexState.cs +++ b/src/Nest/IndexModules/IndexSettings/IndexState.cs @@ -1,4 +1,5 @@ -using Newtonsoft.Json; +using System; +using Newtonsoft.Json; namespace Nest { @@ -17,24 +18,21 @@ public interface IIndexState [JsonProperty("mappings")] IMappings Mappings { get; set; } - [JsonProperty("similarity")] + [JsonIgnore] + [Obsolete("Use Similarity within Settings. Removed in NEST 6.x")] ISimilarities Similarity { get; set; } } public class IndexState : IIndexState { public IIndexSettings Settings { get; set; } - + public IMappings Mappings { get; set; } public IAliases Aliases { get; set; } - + public IWarmers Warmers { get; set; } + [Obsolete("Use Similarity within Settings. Removed in NEST 6.x")] public ISimilarities Similarity { get; set; } } - - - - - -} \ No newline at end of file +} diff --git a/src/Nest/IndexModules/IndexSettings/Settings/DynamicIndexSettings.cs b/src/Nest/IndexModules/IndexSettings/Settings/DynamicIndexSettings.cs index 6c4f728c127..43cc77a9995 100644 --- a/src/Nest/IndexModules/IndexSettings/Settings/DynamicIndexSettings.cs +++ b/src/Nest/IndexModules/IndexSettings/Settings/DynamicIndexSettings.cs @@ -8,13 +8,13 @@ namespace Nest public interface IDynamicIndexSettings : IIsADictionary { /// - ///The number of replicas each primary shard has. Defaults to 1. + ///The number of replicas each primary shard has. Defaults to 1. /// int? NumberOfReplicas { get; set; } /// - ///Auto-expand the number of replicas based on the number of available nodes. - /// Set to a dash delimited lower and upper bound (e.g. 0-5) or use all for the upper bound (e.g. 0-all). Defaults to false (i.e. disabled). + ///Auto-expand the number of replicas based on the number of available nodes. + /// Set to a dash delimited lower and upper bound (e.g. 0-5) or use all for the upper bound (e.g. 0-all). Defaults to false (i.e. disabled). /// //TODO SPECIAL TYPE FOR THIS INSTEAD OF JUST STRING string AutoExpandReplicas { get; set; } @@ -51,17 +51,17 @@ public interface IDynamicIndexSettings : IIsADictionary int? Priority { get; set; } /// - /// Index warmup can be disabled by setting index.warmer.enabled to false. This can be handy when - /// doing initial bulk indexing: disable pre registered warmers to make indexing faster + /// Index warmup can be disabled by setting index.warmer.enabled to false. This can be handy when + /// doing initial bulk indexing: disable pre registered warmers to make indexing faster /// and less expensive and then enable it. /// bool? WarmersEnabled { get; set; } /// /// When a search request is run against an index or against many indices, each involved shard executes the search locally and - /// returns its local results to the coordinating node, which combines these shard-level results into a global result set. + /// returns its local results to the coordinating node, which combines these shard-level results into a “global” result set. /// - /// The shard-level request cache module caches the local results on each shard.This allows frequently used + /// The shard-level request cache module caches the local results on each shard.This allows frequently used /// (and potentially heavy) search requests to return results almost instantly. /// bool? RequestCacheEnabled { get; set; } @@ -73,7 +73,7 @@ public interface IDynamicIndexSettings : IIsADictionary Union RecoveryInitialShards { get; set; } /// - /// The allocation of replica shards which become unassigned because a node has left can be + /// The allocation of replica shards which become unassigned because a node has left can be /// delayed with this dynamic setting, which defaults to 1m. /// Time UnassignedNodeLeftDelayedTimeout { get; set; } @@ -99,6 +99,11 @@ public interface IDynamicIndexSettings : IIsADictionary ITranslogSettings Translog { get; set; } IAnalysis Analysis { get; set; } + + /// + /// Configure similarity + /// + ISimilarities Similarity { get; set; } } public class DynamicIndexSettings : IsADictionaryBase, IDynamicIndexSettings @@ -120,46 +125,49 @@ public DynamicIndexSettings(Dictionary container) /// public bool? BlocksReadOnly { get; set; } - + /// public bool? BlocksWrite { get; set; } - + /// public int? Priority { get; set; } - + /// public bool? WarmersEnabled { get; set; } - + /// public bool? RequestCacheEnabled { get; set; } - + /// public IMergeSettings Merge { get; set; } - + /// public int? NumberOfReplicas { get; set; } - + /// public Union RecoveryInitialShards { get; set; } - + /// public Time RefreshInterval { get; set; } - + /// public int? RoutingAllocationTotalShardsPerNode { get; set; } - + /// public ISlowLog SlowLog { get; set; } - + /// public ITranslogSettings Translog { get; set; } - + /// public Time UnassignedNodeLeftDelayedTimeout { get; set; } /// public IAnalysis Analysis { get; set; } + /// + public ISimilarities Similarity { get; set; } + /// /// Add any setting to the index /// @@ -242,8 +250,13 @@ public TDescriptor Translog(Func public TDescriptor UnassignedNodeLeftDelayedTimeout(Time time) => Assign(a => a.UnassignedNodeLeftDelayedTimeout = time); + /// public TDescriptor Analysis(Func selector) => Assign(a => a.Analysis = selector?.Invoke(new AnalysisDescriptor())); + + /// + public TDescriptor Similarity(Func> selector) => + Assign(a => a.Similarity = selector?.Invoke(new SimilaritiesDescriptor())?.Value); } -} \ No newline at end of file +} diff --git a/src/Nest/IndexModules/IndexSettings/Settings/IndexSettingsConverter.cs b/src/Nest/IndexModules/IndexSettings/Settings/IndexSettingsConverter.cs index 2cbc02e01eb..b58d840e7d2 100644 --- a/src/Nest/IndexModules/IndexSettings/Settings/IndexSettingsConverter.cs +++ b/src/Nest/IndexModules/IndexSettings/Settings/IndexSettingsConverter.cs @@ -1,221 +1,226 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; - -namespace Nest -{ - internal class IndexSettingsConverter : VerbatimDictionaryKeysJsonConverter - { - public override bool CanRead => true; - public override bool CanWrite => true; - public override bool CanConvert(Type objectType) => true; - - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - var ds = value as IDynamicIndexSettings ?? (value as IUpdateIndexSettingsRequest)?.IndexSettings; - ; - if (ds == null) return; - - IDictionary d = ds; - - d[UpdatableIndexSettings.NumberOfReplicas] = ds.NumberOfReplicas; - d[UpdatableIndexSettings.AutoExpandReplicas] = ds.AutoExpandReplicas; - d[UpdatableIndexSettings.RefreshInterval] = ds.RefreshInterval; - d[UpdatableIndexSettings.BlocksReadOnly] = ds.BlocksReadOnly; - d[UpdatableIndexSettings.BlocksRead] = ds.BlocksRead; - d[UpdatableIndexSettings.BlocksWrite] = ds.BlocksWrite; - d[UpdatableIndexSettings.BlocksMetadata] = ds.BlocksMetadata; - d[UpdatableIndexSettings.Priority] = ds.Priority; - d[UpdatableIndexSettings.WarmersEnabled] = ds.WarmersEnabled; - d[UpdatableIndexSettings.RequestCacheEnable] = ds.RequestCacheEnabled; - d[UpdatableIndexSettings.RecoveryInitialShards] = ds.RecoveryInitialShards; - d[UpdatableIndexSettings.RoutingAllocationTotalShardsPerNode] = - ds.RoutingAllocationTotalShardsPerNode; - d[UpdatableIndexSettings.UnassignedNodeLeftDelayedTimeout] = ds.UnassignedNodeLeftDelayedTimeout; - - var translog = ds.Translog; - d[UpdatableIndexSettings.TranslogSyncInterval] = translog?.SyncInterval; - d[UpdatableIndexSettings.TranslogDurability] = translog?.Durability; - d[UpdatableIndexSettings.TranslogFsType] = translog?.FileSystemType; - - var flush = ds.Translog?.Flush; - d[UpdatableIndexSettings.TranslogFlushThresholdSize] = flush?.ThresholdSize; - d[UpdatableIndexSettings.TranslogFlushTreshHoldOps] = flush?.ThresholdOps; - d[UpdatableIndexSettings.TranslogFlushThresholdPeriod] = flush?.ThresholdPeriod; - d[UpdatableIndexSettings.TranslogInterval] = flush?.Interval; - - d[UpdatableIndexSettings.MergePolicyExpungeDeletesAllowed] = ds.Merge?.Policy?.ExpungeDeletesAllowed; - d[UpdatableIndexSettings.MergePolicyFloorSegment] = ds.Merge?.Policy?.FloorSegment; - d[UpdatableIndexSettings.MergePolicyMaxMergeAtOnce] = ds.Merge?.Policy?.MaxMergeAtOnce; - d[UpdatableIndexSettings.MergePolicyMaxMergeAtOnceExplicit] = ds.Merge?.Policy?.MaxMergeAtOnceExplicit; - d[UpdatableIndexSettings.MergePolicyMaxMergedSegment] = ds.Merge?.Policy?.MaxMergedSegment; - d[UpdatableIndexSettings.MergePolicySegmentsPerTier] = ds.Merge?.Policy?.SegmentsPerTier; - d[UpdatableIndexSettings.MergePolicyReclaimDeletesWeight] = ds.Merge?.Policy?.ReclaimDeletesWeight; - - d[UpdatableIndexSettings.MergeSchedulerMaxThreadCount] = ds.Merge?.Scheduler?.MaxThreadCount; - d[UpdatableIndexSettings.MergeSchedulerAutoThrottle] = ds.Merge?.Scheduler?.AutoThrottle; - - var log = ds.SlowLog; - var search = log?.Search; - var indexing = log?.Indexing; - - d[UpdatableIndexSettings.SlowlogSearchThresholdQueryWarn] = search?.Query?.ThresholdWarn; - d[UpdatableIndexSettings.SlowlogSearchThresholdQueryInfo] = search?.Query?.ThresholdInfo; - d[UpdatableIndexSettings.SlowlogSearchThresholdQueryDebug] = search?.Query?.ThresholdDebug; - d[UpdatableIndexSettings.SlowlogSearchThresholdQueryTrace] = search?.Query?.ThresholdTrace; - - d[UpdatableIndexSettings.SlowlogSearchThresholdFetchWarn] = search?.Fetch?.ThresholdWarn; - d[UpdatableIndexSettings.SlowlogSearchThresholdFetchInfo] = search?.Fetch?.ThresholdInfo; - d[UpdatableIndexSettings.SlowlogSearchThresholdFetchDebug] = search?.Fetch?.ThresholdDebug; - d[UpdatableIndexSettings.SlowlogSearchThresholdFetchTrace] = search?.Fetch?.ThresholdTrace; - d[UpdatableIndexSettings.SlowlogSearchLevel] = search?.LogLevel; - - d[UpdatableIndexSettings.SlowlogIndexingThresholdFetchWarn] = indexing?.ThresholdWarn; - d[UpdatableIndexSettings.SlowlogIndexingThresholdFetchInfo] = indexing?.ThresholdInfo; - d[UpdatableIndexSettings.SlowlogIndexingThresholdFetchDebug] = indexing?.ThresholdDebug; - d[UpdatableIndexSettings.SlowlogIndexingThresholdFetchTrace] = indexing?.ThresholdTrace; - d[UpdatableIndexSettings.SlowlogIndexingLevel] = indexing?.LogLevel; - d[UpdatableIndexSettings.SlowlogIndexingSource] = indexing?.Source; - - - var indexSettings = value as IIndexSettings; - d["index.number_of_shards"] = indexSettings?.NumberOfShards; - d["index.store.type"] = indexSettings?.FileSystemStorageImplementation; - - d["analysis"] = ds.Analysis; - base.WriteJson(writer, d, serializer); - } - - - public JObject Flatten(JObject original, string prefix = "", JObject newObject = null) - { - newObject = newObject ?? new JObject(); - foreach (var property in original.Properties()) - { - if (property.Value is JObject && property.Name != "analysis") - Flatten(property.Value.Value(), prefix + property.Name + ".", newObject); - else newObject.Add(prefix + property.Name, property.Value); - } - return newObject; - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - var s = new IndexSettings(); - SetKnownIndexSettings(reader, serializer, s); - if (!typeof (IUpdateIndexSettingsRequest).IsAssignableFrom(objectType)) return s; - - var request = new UpdateIndexSettingsRequest() { IndexSettings = s}; - return request; - } - - private void SetKnownIndexSettings(JsonReader reader, JsonSerializer serializer, IIndexSettings s) - { - var settings = Flatten(JObject.Load(reader)).Properties().ToDictionary(kv => kv.Name); - - Set(s, settings, UpdatableIndexSettings.NumberOfReplicas, v => s.NumberOfReplicas = v); - Set(s, settings, UpdatableIndexSettings.AutoExpandReplicas, v => s.AutoExpandReplicas = v); - Set