Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
fa3dd20
TEMP
GalLalouche Jan 13, 2025
c2b0d9c
WTF checkstyle?!
GalLalouche Jan 9, 2025
7b33f15
Trying to fix failures
GalLalouche Jan 9, 2025
a105f0a
Add capability, Fix parser test
GalLalouche Jan 12, 2025
0ca5e79
Update docs/changelog/119886.yaml
GalLalouche Jan 12, 2025
bf309fb
Update changelog
GalLalouche Jan 14, 2025
0b72c89
Merge branch 'main' into feature/unmapped_fields_squashed
GalLalouche Jan 14, 2025
c046112
Really merge main this time
GalLalouche Jan 14, 2025
aca3796
Merge branch 'main' into feature/unmapped_fields_squashed
craigtaverner Jan 14, 2025
dacc8f6
Craig's PR notes
GalLalouche Jan 14, 2025
f71a586
Test for no sources
GalLalouche Jan 16, 2025
2ba5935
More code review fixes
GalLalouche Jan 16, 2025
c22b9d4
Merge branch 'main' into feature/unmapped_fields_squashed
GalLalouche Jan 16, 2025
f5c77fa
Update docs/changelog/119886.yaml
GalLalouche Jan 19, 2025
d6afb24
More code review fixes
GalLalouche Jan 19, 2025
25f0c53
Merge branch 'main' into feature/unmapped_fields_squashed
GalLalouche Jan 19, 2025
165ad16
Merge branch 'feature/unmapped_fields_squashed' of github.com:GalLalo…
GalLalouche Jan 19, 2025
9d85915
Some of Costin's notes
GalLalouche Jan 22, 2025
d0959ea
Pre huge refactor
GalLalouche Jan 23, 2025
d68a0ca
Post huge refactor
GalLalouche Jan 23, 2025
a12aa82
Merge branch 'main' into feature/unmapped_fields_squashed
GalLalouche Jan 26, 2025
f02fd43
Temp fixes
GalLalouche Jan 26, 2025
a8d9372
Slighly more delicate refactor
GalLalouche Jan 26, 2025
fcd4663
Fix borken test
GalLalouche Jan 26, 2025
be4bbfd
Handle failing tests
GalLalouche Jan 26, 2025
b84ff2c
Fix test names
GalLalouche Jan 26, 2025
a0e1840
Replace flag with inheritance
GalLalouche Jan 26, 2025
0b4132e
Add comment parsing
GalLalouche Jan 27, 2025
b05b327
Add a few more unmapped fields CSV tests
GalLalouche Jan 29, 2025
3f9faef
Added IndexResolverFieldNames test
GalLalouche Jan 29, 2025
903f6fa
Merge branch 'main' into feature/unmapped_fields_squashed
GalLalouche Jan 29, 2025
85b84f5
Move tests from LogicalPlanOptimizerTests to AnalyzerTests
GalLalouche Jan 29, 2025
400f473
Merge branch 'main' into feature/unmapped_fields_squashed
GalLalouche Jan 29, 2025
fb09120
Properly apply Andrei's suggestion after it somehow got removed o_O
GalLalouche Jan 29, 2025
0d9b280
Add snapshot check to StatementParserTests
GalLalouche Jan 29, 2025
d7ce623
Merge branch 'main' into feature/unmapped_fields_squashed
GalLalouche Jan 29, 2025
0f01ebe
Merge branch 'main' into feature/unmapped_fields_squashed
GalLalouche Jan 30, 2025
5c2c7d7
Merge branch 'main' into feature/unmapped_fields_squashed
GalLalouche Feb 2, 2025
af26d5f
More code review fixes
GalLalouche Feb 2, 2025
faef67a
Merge branch 'main' into feature/unmapped_fields_squashed
GalLalouche Feb 2, 2025
1204791
TEMP
GalLalouche Feb 2, 2025
22569b8
Things pass! Excitement!
GalLalouche Feb 4, 2025
a9f4a0b
Merge branch 'main' into feature/unmapped_fields_squashed
GalLalouche Feb 5, 2025
8f3c235
Remove println
GalLalouche Feb 5, 2025
7d07d1a
Merge branch 'main' into feature/unmapped_fields_squashed
GalLalouche Feb 5, 2025
697989c
Fix borken test
GalLalouche Feb 5, 2025
c0fe85e
Merge branch 'main' into feature/unmapped_fields_squashed
GalLalouche Feb 5, 2025
ab9bfdf
More review fixes
GalLalouche Feb 6, 2025
5c1c2be
Merge branch 'main' into feature/unmapped_fields_squashed
GalLalouche Feb 6, 2025
9805f12
Merge branch 'main' into feature/unmapped_fields_squashed
GalLalouche Feb 9, 2025
d5dc662
Fix borken test
GalLalouche Feb 9, 2025
ef56e8a
Merge branch 'main' into feature/unmapped_fields_squashed
GalLalouche Feb 10, 2025
13b3dff
Merge branch 'main' into feature/unmapped_fields_squashed
GalLalouche Feb 10, 2025
088a622
Try to fix BWC test
GalLalouche Feb 11, 2025
ea8567b
Merge branch 'main' into feature/unmapped_fields_squashed
GalLalouche Feb 11, 2025
9c466e4
Try to fix BWC test (2)
GalLalouche Feb 11, 2025
1fb5cb4
Try to fix BWC test (3)
GalLalouche Feb 11, 2025
8017c78
Merge branch 'main' into feature/unmapped_fields_squashed
GalLalouche Feb 11, 2025
4f6f6a1
Try to fix BWC test (4)
GalLalouche Feb 11, 2025
971b869
Merge branch 'main' into feature/unmapped_fields_squashed
GalLalouche Feb 11, 2025
ef94c52
Merge branch 'main' into feature/unmapped_fields_squashed
GalLalouche Feb 12, 2025
c9fdc92
Merge branch 'main' into feature/unmapped_fields_squashed
GalLalouche Feb 12, 2025
b46cb9d
Merge branch 'main' into feature/unmapped_fields_squashed
GalLalouche Feb 12, 2025
b5da964
Merge branch 'main' into feature/unmapped_fields_squashed
GalLalouche Feb 12, 2025
7a48277
Merge branch 'main' into feature/unmapped_fields_squashed
GalLalouche Feb 12, 2025
dcc518c
Merge branch 'main' into feature/unmapped_fields_squashed
GalLalouche Feb 13, 2025
770ea6f
Merge branch 'main' into feature/unmapped_fields_squashed
GalLalouche Feb 13, 2025
97399fc
Merge branch 'main' into feature/unmapped_fields_squashed
GalLalouche Feb 13, 2025
e32a446
Merge branch 'main' into feature/unmapped_fields_squashed
GalLalouche Feb 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/changelog/119886.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pr: 119886
summary: Initial support for unmapped fields
area: ES|QL
type: feature
issues: []
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ private static class BytesRefs extends BlockSourceReader {

@Override
protected void append(BlockLoader.Builder builder, Object v) {
((BlockLoader.BytesRefBuilder) builder).appendBytesRef(toBytesRef(scratch, (String) v));
((BlockLoader.BytesRefBuilder) builder).appendBytesRef(toBytesRef(scratch, v.toString()));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public class EsField implements Writeable {
Map.entry("EsField", EsField::new),
Map.entry("DateEsField", DateEsField::new),
Map.entry("InvalidMappedField", InvalidMappedField::new),
Map.entry("UnmappedEsField", UnmappedEsField::new),
Map.entry("KeywordEsField", KeywordEsField::new),
Map.entry("MultiTypeEsField", MultiTypeEsField::new),
Map.entry("TextEsField", TextEsField::new),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ public Map<String, Set<String>> getTypesToIndices() {
return typesToIndices;
}

public InvalidMappedField withTypesToIndices(Map<String, Set<String>> typesToIndices) {
return new InvalidMappedField(getName(), makeErrorMessage(typesToIndices), getProperties(), typesToIndices);
}

private static String makeErrorMessage(Map<String, Set<String>> typesToIndices) {
StringBuilder errorMessage = new StringBuilder();
errorMessage.append("mapped as [");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

package org.elasticsearch.xpack.esql.core.type;

import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.core.Strings;
import org.elasticsearch.xpack.esql.core.expression.Expression;

import java.io.IOException;
import java.util.Map;
import java.util.TreeMap;
import java.util.TreeSet;

import static org.elasticsearch.xpack.esql.core.type.DataType.KEYWORD;
import static org.elasticsearch.xpack.esql.core.util.PlanStreamInput.readCachedStringWithVersionCheck;
import static org.elasticsearch.xpack.esql.core.util.PlanStreamOutput.writeCachedStringWithVersionCheck;

/// A special marker for fields explicitly marked as unmapped in the query. These need to be explicitly marked, so we know to search for
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a public class, so surely these comments should be javadoc?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are javadocs :) /// is a markdown syntax as opposed to Javadoc syntax. https://openjdk.org/jeps/467

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While they are ok, technically, the codebase of Elasticsearch especially has a certain style: both in looks and in intent. This is the first time I am seeing this style in the elasticsearch repo :-) and, my 2c, is to try and keep the looks of the code consistent.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaving aside my previous comment and looking over the code in my IDE, I find the new style less airy than the classic javadoc style. The description is tightly (one line after the other) attached to the Java code itself making this class more difficult to follow because of the multiple bulky pieces of text and code. My personal preference is for the old Javadoc style. It helps me follow the code in an easier manner.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd love to switch us to markdown syntax. It's just so much more familiar. After all this comment is in markdown. It sort of won the markup war. Sort of. Kind of. Whatever.

I imagine these won't work properly in 8.x because they aren't on jdk-latest. Worth checking that before we do this.

Once we're no longer backporting things to 8.x I'd say we should just do it. Style and consistency are lovely, but not having to remember the special javadoc style is lovely too.

I guess, other question, does IntelliJ's mouseover support it? It should. This is basically the same syntax rust uses and it supports that.

Probably worth checking with the delivery friends if they've seen this and have an opinion. They are the clearinghouse on such knowledge on our team.

/// during data loading. By default, the [DataType] of these fields is [DataType#KEYWORD], since we can always convert a [DataType#KEYWORD]
/// to any other type. However, this can cause type conflicts with partially mapped types, i.e, types which appear in some indices but not
/// all. In that sense, this field is very similar to the [MultiTypeEsField] feature, except we allow for unmapped fields.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not combine this capability with MultiTypeEsField, instead of having two classes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MultiTypeField doesn't directly support this kind of behavior, e.g., for the case where the field is mapped to a single consistent type, since it holds a map from an index to a conversion, and we don't actually have an index at that point (since there is not InvalidMappedField, since there is no conflict). While I could retrofit MultiTypeEsField to handle that case as well, I think it's cleaner to do it in another class. SRP and all that :)

///
/// Check out the [State] algebraic data type for the different kinds of unmapped fields.
public class UnmappedEsField extends EsField {
private UnmappedEsField(State state, String name, DataType dataType, Map<String, EsField> properties) {
super(name, dataType, properties, true /* aggregatable */);
this.state = state;
}

public sealed interface State {}

/// A field which is either unmapped in all indices, or mapped to [DataType#KEYWORD] in all indices where it is mapped.
public enum NoConflicts implements State {
INSTANCE;
}

/// A field which is mapped to a single type, which is not a [DataType#KEYWORD]. This can be resolved using a cast, similar to union
/// types. This is treated differently from [InvalidMappedField], since resolving this conflict doesn't use [MultiTypeEsField].
public record SimpleConflict(DataType otherType) implements State {
public SimpleConflict {
if (otherType == KEYWORD) {
throw new IllegalArgumentException("Use NoConflicts.INSTANCE for KEYWORD");
}
}
}

/// A field which is mapped to a single type, but that type is not [DataType#KEYWORD]. This is resolved using the specified conversions.
public record SimpleResolution(Expression unmappedConversion, Expression mappedConversion) implements State {}

/// A field which is mapped to more than one type in multiple indices, *in addition* to the unmapped case which is always treated as
/// [DataType#KEYWORD]. This can be resolved using a cast, similar to union types.
public record Invalid(InvalidMappedField invalidMappedField) implements State {}

/// A field which is mapped to different types in different indices, but resolved using union types. In mapped indices, we treat this
/// as a union type, and use the specified conversion for unmapped indices.
public record MultiType(Expression conversionFromKeyword, MultiTypeEsField multiTypeEsField) implements State {}

private final State state;

public State getState() {
return state;
}

public static UnmappedEsField fromField(EsField f) {
State state = switch (f) {
case InvalidMappedField imf -> {
var newTypesToIndices = new TreeMap<>(imf.getTypesToIndices());
newTypesToIndices.compute(KEYWORD.typeName(), (k, v) -> v == null ? new TreeSet<>() : new TreeSet<>(v))
.add("unmapped field");
yield new Invalid(imf.withTypesToIndices(newTypesToIndices));
}
case MultiTypeEsField mf -> throw new IllegalArgumentException("Use fromMultiType for MultiTypeEsField");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not an assertion here, since it seems to be a programmatically incorrect use of fromField? You have a similar approach in simpleResolution method.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question, especially regarding the inconsistencies! Both IllegalArgumentException and assert signify programmer errors, as do all unchecked exceptions (as opposed to checked exception, which should signify user errors, or, for some reason, IO boundaries). I'd argue that the assert below should also be an IllegalArgumentException, as the boundary checks of public methods should be regular RuntimeException and not assert. So I'll change the other one :).

default -> f.getDataType() == KEYWORD ? UnmappedEsField.NoConflicts.INSTANCE : new SimpleConflict(f.getDataType());
};
return new UnmappedEsField(state, f.getName(), f.getDataType(), f.getProperties());
}

public static UnmappedEsField fromStandalone(String name) {
return new UnmappedEsField(NoConflicts.INSTANCE, name, KEYWORD, Map.of());
}

public static UnmappedEsField fromMultiType(Expression expression, MultiTypeEsField multiTypeEsField) {
return new UnmappedEsField(
new MultiType(expression, multiTypeEsField),
multiTypeEsField.getName(),
multiTypeEsField.getDataType(),
multiTypeEsField.getProperties()
);
}

public static UnmappedEsField simpleResolution(Expression unmappedConv, Expression mappedConv, String name) {
assert unmappedConv.dataType() == mappedConv.dataType()
: Strings.format(
"Both conversions must have the same target type, but got [%s, %s]",
unmappedConv.dataType(),
mappedConv.dataType()
);
assert unmappedConv.children().get(0).dataType() == KEYWORD
: Strings.format("Unmapped conversion must be from keyword, but got [%s]", unmappedConv.children().get(0).dataType());
assert mappedConv.children().get(0).dataType() != KEYWORD : Strings.format("Unmapped conversion must be from non-keyword");
return new UnmappedEsField(new SimpleResolution(unmappedConv, mappedConv), name, unmappedConv.dataType(), Map.of());
}

@Override
public void writeContent(StreamOutput out) throws IOException {
switch (state) {
case NoConflicts unused -> {
out.writeInt(0);
}
case SimpleConflict sf -> {
out.writeInt(1);
sf.otherType().writeTo(out);
}
case SimpleResolution sr -> {
out.writeInt(2);
out.writeNamedWriteable(sr.unmappedConversion());
out.writeNamedWriteable(sr.mappedConversion());
}
case Invalid invalid -> {
out.writeInt(3);
invalid.invalidMappedField().writeTo(out);
}
case MultiType mt -> {
out.writeInt(4);
out.writeNamedWriteable(mt.conversionFromKeyword());
mt.multiTypeEsField.writeTo(out);
}
}
writeCachedStringWithVersionCheck(out, getName());
getDataType().writeTo(out);
out.writeMap(getProperties(), (o, x) -> x.writeTo(out));
}

UnmappedEsField(StreamInput in) throws IOException {
this(readState(in), readCachedStringWithVersionCheck(in), DataType.readFrom(in), in.readImmutableMap(EsField::readFrom));
}

private static State readState(StreamInput in) throws IOException {
var ordinal = in.readInt();
return switch (ordinal) {
case 0 -> NoConflicts.INSTANCE;
case 1 -> new SimpleConflict(DataType.readFrom(in));
case 2 -> new SimpleResolution(in.readNamedWriteable(Expression.class), in.readNamedWriteable(Expression.class));
case 3 -> new Invalid(InvalidMappedField.readFrom(in));
case 4 -> new MultiType(in.readNamedWriteable(Expression.class), MultiTypeEsField.readFrom(in));
default -> throw new AssertionError("Unexpected ordinal: " + ordinal);
};
}

@Override
public String getWriteableName() {
return "UnmappedEsField";
}

@Override
public String toString() {
return Strings.format("UnmappedEsField{state=%s}", state);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.OptionalInt;
import java.util.Set;
import java.util.function.Predicate;

import static java.util.Collections.emptyList;

Expand Down Expand Up @@ -83,4 +85,21 @@ public static <T> List<T> nullSafeList(T... entries) {
}
return list;
}

public static <T, S extends T> List<S> collectType(Collection<T> list, Class<S> clazz) {
return list.stream().<S>mapMulti((e, c) -> {
if (clazz.isInstance(e)) {
c.accept(clazz.cast(e));
}
}).toList();
}

public static <T> OptionalInt findIndex(List<T> list, Predicate<T> predicate) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current style of ESQL limits the use of functional constructs and Optional and instead uses more of a C style approach and use an out of band number for primitives (-1) or null for objects.

for (int i = 0, s = list.size(); i < s; i++) {
      if (predicate.test(list,.get(i)) {
           return i;
      }
}
return -1;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I get that this is the current style, I think the use of Optional is a lot safer and clearer. If this isn't a very strict requirement, I would much rather keep this as is. No reason to throw good code after bad :)

for (int i = 0; i < list.size(); i++) {
if (predicate.test(list.get(i))) {
return OptionalInt.of(i);
}
}
return OptionalInt.empty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.elasticsearch.xpack.esql.core.type.DataType;
import org.elasticsearch.xpack.esql.core.type.EsField;

import java.util.Collection;
import java.util.regex.Pattern;

import static java.util.Collections.emptyMap;
Expand All @@ -24,6 +25,8 @@
import static org.elasticsearch.test.ESTestCase.randomZone;
import static org.elasticsearch.xpack.esql.core.tree.Source.EMPTY;
import static org.elasticsearch.xpack.esql.core.type.DataType.INTEGER;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;

public final class TestUtils {
private TestUtils() {}
Expand Down Expand Up @@ -68,4 +71,9 @@ public static FieldAttribute getFieldAttribute(String name, DataType dataType) {
public static String stripThrough(String input) {
return WS_PATTERN.matcher(input).replaceAll(StringUtils.EMPTY);
}

public static <T> T assertSingleton(Collection<T> collection) {
assertThat(collection, hasSize(1));
return collection.iterator().next();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,9 @@ public static Tuple<Version, Version> skipVersionRange(String testName, String i
return null;
}

public static Tuple<Page, List<String>> loadPageFromCsv(URL source, Map<String, String> typeMapping) throws Exception {
public record PageColumn(String name, DataType dataType) {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the dataType of a PageColumn is used. Probably was used in the initial version of this PR; you might want to revert this change (adding the PageColumn), at this point it looks unnecessary, unless I'm missing where the dataType is actually used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, you're right. It was used when we needed to check for type conflicts during casting.


public static Tuple<Page, List<PageColumn>> loadPageFromCsv(URL source, Map<String, String> typeMapping) throws Exception {

record CsvColumn(String name, Type type, BuilderWrapper builderWrapper) implements Releasable {
void append(String stringValue) {
Expand Down Expand Up @@ -230,13 +232,13 @@ public void close() {
lineNumber++;
}
}
var columnNames = new ArrayList<String>(columns.length);
var pageColumns = new ArrayList<PageColumn>(columns.length);
try {
var blocks = Arrays.stream(columns)
.peek(b -> columnNames.add(b.name))
.peek(b -> pageColumns.add(new PageColumn(b.name, DataType.fromTypeName(b.type.name()))))
.map(b -> b.builderWrapper.builder().build())
.toArray(Block[]::new);
return new Tuple<>(new Page(blocks), columnNames);
return new Tuple<>(new Page(blocks), pageColumns);
} finally {
Releasables.closeExpectNoException(columns);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.elasticsearch.common.logging.LoggerMessageFormat.format;
import static org.elasticsearch.xpack.esql.CsvTestUtils.COMMA_ESCAPING_REGEX;
Expand Down Expand Up @@ -83,6 +85,12 @@ public class CsvTestsDataLoader {
.withData("sample_data_ts_nanos.csv")
.withTypeMapping(Map.of("@timestamp", "date_nanos"));
private static final TestDataset MISSING_IP_SAMPLE_DATA = new TestDataset("missing_ip_sample_data");
private static final TestDataset SAMPLE_DATA_PARTIAL_MAPPING = new TestDataset("partial_mapping_sample_data");
private static final TestDataset SAMPLE_DATA_NO_MAPPING = new TestDataset(
"no_mapping_sample_data",
"mapping-no_mapping_sample_data.json",
"partial_mapping_sample_data.csv"
).withTypeMapping(Stream.of("timestamp", "client_ip", "event_duration").collect(Collectors.toMap(k -> k, k -> "keyword")));
private static final TestDataset CLIENT_IPS = new TestDataset("clientips");
private static final TestDataset CLIENT_IPS_LOOKUP = CLIENT_IPS.withIndex("clientips_lookup")
.withSetting("clientips_lookup-settings.json");
Expand Down Expand Up @@ -128,6 +136,8 @@ public class CsvTestsDataLoader {
Map.entry(LANGUAGES_NESTED_FIELDS.indexName, LANGUAGES_NESTED_FIELDS),
Map.entry(UL_LOGS.indexName, UL_LOGS),
Map.entry(SAMPLE_DATA.indexName, SAMPLE_DATA),
Map.entry(SAMPLE_DATA_PARTIAL_MAPPING.indexName, SAMPLE_DATA_PARTIAL_MAPPING),
Map.entry(SAMPLE_DATA_NO_MAPPING.indexName, SAMPLE_DATA_NO_MAPPING),
Map.entry(MV_SAMPLE_DATA.indexName, MV_SAMPLE_DATA),
Map.entry(ALERTS.indexName, ALERTS),
Map.entry(SAMPLE_DATA_STR.indexName, SAMPLE_DATA_STR),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
@timestamp:date,client_ip:ip,event_duration:long,message:keyword,unmapped_message:keyword,unmapped_event_duration:keyword
2024-10-23T13:55:01.543Z,173.21.3.15,1756466,Connected to 10.1.0.1!,Disconnected from 10.1.0.1,1756468
2024-10-23T13:53:55.832Z,173.21.3.15,5033754,Connection error?,Disconnection error,5033756
2024-10-23T13:52:55.015Z,173.21.3.15,8268152,Connection error?,Disconnection error,8268154
2024-10-23T13:51:54.732Z,173.21.3.15,725447,Connection error?,Disconnection error,725449
2024-10-23T13:33:34.937Z,173.21.0.5,1232381,42,43,1232383
2024-10-23T12:27:28.948Z,173.21.2.113,2764888,Connected to 10.1.0.2!,Disconnected from 10.1.0.2,2764890
2024-10-23T12:15:03.360Z,173.21.2.162,3450232,Connected to 10.1.0.3!,Disconnected from 10.1.0.3,3450234
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"dynamic": "false",
"properties": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"dynamic": "false",
"properties": {
"@timestamp": {
"type": "date"
},
"client_ip": {
"type": "ip"
},
"event_duration": {
"type": "long"
},
"message": {
"type": "keyword"
}
}
}
Loading