9
9
package org .elasticsearch .index .query ;
10
10
11
11
import org .elasticsearch .client .internal .Client ;
12
+ import org .elasticsearch .cluster .metadata .DataStream ;
13
+ import org .elasticsearch .cluster .metadata .IndexMetadata ;
14
+ import org .elasticsearch .common .Strings ;
12
15
import org .elasticsearch .core .Nullable ;
13
- import org .elasticsearch .index .mapper .DateFieldMapper ;
14
16
import org .elasticsearch .index .mapper .MappedFieldType ;
15
17
import org .elasticsearch .index .mapper .MappingLookup ;
16
18
import org .elasticsearch .index .shard .IndexLongFieldRange ;
19
+ import org .elasticsearch .indices .DateFieldRangeInfo ;
17
20
import org .elasticsearch .xcontent .XContentParserConfiguration ;
18
21
19
22
import java .util .Collections ;
23
26
* Context object used to rewrite {@link QueryBuilder} instances into simplified version in the coordinator.
24
27
* Instances of this object rely on information stored in the {@code IndexMetadata} for certain indices.
25
28
* Right now this context object is able to rewrite range queries that include a known timestamp field
26
- * (i.e. the timestamp field for DataStreams) into a MatchNoneQueryBuilder and skip the shards that
27
- * don't hold queried data. See IndexMetadata#getTimestampRange() for more details
29
+ * (i.e. the timestamp field for DataStreams or the 'event.ingested' field in ECS) into a MatchNoneQueryBuilder
30
+ * and skip the shards that don't hold queried data. See IndexMetadata for more details.
28
31
*/
29
32
public class CoordinatorRewriteContext extends QueryRewriteContext {
30
- private final IndexLongFieldRange indexLongFieldRange ;
31
- private final DateFieldMapper .DateFieldType timestampFieldType ;
33
+ private final DateFieldRangeInfo dateFieldRangeInfo ;
32
34
35
+ /**
36
+ * Context for coordinator search rewrites based on time ranges for the @timestamp field and/or 'event.ingested' field
37
+ * @param parserConfig
38
+ * @param client
39
+ * @param nowInMillis
40
+ * @param dateFieldRangeInfo range and field type info for @timestamp and 'event.ingested'
41
+ */
33
42
public CoordinatorRewriteContext (
34
43
XContentParserConfiguration parserConfig ,
35
44
Client client ,
36
45
LongSupplier nowInMillis ,
37
- IndexLongFieldRange indexLongFieldRange ,
38
- DateFieldMapper .DateFieldType timestampFieldType
46
+ DateFieldRangeInfo dateFieldRangeInfo
39
47
) {
40
48
super (
41
49
parserConfig ,
@@ -53,29 +61,98 @@ public CoordinatorRewriteContext(
53
61
null ,
54
62
null
55
63
);
56
- this .indexLongFieldRange = indexLongFieldRange ;
57
- this .timestampFieldType = timestampFieldType ;
64
+ this .dateFieldRangeInfo = dateFieldRangeInfo ;
58
65
}
59
66
60
- long getMinTimestamp () {
61
- return indexLongFieldRange .getMin ();
67
+ /**
68
+ * Get min timestamp for either '@timestamp' or 'event.ingested' fields. Any other field
69
+ * passed in will cause an {@link IllegalArgumentException} to be thrown, as these are the only
70
+ * two fields supported for coordinator rewrites (based on time range).
71
+ * @param fieldName Must be DataStream.TIMESTAMP_FIELD_NAME or IndexMetadata.EVENT_INGESTED_FIELD_NAME
72
+ * @return min timestamp for the field from IndexMetadata in cluster state.
73
+ */
74
+ long getMinTimestamp (String fieldName ) {
75
+ if (DataStream .TIMESTAMP_FIELD_NAME .equals (fieldName )) {
76
+ return dateFieldRangeInfo .getTimestampRange ().getMin ();
77
+ } else if (IndexMetadata .EVENT_INGESTED_FIELD_NAME .equals (fieldName )) {
78
+ return dateFieldRangeInfo .getEventIngestedRange ().getMin ();
79
+ } else {
80
+ throw new IllegalArgumentException (
81
+ Strings .format (
82
+ "Only [%s] or [%s] fields are supported for min timestamp coordinator rewrites, but got: [%s]" ,
83
+ DataStream .TIMESTAMP_FIELD_NAME ,
84
+ IndexMetadata .EVENT_INGESTED_FIELD_NAME ,
85
+ fieldName
86
+ )
87
+ );
88
+ }
62
89
}
63
90
64
- long getMaxTimestamp () {
65
- return indexLongFieldRange .getMax ();
91
+ /**
92
+ * Get max timestamp for either '@timestamp' or 'event.ingested' fields. Any other field
93
+ * passed in will cause an {@link IllegalArgumentException} to be thrown, as these are the only
94
+ * two fields supported for coordinator rewrites (based on time range).
95
+ * @param fieldName Must be DataStream.TIMESTAMP_FIELD_NAME or IndexMetadata.EVENT_INGESTED_FIELD_NAME
96
+ * @return max timestamp for the field from IndexMetadata in cluster state.
97
+ */
98
+ long getMaxTimestamp (String fieldName ) {
99
+ if (DataStream .TIMESTAMP_FIELD_NAME .equals (fieldName )) {
100
+ return dateFieldRangeInfo .getTimestampRange ().getMax ();
101
+ } else if (IndexMetadata .EVENT_INGESTED_FIELD_NAME .equals (fieldName )) {
102
+ return dateFieldRangeInfo .getEventIngestedRange ().getMax ();
103
+ } else {
104
+ throw new IllegalArgumentException (
105
+ Strings .format (
106
+ "Only [%s] or [%s] fields are supported for max timestamp coordinator rewrites, but got: [%s]" ,
107
+ DataStream .TIMESTAMP_FIELD_NAME ,
108
+ IndexMetadata .EVENT_INGESTED_FIELD_NAME ,
109
+ fieldName
110
+ )
111
+ );
112
+ }
66
113
}
67
114
68
- boolean hasTimestampData () {
69
- return indexLongFieldRange .isComplete () && indexLongFieldRange != IndexLongFieldRange .EMPTY ;
115
+ /**
116
+ * Determine whether either '@timestamp' or 'event.ingested' fields has useful timestamp ranges
117
+ * stored in cluster state for this context.
118
+ * Any other fieldname will cause an {@link IllegalArgumentException} to be thrown, as these are the only
119
+ * two fields supported for coordinator rewrites (based on time range).
120
+ * @param fieldName Must be DataStream.TIMESTAMP_FIELD_NAME or IndexMetadata.EVENT_INGESTED_FIELD_NAME
121
+ * @return min timestamp for the field from IndexMetadata in cluster state.
122
+ */
123
+ boolean hasTimestampData (String fieldName ) {
124
+ if (DataStream .TIMESTAMP_FIELD_NAME .equals (fieldName )) {
125
+ return dateFieldRangeInfo .getTimestampRange ().isComplete ()
126
+ && dateFieldRangeInfo .getTimestampRange () != IndexLongFieldRange .EMPTY ;
127
+ } else if (IndexMetadata .EVENT_INGESTED_FIELD_NAME .equals (fieldName )) {
128
+ return dateFieldRangeInfo .getEventIngestedRange ().isComplete ()
129
+ && dateFieldRangeInfo .getEventIngestedRange () != IndexLongFieldRange .EMPTY ;
130
+ } else {
131
+ throw new IllegalArgumentException (
132
+ Strings .format (
133
+ "Only [%s] or [%s] fields are supported for min/max timestamp coordinator rewrites, but got: [%s]" ,
134
+ DataStream .TIMESTAMP_FIELD_NAME ,
135
+ IndexMetadata .EVENT_INGESTED_FIELD_NAME ,
136
+ fieldName
137
+ )
138
+ );
139
+ }
70
140
}
71
141
142
+ /**
143
+ * @param fieldName Get MappedFieldType for either '@timestamp' or 'event.ingested' fields.
144
+ * @return min timestamp for the field from IndexMetadata in cluster state or null if fieldName was not
145
+ * DataStream.TIMESTAMP_FIELD_NAME or IndexMetadata.EVENT_INGESTED_FIELD_NAME.
146
+ */
72
147
@ Nullable
73
148
public MappedFieldType getFieldType (String fieldName ) {
74
- if (fieldName .equals (timestampFieldType .name ()) == false ) {
149
+ if (DataStream .TIMESTAMP_FIELD_NAME .equals (fieldName )) {
150
+ return dateFieldRangeInfo .getTimestampFieldType ();
151
+ } else if (IndexMetadata .EVENT_INGESTED_FIELD_NAME .equals (fieldName )) {
152
+ return dateFieldRangeInfo .getEventIngestedFieldType ();
153
+ } else {
75
154
return null ;
76
155
}
77
-
78
- return timestampFieldType ;
79
156
}
80
157
81
158
@ Override
0 commit comments