/* SPDX-License-Identifier: Apache-2.0 * * The OpenSearch Contributors require contributions made to * this file be licensed under the Apache-2.0 license or a * compatible open source license. */ /* * Modifications Copyright OpenSearch Contributors. See * GitHub history for details. * * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright * ownership. Elasticsearch B.V. licenses this file to you under * the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ using OpenSearch.OpenSearch.Xunit.XunitPlumbing; using OpenSearch.Net; using FluentAssertions; using OpenSearch.Client; using Tests.Core.Client; using Tests.Domain; using Tests.Framework; using Tests.Framework.DocumentationTests; using static OpenSearch.Client.Indices; namespace Tests.ClientConcepts.HighLevel.Inference { public class IndicesPaths : DocumentationTestBase { /**[[indices-paths]] * === Indices paths * * Some APIs in OpenSearch take an index name, a collection of index names, * or the special `_all` marker (used to specify all indices), in the URI path of the request, to specify the indices that * the request should execute against. * * In OSC, these index names can be specified using the `Indices` type. * * ==== Implicit Conversion * * To make working with `Indices` easier, several types implicitly convert to it: * * - `string` * - comma separated `string` * - `string` array * - a CLR type, <<index-name-inference, where a default index name or index name for the type has been specified on `ConnectionSettings`>> * - `IndexName` * - `IndexName` array * * Here are some examples of how implicit conversions can be used to specify index names */ [U] public void ImplicitConversions() { OpenSearch.Client.Indices singleIndexFromString = "name"; OpenSearch.Client.Indices multipleIndicesFromString = "name1, name2"; OpenSearch.Client.Indices multipleIndicesFromStringArray = new [] { "name1", "name2" }; OpenSearch.Client.Indices allFromString = "_all"; OpenSearch.Client.Indices allWithOthersFromString = "_all, name2"; //<1> `_all` will override any specific index names here OpenSearch.Client.Indices singleIndexFromType = typeof(Project); //<2> The `Project` type has been mapped to a specific index name using <<index-name-type-mapping,`.DefaultMappingFor<Project>`>> OpenSearch.Client.Indices singleIndexFromIndexName = IndexName.From<Project>(); singleIndexFromString.Match( all => all.Should().BeNull(), many => many.Indices.Should().HaveCount(1).And.Contain("name") ); multipleIndicesFromString.Match( all => all.Should().BeNull(), many => many.Indices.Should().HaveCount(2).And.Contain("name2") ); allFromString.Match( all => all.Should().NotBeNull(), many => many.Indices.Should().BeNull() ); allWithOthersFromString.Match( all => all.Should().NotBeNull(), many => many.Indices.Should().BeNull() ); multipleIndicesFromStringArray.Match( all => all.Should().BeNull(), many => many.Indices.Should().HaveCount(2).And.Contain("name2") ); singleIndexFromType.Match( all => all.Should().BeNull(), many => many.Indices.Should().HaveCount(1).And.Contain(typeof(Project)) ); singleIndexFromIndexName.Match( all => all.Should().BeNull(), many => many.Indices.Should().HaveCount(1).And.Contain(typeof(Project)) ); } /** * [[osc-indices]] *==== Using OpenSearch.Client.Indices methods * To make creating `IndexName` or `Indices` instances easier, `OpenSearch.Client.Indices` also contains several static methods * that can be used to construct them. * *===== Single index * * A single index can be specified using a CLR type or a string, and the `.Index()` method. * * [TIP] * ==== * This example uses the static import `using static OpenSearch.Client.Indices;` in the using directives to shorthand `OpenSearch.Client.Indices.Index()` * to simply `Index()`. Be sure to include this static import if copying any of these examples. * ==== */ [U] public void UsingStaticPropertyField() { var client = TestClient.Default; var singleString = Index("name1"); // <1> specifying a single index using a string var singleTyped = Index<Project>(); //<2> specifying a single index using a type ISearchRequest singleStringRequest = new SearchDescriptor<Project>().Index(singleString); ISearchRequest singleTypedRequest = new SearchDescriptor<Project>().Index(singleTyped); ((IUrlParameter)singleStringRequest.Index).GetString(this.Client.ConnectionSettings).Should().Be("name1"); ((IUrlParameter)singleTypedRequest.Index).GetString(this.Client.ConnectionSettings).Should().Be("project"); var invalidSingleString = Index("name1, name2"); //<3> an **invalid** single index name } /**===== Multiple indices * * Similarly to a single index, multiple indices can be specified using multiple CLR types or multiple strings */ [U] public void MultipleIndices() { var manyStrings = Index("name1", "name2"); //<1> specifying multiple indices using strings var manyTypes = Index<Project>().And<Developer>(); //<2> specifying multiple indices using types var client = TestClient.Default; ISearchRequest manyStringRequest = new SearchDescriptor<Project>().Index(manyStrings); ISearchRequest manyTypedRequest = new SearchDescriptor<Project>().Index(manyTypes); ((IUrlParameter)manyStringRequest.Index).GetString(this.Client.ConnectionSettings).Should().Be("name1,name2"); ((IUrlParameter)manyTypedRequest.Index).GetString(this.Client.ConnectionSettings).Should().Be("project,devs"); // <3> The index names here come from the Connection Settings passed to `TestClient`. See the documentation on <<index-name-inference, Index Name Inference>> for more details. manyStringRequest = new SearchDescriptor<Project>().Index(new[] { "name1", "name2" }); ((IUrlParameter)manyStringRequest.Index).GetString(this.Client.ConnectionSettings).Should().Be("name1,name2"); } /**===== All Indices * * OpenSearch allows searching across multiple indices using the special `_all` marker. * * OSC exposes the `_all` marker with `Indices.All` and `Indices.AllIndices`. Why expose it in two ways, you ask? * Well, you may be using both `OpenSearch.Client.Indices` and `OpenSearch.Client.Types` in the same file and you may also be using C#6 * static imports too; in this scenario, the `All` property becomes ambiguous between `Indices.All` and `Types.All`, so the * `_all` marker for indices is exposed as `Indices.AllIndices`, to alleviate this ambiguity */ [U] public void IndicesAllAndAllIndicesSpecifiedWhenUsingStaticUsingDirective() { var indicesAll = All; var allIndices = AllIndices; ISearchRequest indicesAllRequest = new SearchDescriptor<Project>().Index(indicesAll); ISearchRequest allIndicesRequest = new SearchDescriptor<Project>().Index(allIndices); ((IUrlParameter)indicesAllRequest.Index).GetString(this.Client.ConnectionSettings).Should().Be("_all"); ((IUrlParameter)allIndicesRequest.Index).GetString(this.Client.ConnectionSettings).Should().Be("_all"); } } }