Skip to content

Commit e7a556d

Browse files
jaymodeSivagurunathanV
authored andcommitted
Introduce hidden indices (elastic#50452)
This change introduces a new feature for indices so that they can be hidden from wildcard expansion. The feature is referred to as hidden indices. An index can be marked hidden through the use of an index setting, `index.hidden`, at creation time. One primary use case for this feature is to have a construct that fits indices that are created by the stack that contain data used for display to the user and/or intended for querying by the user. The desire to keep them hidden is to avoid confusing users when searching all of the data they have indexed and getting results returned from indices created by the system. Hidden indices have the following properties: * API calls for all indices (empty indices array, _all, or *) will not return hidden indices by default. * Wildcard expansion will not return hidden indices by default unless the wildcard pattern begins with a `.`. This behavior is similar to shell expansion of wildcards. * REST API calls can enable the expansion of wildcards to hidden indices with the `expand_wildcards` parameter. To expand wildcards to hidden indices, use the value `hidden` in conjunction with `open` and/or `closed`. * Creation of a hidden index will ignore global index templates. A global index template is one with a match-all pattern. * Index templates can make an index hidden, with the exception of a global index template. * Accessing a hidden index directly requires no additional parameters. Relates elastic#50251
1 parent 94d4b0a commit e7a556d

File tree

27 files changed

+930
-191
lines changed

27 files changed

+930
-191
lines changed

docs/reference/index-modules.asciidoc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,13 @@ indices.
7979
Indicates whether <<query-filter-context, cached filters>> are pre-loaded for
8080
nested queries. Possible values are `true` (default) and `false`.
8181

82+
`index.hidden`::
83+
84+
Indicates whether the index should be hidden by default. Hidden indices are not
85+
returned by default when using a wildcard expression. This behavior is controlled
86+
per request through the use of the `expand_wildcards` parameter. Possible values are
87+
`true` and `false` (default).
88+
8289
[float]
8390
[[dynamic-index-settings]]
8491
=== Dynamic index settings

docs/reference/rest-api/common-parms.asciidoc

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ Specifies what to do when the request:
5353
--
5454
* Contains wildcard expressions and there are no {transforms} that match.
5555
* Contains the `_all` string or no identifiers and there are no matches.
56-
* Contains wildcard expressions and there are only partial matches.
56+
* Contains wildcard expressions and there are only partial matches.
5757

5858
The default value is `true`, which returns an empty `transforms` array when
5959
there are no matches and the subset of results when there are partial matches.
@@ -69,7 +69,7 @@ Specifies what to do when the request:
6969
--
7070
* Contains wildcard expressions and there are no {transforms} that match.
7171
* Contains the `_all` string or no identifiers and there are no matches.
72-
* Contains wildcard expressions and there are only partial matches.
72+
* Contains wildcard expressions and there are only partial matches.
7373

7474
The default value is `true`, which returns a successful acknowledgement message
7575
when there are no matches. When there are only partial matches, the API stops
@@ -90,7 +90,7 @@ end::analyzer[]
9090

9191
tag::analyze_wildcard[]
9292
`analyze_wildcard`::
93-
(Optional, boolean) If `true`, wildcard and prefix queries are
93+
(Optional, boolean) If `true`, wildcard and prefix queries are
9494
analyzed. Defaults to `false`.
9595
end::analyze_wildcard[]
9696

@@ -118,7 +118,7 @@ end::completion-fields[]
118118

119119
tag::default_operator[]
120120
`default_operator`::
121-
(Optional, string) The default operator for query string query: AND or OR.
121+
(Optional, string) The default operator for query string query: AND or OR.
122122
Defaults to `OR`.
123123
end::default_operator[]
124124

@@ -144,7 +144,7 @@ end::detailed[]
144144

145145
tag::df[]
146146
`df`::
147-
(Optional, string) Field to use as default where no field prefix is
147+
(Optional, string) Field to use as default where no field prefix is
148148
given in the query string.
149149
end::df[]
150150

@@ -181,14 +181,17 @@ Expand only to open indices.
181181
`closed`::
182182
Expand only to closed indices.
183183

184+
`hidden`::
185+
Expansion of wildcards will include hidden indices.
186+
184187
`none`::
185188
Wildcard expressions are not accepted.
186189
--
187190
end::expand-wildcards[]
188191

189192
tag::field_statistics[]
190193
`field_statistics`::
191-
(Optional, boolean) If `true`, the response includes the document count, sum of document frequencies,
194+
(Optional, boolean) If `true`, the response includes the document count, sum of document frequencies,
192195
and sum of total term frequencies.
193196
Defaults to `true`.
194197
end::field_statistics[]
@@ -297,9 +300,9 @@ end::help[]
297300

298301
tag::bulk-id[]
299302
`_id`::
300-
(Optional, string)
303+
(Optional, string)
301304
The document ID.
302-
If no ID is specified, a document ID is automatically generated.
305+
If no ID is specified, a document ID is automatically generated.
303306
end::bulk-id[]
304307

305308
tag::if_primary_term[]
@@ -316,7 +319,7 @@ end::if_seq_no[]
316319

317320
tag::ignore_throttled[]
318321
`ignore_throttled`::
319-
(Optional, boolean) If `true`, concrete, expanded or aliased indices are
322+
(Optional, boolean) If `true`, concrete, expanded or aliased indices are
320323
ignored when throttled.
321324
end::ignore_throttled[]
322325

@@ -362,7 +365,7 @@ end::index[]
362365
tag::bulk-index[]
363366
`_index`::
364367
(Optional, string)
365-
The name of the target index.
368+
The name of the target index.
366369
Required if not specified as a path parameter.
367370
end::bulk-index[]
368371

@@ -447,7 +450,7 @@ end::index-template[]
447450

448451
tag::lenient[]
449452
`lenient`::
450-
(Optional, boolean) If `true`, format-based query failures (such as
453+
(Optional, boolean) If `true`, format-based query failures (such as
451454
providing text to a numeric field) will be ignored. Defaults to `false`.
452455
end::lenient[]
453456

@@ -618,13 +621,13 @@ end::search-q[]
618621

619622
tag::query[]
620623
`query`::
621-
(Optional, <<query-dsl,query object>>) Defines the search definition using the
624+
(Optional, <<query-dsl,query object>>) Defines the search definition using the
622625
<<query-dsl,Query DSL>>.
623626
end::query[]
624627

625628
tag::realtime[]
626629
`realtime`::
627-
(Optional, boolean) If `true`, the request is real-time as opposed to near-real-time.
630+
(Optional, boolean) If `true`, the request is real-time as opposed to near-real-time.
628631
Defaults to `true`. See <<realtime>>.
629632
end::realtime[]
630633

@@ -638,7 +641,7 @@ end::refresh[]
638641

639642
tag::request_cache[]
640643
`request_cache`::
641-
(Optional, boolean) If `true`, the request cache is used for this request.
644+
(Optional, boolean) If `true`, the request cache is used for this request.
642645
Defaults to the index-level setting.
643646
end::request_cache[]
644647

@@ -668,14 +671,14 @@ end::cat-s[]
668671

669672
tag::scroll[]
670673
`scroll`::
671-
(Optional, <<time-units, time units>>) Specifies how long a consistent view of
674+
(Optional, <<time-units, time units>>) Specifies how long a consistent view of
672675
the index should be maintained for scrolled search.
673676
end::scroll[]
674677

675678
tag::scroll_size[]
676679
`scroll_size`::
677-
(Optional, integer) Size of the scroll request that powers the operation.
678-
Defaults to 100.
680+
(Optional, integer) Size of the scroll request that powers the operation.
681+
Defaults to 100.
679682
end::scroll_size[]
680683

681684
tag::search_timeout[]
@@ -731,7 +734,7 @@ end::size-transforms[]
731734

732735
tag::slices[]
733736
`slices`::
734-
(Optional, integer) The number of slices this task should be divided into.
737+
(Optional, integer) The number of slices this task should be divided into.
735738
Defaults to 1 meaning the task isn't sliced into subtasks.
736739
end::slices[]
737740

@@ -742,24 +745,24 @@ end::sort[]
742745

743746
tag::source[]
744747
`_source`::
745-
(Optional, string) True or false to return the `_source` field or not, or a
748+
(Optional, string) True or false to return the `_source` field or not, or a
746749
list of fields to return.
747750
end::source[]
748751

749752
tag::source_excludes[]
750753
`_source_excludes`::
751-
(Optional, string) A list of fields to exclude from the returned `_source`
754+
(Optional, string) A list of fields to exclude from the returned `_source`
752755
field.
753756
end::source_excludes[]
754757

755758
tag::source_includes[]
756759
`_source_includes`::
757-
(Optional, string) A list of fields to extract and return from the `_source`
760+
(Optional, string) A list of fields to extract and return from the `_source`
758761
field.
759762
end::source_includes[]
760763

761764
tag::source-transforms[]
762-
The source of the data for the {transform}.
765+
The source of the data for the {transform}.
763766
end::source-transforms[]
764767

765768
tag::source-index-transforms[]
@@ -823,13 +826,13 @@ end::task-id[]
823826

824827
tag::term_statistics[]
825828
`term_statistics`::
826-
(Optional, boolean) If `true`, the response includes term frequency and document frequency.
829+
(Optional, boolean) If `true`, the response includes term frequency and document frequency.
827830
Defaults to `false`.
828831
end::term_statistics[]
829832

830833
tag::terminate_after[]
831834
`terminate_after`::
832-
(Optional, integer) The maximum number of documents to collect for each shard,
835+
(Optional, integer) The maximum number of documents to collect for each shard,
833836
upon reaching which the query execution will terminate early.
834837
end::terminate_after[]
835838

@@ -871,7 +874,7 @@ end::transform-id-wildcard[]
871874

872875
tag::cat-v[]
873876
`v`::
874-
(Optional, boolean) If `true`, the response includes column headings.
877+
(Optional, boolean) If `true`, the response includes column headings.
875878
Defaults to `false`.
876879
end::cat-v[]
877880

@@ -912,6 +915,6 @@ end::wait_for_active_shards[]
912915

913916
tag::wait_for_completion[]
914917
`wait_for_completion`::
915-
(Optional, boolean) If `true`, the request blocks until the operation is complete.
918+
(Optional, boolean) If `true`, the request blocks until the operation is complete.
916919
Defaults to `true`.
917920
end::wait_for_completion[]

server/src/main/java/org/elasticsearch/action/admin/cluster/health/ClusterHealthRequest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
public class ClusterHealthRequest extends MasterNodeReadRequest<ClusterHealthRequest> implements IndicesRequest.Replaceable {
4040

4141
private String[] indices;
42-
private IndicesOptions indicesOptions = IndicesOptions.lenientExpand();
42+
private IndicesOptions indicesOptions = IndicesOptions.lenientExpandHidden();
4343
private TimeValue timeout = new TimeValue(30, TimeUnit.SECONDS);
4444
private ClusterHealthStatus waitForStatus;
4545
private boolean waitForNoRelocatingShards = false;

server/src/main/java/org/elasticsearch/action/admin/indices/rollover/TransportRolloverAction.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
import org.elasticsearch.cluster.metadata.MetaData;
4444
import org.elasticsearch.cluster.metadata.MetaDataCreateIndexService;
4545
import org.elasticsearch.cluster.metadata.MetaDataIndexAliasesService;
46-
import org.elasticsearch.cluster.metadata.MetaDataIndexTemplateService;
4746
import org.elasticsearch.cluster.service.ClusterService;
4847
import org.elasticsearch.common.Nullable;
4948
import org.elasticsearch.common.inject.Inject;
@@ -63,6 +62,8 @@
6362
import java.util.regex.Pattern;
6463
import java.util.stream.Collectors;
6564

65+
import static org.elasticsearch.cluster.metadata.MetaDataIndexTemplateService.findTemplates;
66+
6667
/**
6768
* Main class to swap the index pointed to by an alias, given some conditions
6869
*/
@@ -122,7 +123,9 @@ protected void masterOperation(Task task, final RolloverRequest rolloverRequest,
122123
: generateRolloverIndexName(sourceProvidedName, indexNameExpressionResolver);
123124
final String rolloverIndexName = indexNameExpressionResolver.resolveDateMathExpression(unresolvedName);
124125
MetaDataCreateIndexService.validateIndexName(rolloverIndexName, state); // will fail if the index already exists
125-
checkNoDuplicatedAliasInIndexTemplate(metaData, rolloverIndexName, rolloverRequest.getAlias());
126+
final Boolean isHidden = IndexMetaData.INDEX_HIDDEN_SETTING.exists(rolloverRequest.getCreateIndexRequest().settings()) ?
127+
IndexMetaData.INDEX_HIDDEN_SETTING.get(rolloverRequest.getCreateIndexRequest().settings()) : null;
128+
checkNoDuplicatedAliasInIndexTemplate(metaData, rolloverIndexName, rolloverRequest.getAlias(), isHidden);
126129
IndicesStatsRequest statsRequest = new IndicesStatsRequest().indices(rolloverRequest.getAlias())
127130
.clear()
128131
.indicesOptions(IndicesOptions.fromOptions(true, false, true, true))
@@ -291,8 +294,9 @@ static CreateIndexClusterStateUpdateRequest prepareCreateIndexRequest(final Stri
291294
* the rollover alias will point to multiple indices. This causes indexing requests to be rejected.
292295
* To avoid this, we make sure that there is no duplicated alias in index templates before creating a new index.
293296
*/
294-
static void checkNoDuplicatedAliasInIndexTemplate(MetaData metaData, String rolloverIndexName, String rolloverRequestAlias) {
295-
final List<IndexTemplateMetaData> matchedTemplates = MetaDataIndexTemplateService.findTemplates(metaData, rolloverIndexName);
297+
static void checkNoDuplicatedAliasInIndexTemplate(MetaData metaData, String rolloverIndexName, String rolloverRequestAlias,
298+
@Nullable Boolean isHidden) {
299+
final List<IndexTemplateMetaData> matchedTemplates = findTemplates(metaData, rolloverIndexName, isHidden);
296300
for (IndexTemplateMetaData template : matchedTemplates) {
297301
if (template.aliases().containsKey(rolloverRequestAlias)) {
298302
throw new IllegalArgumentException(String.format(Locale.ROOT,

server/src/main/java/org/elasticsearch/action/bulk/TransportBulkAction.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ static boolean resolvePipelines(final DocWriteRequest<?> originalRequest, final
307307
}
308308
} else if (indexRequest.index() != null) {
309309
// the index does not exist yet (and this is a valid request), so match index templates to look for pipelines
310-
List<IndexTemplateMetaData> templates = MetaDataIndexTemplateService.findTemplates(metaData, indexRequest.index());
310+
List<IndexTemplateMetaData> templates = MetaDataIndexTemplateService.findTemplates(metaData, indexRequest.index(), null);
311311
assert (templates != null);
312312
// order of templates are highest order first
313313
for (final IndexTemplateMetaData template : templates) {

server/src/main/java/org/elasticsearch/action/search/MultiSearchRequest.java

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.elasticsearch.action.ActionRequestValidationException;
2424
import org.elasticsearch.action.CompositeIndicesRequest;
2525
import org.elasticsearch.action.support.IndicesOptions;
26+
import org.elasticsearch.action.support.IndicesOptions.WildcardStates;
2627
import org.elasticsearch.common.CheckedBiConsumer;
2728
import org.elasticsearch.common.bytes.BytesReference;
2829
import org.elasticsearch.common.io.stream.StreamInput;
@@ -304,15 +305,7 @@ public static void writeSearchRequestParams(SearchRequest request, XContentBuild
304305
xContentBuilder.field("index", request.indices());
305306
}
306307
if (request.indicesOptions() != null && request.indicesOptions() != SearchRequest.DEFAULT_INDICES_OPTIONS) {
307-
if (request.indicesOptions().expandWildcardsOpen() && request.indicesOptions().expandWildcardsClosed()) {
308-
xContentBuilder.field("expand_wildcards", "all");
309-
} else if (request.indicesOptions().expandWildcardsOpen()) {
310-
xContentBuilder.field("expand_wildcards", "open");
311-
} else if (request.indicesOptions().expandWildcardsClosed()) {
312-
xContentBuilder.field("expand_wildcards", "closed");
313-
} else {
314-
xContentBuilder.field("expand_wildcards", "none");
315-
}
308+
WildcardStates.toXContent(request.indicesOptions().getExpandWildcards(), xContentBuilder);
316309
xContentBuilder.field("ignore_unavailable", request.indicesOptions().ignoreUnavailable());
317310
xContentBuilder.field("allow_no_indices", request.indicesOptions().allowNoIndices());
318311
}

0 commit comments

Comments
 (0)