Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
22 changes: 22 additions & 0 deletions src/main/java/com/aerospike/dsl/IndexContext.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.aerospike.dsl;

import com.aerospike.dsl.client.query.Filter;
import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.Collection;
import java.util.List;

/**
* This class stores namespace and indexes required to build secondary index Filter
Expand All @@ -22,4 +24,24 @@ public class IndexContext {
* with bins in DSL String
*/
private Collection<Index> indexes;


/**
* Create index context specifying the index to be used.
*
* @param namespace Namespace to be used for creating {@link Filter}. Is matched with namespace of indexes
* @param indexes Collection of {@link Index} objects to be used for creating {@link Filter}. Bin name and
* index type are matched with bins in DSL String
* @param indexToUse The name of an index to use for creating {@link Filter}. If the index with the specified name
* is not found, the resulting index is chosen the usual way (cardinality-based or alphabetically)
* @return A new instance of {@code IndexContext}
*/
public static IndexContext of(String namespace, Collection<Index> indexes, String indexToUse) {
List<Index> singleIndexList = indexes.stream().filter(idx -> areNamesEqual(idx, indexToUse)).toList();
return new IndexContext(namespace, singleIndexList.isEmpty() ? indexes : singleIndexList);
}

private static boolean areNamesEqual(Index idx, String indexToUse) {
return idx != null && idx.getName() != null && idx.getName().equals(indexToUse);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,41 @@ void binLogical_AND_AND_all_indexes_no_cardinality() {
IndexContext.of(TestUtils.NAMESPACE, indexes));
}

@Test
void binLogical_AND_AND_explicitly_given_index() {
List<Index> indexes = List.of(
Index.builder().namespace(TestUtils.NAMESPACE).name("idx_bin1").bin("intBin1")
.indexType(IndexType.NUMERIC).binValuesRatio(0).build(),
Index.builder().namespace(TestUtils.NAMESPACE).name("idx_bin2").bin("intBin2")
.indexType(IndexType.NUMERIC).binValuesRatio(1).build(),
Index.builder().namespace(TestUtils.NAMESPACE).name("idx_bin3").bin("intBin3")
.indexType(IndexType.NUMERIC).binValuesRatio(0).build()
);
Filter filter = Filter.range("intBin1", 101, Long.MAX_VALUE); // The index has been chosen manually
Exp exp = Exp.and(
Exp.gt(Exp.intBin("intBin2"), Exp.val(100)),
Exp.gt(Exp.intBin("intBin3"), Exp.val(100))
);
parseDslExpressionAndCompare(ExpressionContext.of("$.intBin1 > 100 and $.intBin2 > 100 and $.intBin3 > 100"), filter, exp,
IndexContext.of(TestUtils.NAMESPACE, indexes, "idx_bin1")); // Manually selecting the index by its name
}

@Test
void binLogical_AND_AND_explicitly_given_index_unavailable() {
List<Index> indexes = List.of(
Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(),
Index.builder().namespace(TestUtils.NAMESPACE).name("idx_bin2").bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build(),
Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(0).build()
);
Filter filter = Filter.range("intBin2", 101, Long.MAX_VALUE); // Fallback to choosing the index regularly
Exp exp = Exp.and(
Exp.gt(Exp.intBin("intBin1"), Exp.val(100)),
Exp.gt(Exp.intBin("intBin3"), Exp.val(100))
);
parseDslExpressionAndCompare(ExpressionContext.of("$.intBin1 > 100 and $.intBin2 > 100 and $.intBin3 > 100"), filter, exp,
IndexContext.of(TestUtils.NAMESPACE, indexes, "intBin10")); // There is no index with the name "intBin10"
}

@Test
void binLogical_AND_AND_all_indexes_partial_data() {
List<Index> indexes = List.of(
Expand Down
Loading