Skip to content

Commit fe2adce

Browse files
author
Ross Hansen
committed
Fix index issue with multiple keys in embedded documents
1 parent cb3d1b7 commit fe2adce

File tree

4 files changed

+57
-20
lines changed

4 files changed

+57
-20
lines changed

core/src/main/java/de/bwaldvogel/mongo/backend/CollectionUtils.java

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,30 @@ public static <T> T getSingleElement(Iterable<T> iterable, Supplier<? extends Ru
3737
return value;
3838
}
3939

40-
static <T> List<List<T>> multiplyWithOtherElements(Collection<?> allValues, Collection<T> collectionValues) {
41-
Assert.isTrue(allValues.contains(collectionValues), () -> "Expected " + collectionValues + " to be part of " + allValues);
42-
List<List<T>> result = new ArrayList<>();
43-
for (T collectionValue : collectionValues) {
44-
List<T> values = new ArrayList<>();
40+
static <T> List<List<T>> multiplyWithOtherElements(Collection<T> allValues, Collection<? extends Collection<T>> collectionValues) {
41+
// Ex: multiplyWithOtherElements([abc, xyz, [L, M, S], [red, green, blue]], [[L, M, S], [red, green, blue]])
42+
// --> [[abc, xyz, L, red], [abc, xyz, M, green], [abc, xyz, S, blue]]
43+
final int collectionValueSize = CollectionUtils.getElementAtPosition(collectionValues, 0).size();
44+
for (Collection<T> collectionValue : collectionValues) {
45+
Assert.isTrue(allValues.contains(collectionValue), () -> "Expected " + collectionValue + " to be part of " + allValues);
46+
Assert.isTrue(collectionValue.size() == collectionValueSize, () -> "Expected " + collectionValue + " to be size " + collectionValueSize);
47+
}
48+
49+
List<List<T>> result = new ArrayList<>(collectionValueSize);
50+
for (int i = 0; i < collectionValueSize; i++) {
51+
final ArrayList<T> newValues = new ArrayList();
4552

4653
for (Object value : allValues) {
47-
if (value == collectionValues) {
48-
values.add(collectionValue);
54+
if (collectionValues.contains(value)) {
55+
newValues.add(CollectionUtils.getElementAtPosition((Collection<T>) value, i));
4956
} else {
50-
values.add((T) value);
57+
newValues.add((T) value);
5158
}
5259
}
5360

54-
result.add(values);
61+
result.add(newValues);
5562
}
63+
5664
return result;
5765
}
5866

core/src/main/java/de/bwaldvogel/mongo/backend/Index.java

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,20 +65,16 @@ Set<KeyValue> getKeyValues(Document document, boolean normalize) {
6565
valuesPerKey.replaceAll((key, value) -> Utils.normalizeValue(value));
6666
}
6767

68-
List<Collection<?>> collectionValues = valuesPerKey.values().stream()
68+
List<Collection<Object>> collectionValues = valuesPerKey.values().stream()
6969
.filter(value -> value instanceof Collection)
70-
.map(value -> (Collection<?>) value)
70+
.map(value -> (Collection<Object>) value)
7171
.collect(Collectors.toList());
7272

73-
if (collectionValues.size() == 1) {
74-
@SuppressWarnings("unchecked")
75-
Collection<Object> collectionValue = (Collection<Object>) CollectionUtils.getSingleElement(collectionValues);
76-
return CollectionUtils.multiplyWithOtherElements(valuesPerKey.values(), collectionValue).stream()
73+
if (collectionValues.size() > 0) {
74+
validateHasNoParallelArrays(document);
75+
return CollectionUtils.multiplyWithOtherElements(valuesPerKey.values(), collectionValues).stream()
7776
.map(KeyValue::new)
7877
.collect(StreamUtils.toLinkedHashSet());
79-
} else if (collectionValues.size() > 1) {
80-
validateHasNoParallelArrays(document);
81-
return collectCollectionValues(collectionValues);
8278
} else {
8379
return Collections.singleton(new KeyValue(valuesPerKey.values()));
8480
}

core/src/test/java/de/bwaldvogel/mongo/backend/CollectionUtilsTest.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,17 +64,28 @@ void testMultiplyWithOtherElements() throws Exception {
6464
List<Object> values = Arrays.asList(1, 2);
6565
List<Object> collection = Arrays.asList("abc", "def", values);
6666

67-
assertThat(CollectionUtils.multiplyWithOtherElements(collection, values))
67+
assertThat(CollectionUtils.multiplyWithOtherElements(collection, Arrays.asList(values)))
6868
.containsExactly(
6969
Arrays.asList("abc", "def", 1),
7070
Arrays.asList("abc", "def", 2)
7171
);
7272

7373
assertThatExceptionOfType(IllegalArgumentException.class)
74-
.isThrownBy(() -> CollectionUtils.multiplyWithOtherElements(collection, Arrays.asList(1, 2, 3)))
74+
.isThrownBy(() -> CollectionUtils.multiplyWithOtherElements(collection, Arrays.asList(Arrays.asList(1, 2, 3))))
7575
.withMessage("Expected [1, 2, 3] to be part of [abc, def, [1, 2]]");
7676
}
7777

78+
@Test
79+
void testMultiplyWithOtherElementsWrongSize() throws Exception {
80+
List<Object> smallValues = Arrays.asList(1, 2);
81+
List<Object> bigValues = Arrays.asList(1, 2, 3);
82+
List<Object> collection = Arrays.asList("abc", "def", smallValues, bigValues);
83+
84+
assertThatExceptionOfType(IllegalArgumentException.class)
85+
.isThrownBy(() -> CollectionUtils.multiplyWithOtherElements(collection, Arrays.asList(smallValues, bigValues)))
86+
.withMessage("Expected [1, 2, 3] to be size 2");
87+
}
88+
7889
@Test
7990
void testGetElementAtPosition_list() throws Exception {
8091
List<String> list = Arrays.asList("a", "b", "c");

memory-backend/src/test/java/de/bwaldvogel/mongo/backend/memory/index/MemoryUniqueIndexTest.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,28 @@ void testGetKeyValues_multiKey_document_nested_objects() throws Exception {
7272
);
7373
}
7474

75+
@Test
76+
void testGetKeyValues_multiKey_nested_objects_multiple_keys() throws Exception {
77+
Index<?> index = new MemoryUniqueIndex("name", Arrays.asList(
78+
new IndexKey("item", true),
79+
new IndexKey("stock.size", true),
80+
new IndexKey("stock.quantity", true)
81+
), false);
82+
83+
assertThat(index.getKeyValues(
84+
new Document("stock", Arrays.asList(
85+
new Document("size", "S").append("color", "red").append("quantity", 25),
86+
new Document("size", "S").append("color", "blue").append("quantity", 10),
87+
new Document("size", "M").append("color", "blue").append("quantity", 50)
88+
))
89+
.append("item", "abc")
90+
)).containsExactly(
91+
new KeyValue("abc", "S", 25.0),
92+
new KeyValue("abc", "S", 10.0),
93+
new KeyValue("abc", "M", 50.0)
94+
);
95+
}
96+
7597
private static Document jsonDocument(String json) {
7698
return convert(json(json));
7799
}

0 commit comments

Comments
 (0)