Skip to content

Commit d1617c5

Browse files
authored
Closes #47. Supporting nested extracts in projections (#69)
1 parent ae95c67 commit d1617c5

File tree

7 files changed

+36
-36
lines changed

7 files changed

+36
-36
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
3737
<maven.compiler.source>1.8</maven.compiler.source>
3838
<maven.compiler.target>1.8</maven.compiler.target>
39-
<bullet.record.version>0.2.2</bullet.record.version>
39+
<bullet.record.version>0.3.0</bullet.record.version>
4040
<sketches.version>0.9.1</sketches.version>
4141
</properties>
4242

src/main/java/com/yahoo/bullet/common/Utilities.java

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@
1414
import java.util.Map;
1515

1616
public class Utilities {
17-
public static final String SUB_KEY_SEPERATOR = "\\.";
18-
1917
/**
2018
* Tries to get the object casted as the target type. If it is generic, the captured types cannot not be
2119
* validated. Only the base object type is validated.
@@ -123,14 +121,4 @@ public static Number extractFieldAsNumber(String identifier, BulletRecord record
123121
}
124122
return (Number) asNumber.getValue();
125123
}
126-
127-
/**
128-
* Takes a field and returns it split into subfields if necessary.
129-
*
130-
* @param field The non-null field to get.
131-
* @return The field split into field or subfield if it was a map field, or just the field itself.
132-
*/
133-
public static String[] splitField(String field) {
134-
return field.split(SUB_KEY_SEPERATOR, 2);
135-
}
136124
}

src/main/java/com/yahoo/bullet/querying/Querier.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,8 +449,8 @@ public void consume(BulletRecord record) {
449449
return;
450450
}
451451

452-
BulletRecord projected = project(record);
453452
try {
453+
BulletRecord projected = project(record);
454454
window.consume(projected);
455455
hasNewData = true;
456456
} catch (RuntimeException e) {

src/main/java/com/yahoo/bullet/querying/operations/ProjectionOperations.java

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313
import java.util.HashMap;
1414
import java.util.Map;
1515

16-
import static com.yahoo.bullet.common.Utilities.splitField;
17-
1816
@Slf4j
1917
public class ProjectionOperations {
2018
/**
@@ -44,24 +42,10 @@ public static BulletRecord project(BulletRecord record, Projection projection, M
4442
for (Map.Entry<String, String> e : fields.entrySet()) {
4543
String field = e.getKey();
4644
String newName = e.getValue();
47-
try {
48-
copyInto(projected, newName, record, field);
49-
} catch (ClassCastException cce) {
50-
log.warn("Skipping copying {} as {} as it is not a field that can be extracted", field, newName);
45+
if (field != null) {
46+
projected.forceSet(newName, record.extractField(field));
5147
}
5248
}
5349
return projected;
5450
}
55-
56-
private static void copyInto(BulletRecord record, String newName, BulletRecord source, String field) throws ClassCastException {
57-
if (field == null) {
58-
return;
59-
}
60-
String[] split = splitField(field);
61-
if (split.length > 1) {
62-
record.set(newName, source, split[0], split[1]);
63-
} else {
64-
record.set(newName, source, field);
65-
}
66-
}
6751
}

src/test/java/com/yahoo/bullet/querying/operations/FilterOperationsTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,21 @@ public void testComparisonNestedField() {
426426
Assert.assertTrue(FilterOperations.perform(box.getRecord(), clause));
427427
}
428428

429+
@Test
430+
public void testComparisonEverMoreNestedField() {
431+
FilterClause clause = getFieldFilter("map_of_maps.demog.age", GREATER_THAN, "30");
432+
433+
// "null" is not > 30
434+
Assert.assertFalse(FilterOperations.perform(RecordBox.get().getRecord(), clause));
435+
RecordBox box = RecordBox.get();
436+
box.addMapOfMaps("map_of_maps", Pair.of("demog", singletonMap("age", 3)), Pair.of("foo", singletonMap("bar", 50)));
437+
Assert.assertFalse(FilterOperations.perform(box.getRecord(), clause));
438+
box.addMapOfMaps("map_of_maps", Pair.of("demog", singletonMap("age", 30)), Pair.of("foo", singletonMap("bar", 50)));
439+
Assert.assertFalse(FilterOperations.perform(box.getRecord(), clause));
440+
box.addMapOfMaps("map_of_maps", Pair.of("demog", singletonMap("age", 31)), Pair.of("foo", singletonMap("bar", 50)));
441+
Assert.assertTrue(FilterOperations.perform(box.getRecord(), clause));
442+
}
443+
429444
@Test
430445
public void testComparisonBooleanMap() {
431446
FilterClause clause = getFieldFilter("filter_map.is_fake_event", EQUALS, "true");

src/test/java/com/yahoo/bullet/querying/operations/ProjectionOperationsTest.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
import static com.yahoo.bullet.parsing.ProjectionUtils.makeProjection;
1919
import static java.util.Collections.emptyMap;
2020
import static java.util.Collections.singletonMap;
21+
import static org.mockito.Matchers.anyString;
22+
import static org.mockito.Mockito.doThrow;
23+
import static org.mockito.Mockito.spy;
2124

2225
public class ProjectionOperationsTest {
2326
private static BulletRecordProvider provider = new BulletConfig().getBulletRecordProvider();
@@ -43,17 +46,27 @@ public void testProjection() {
4346
}
4447

4548
@Test
46-
public void testUnsupportedProjection() {
49+
public void testNestedProjections() {
4750
Projection projection = makeProjection(ImmutablePair.of("list_field.1.foo", "bar"),
51+
ImmutablePair.of("map_field.foo.bar", "baz"),
4852
ImmutablePair.of("field", "foo"));
49-
BulletRecord record = RecordBox.get().addListOfMaps("list_field", emptyMap(), singletonMap("foo", "bar"))
53+
BulletRecord record = RecordBox.get().addListOfMaps("list_field", emptyMap(), singletonMap("foo", "qux"))
54+
.addMapOfMaps("map_field", ImmutablePair.of("foo", singletonMap("bar", "foo.bar")))
5055
.add("field", "123")
5156
.getRecord();
5257
BulletRecord actual = ProjectionOperations.project(record, projection, null, provider);
53-
BulletRecord expected = RecordBox.get().add("foo", "123").getRecord();
58+
BulletRecord expected = RecordBox.get().add("foo", "123").add("bar", "qux").add("baz", "foo.bar").getRecord();
5459
Assert.assertEquals(actual, expected);
5560
}
5661

62+
@Test(expectedExceptions = RuntimeException.class, expectedExceptionsMessageRegExp = ".*Testing.*")
63+
public void testFailingProjection() {
64+
Projection projection = makeProjection(ImmutablePair.of("foo", "bar"));
65+
BulletRecord record = spy(RecordBox.get().add("foo", "123").getRecord());
66+
doThrow(new RuntimeException("Testing")).when(record).extractField(anyString());
67+
ProjectionOperations.project(record, projection, null, provider);
68+
}
69+
5770
@Test
5871
public void testMapList() {
5972
Projection projection = makeProjection("list_field", "foo");

src/test/java/com/yahoo/bullet/result/RecordBox.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public final RecordBox addMap(String name, Pair<String, Object>... entries) {
8181
@SafeVarargs
8282
public final RecordBox addMapOfMaps(String name, Pair<String, Map<String, Object>>... entries) {
8383
if (entries != null && entries.length != 0) {
84-
Map<String, Object>[] sampleEntries = (Map<String, Object>[]) Arrays.stream(entries).map(Pair::getRight).toArray();
84+
Map<String, Object>[] sampleEntries = (Map<String, Object>[]) Arrays.stream(entries).map(Pair::getRight).toArray(Map[]::new);
8585
Object value = findObject(sampleEntries);
8686
if (value instanceof Boolean) {
8787
record.setMapOfBooleanMap(name, asMapOfMaps(Boolean.class, entries));

0 commit comments

Comments
 (0)