Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Java: FT.PROFILE #2473

Open
wants to merge 6 commits into
base: release-1.2
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* Java: Added `FT.DROPINDEX` ([#2440](https://github.com/valkey-io/valkey-glide/pull/2440))
* Java: Added `FT.SEARCH` ([#2439](https://github.com/valkey-io/valkey-glide/pull/2439))
* Java: Added `FT.AGGREGATE` ([#2466](https://github.com/valkey-io/valkey-glide/pull/2466))
* Java: Added `FT.PROFILE` ([#2473](https://github.com/valkey-io/valkey-glide/pull/2473))
* Java: Added `JSON.SET` and `JSON.GET` ([#2462](https://github.com/valkey-io/valkey-glide/pull/2462))
* Java: Added `JSON.ARRINSERT` and `JSON.ARRLEN` ([#2476](https://github.com/valkey-io/valkey-glide/pull/2476))
* Java: Added `FT.ALIASADD`, `FT.ALIASDEL`, `FT.ALIASUPDATE` ([#2442](https://github.com/valkey-io/valkey-glide/pull/2442))
Expand Down
51 changes: 49 additions & 2 deletions glide-core/src/client/value_conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pub(crate) enum ExpectedReturnType<'a> {
ArrayOfDoubleOrNull,
FTAggregateReturnType,
FTSearchReturnType,
FTProfileReturnType(&'a Option<ExpectedReturnType<'a>>),
FTInfoReturnType,
Lolwut,
ArrayOfStringAndArrays,
Expand Down Expand Up @@ -939,7 +940,7 @@ pub(crate) fn convert_to_expected_type(
let Value::Array(fields) = aggregation else {
return Err((
ErrorKind::TypeError,
"Response couldn't be converted for FT.AGGREGATION",
"Response couldn't be converted for FT.AGGREGATE",
format!("(`fields` was {:?})", get_value_type(&aggregation)),
)
.into());
Expand All @@ -954,7 +955,7 @@ pub(crate) fn convert_to_expected_type(
}
_ => Err((
ErrorKind::TypeError,
"Response couldn't be converted to FT.AGGREGATION",
"Response couldn't be converted for FT.AGGREGATE",
format!("(response was {:?})", get_value_type(&value)),
)
.into()),
Expand Down Expand Up @@ -1106,6 +1107,44 @@ pub(crate) fn convert_to_expected_type(
)
.into())
},
ExpectedReturnType::FTProfileReturnType(type_of_query) => match value {
/*
Example of the response
1) <query response>
2) 1) 1) "parse.time"
2) 119
2) 1) "all.count"
2) 4
3) 1) "sync.time"
2) 0
...

Converting response to
1) <converted query response>
2) 1# "parse.time" => 119
2# "all.count" => 4
3# "sync.time" => 0
...

Converting first array element as it is needed for the inner query and second element to a map.
*/
Value::Array(mut array) if array.len() == 2 => {
let res = vec![
convert_to_expected_type(array.remove(0), *type_of_query)?,
convert_to_expected_type(array.remove(0), Some(ExpectedReturnType::Map {
key_type: &None,
value_type: &None,
}))?];

Ok(Value::Array(res))
},
_ => Err((
ErrorKind::TypeError,
"Response couldn't be converted for FT.PROFILE",
format!("(response was {:?})", get_value_type(&value)),
)
.into())
}
}
}

Expand Down Expand Up @@ -1472,6 +1511,14 @@ pub(crate) fn expected_type_for_cmd(cmd: &Cmd) -> Option<ExpectedReturnType> {
}),
b"FT.AGGREGATE" => Some(ExpectedReturnType::FTAggregateReturnType),
b"FT.SEARCH" => Some(ExpectedReturnType::FTSearchReturnType),
// TODO replace with tuple
b"FT.PROFILE" => Some(ExpectedReturnType::FTProfileReturnType(
if cmd.arg_idx(2).is_some_and(|a| a == b"SEARCH") {
Copy link
Collaborator

Choose a reason for hiding this comment

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

interesting solution - good re-use of code

&Some(ExpectedReturnType::FTSearchReturnType)
} else {
&Some(ExpectedReturnType::FTAggregateReturnType)
},
)),
b"FT.INFO" => Some(ExpectedReturnType::FTInfoReturnType),
_ => None,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import glide.api.models.commands.FT.FTAggregateOptions;
import glide.api.models.commands.FT.FTCreateOptions;
import glide.api.models.commands.FT.FTCreateOptions.FieldInfo;
import glide.api.models.commands.FT.FTProfileOptions;
import glide.api.models.commands.FT.FTSearchOptions;
import java.util.Arrays;
import java.util.Map;
Expand Down Expand Up @@ -474,6 +475,54 @@ public static CompletableFuture<Map<GlideString, Object>[]> aggregate(
.thenApply(res -> castArray(res, Map.class));
}

/**
* Runs a search or aggregation query and collects performance profiling information.
*
* @param client The client to execute the command.
* @param indexName The index name.
* @param options Querying and profiling parameters - see {@link FTProfileOptions}.
* @return A two-element array. The first element contains results of query being profiled, the
* second element stores profiling information.
Yury-Fridlyand marked this conversation as resolved.
Show resolved Hide resolved
* @example
* <pre>{@code
* var options = FTSearchOptions.builder().params(Map.of(
* gs("query_vec"),
* gs(new byte[] { (byte) 0, (byte) 0, (byte) 0, (byte) 0 })))
* .build();
* var result = FT.profile(client, "myIndex", new FTProfileOptions("*=>[KNN 2 @VEC $query_vec]", options)).get();
* // result[0] contains `FT.SEARCH` response with the given options and query
* // result[1] contains profiling data as a `Map<GlideString, Long>`
* }</pre>
*/
public static CompletableFuture<Object[]> profile(
@NonNull BaseClient client, @NonNull String indexName, @NonNull FTProfileOptions options) {
return profile(client, gs(indexName), options);
}

/**
* Runs a search or aggregation query and collects performance profiling information.
*
* @param client The client to execute the command.
* @param indexName The index name.
* @param options Querying and profiling parameters - see {@link FTProfileOptions}.
* @return A two-element array. The first element contains results of query being profiled, the
* second element stores profiling information.
* @example
* <pre>{@code
* var commandLine = new String[] { "*", "LOAD", "1", "__key", "GROUPBY", "1", "@condition", "REDUCE", "COUNT", "0", "AS", "bicylces" };
* var result = FT.profile(client, gs("myIndex"), new FTProfileOptions(QueryType.AGGREGATE, commandLine)).get();
* // result[0] contains `FT.AGGREGATE` response with the given command line
* // result[1] contains profiling data as a `Map<GlideString, Long>`
* }</pre>
*/
public static CompletableFuture<Object[]> profile(
@NonNull BaseClient client,
@NonNull GlideString indexName,
@NonNull FTProfileOptions options) {
var args = concatenateArrays(new GlideString[] {gs("FT.PROFILE"), indexName}, options.toArgs());
return executeCommand(client, args, false);
}

/**
* Returns information about a given index.
*
Expand Down Expand Up @@ -693,7 +742,6 @@ public static CompletableFuture<String> aliasupdate(
public static CompletableFuture<String> aliasupdate(
@NonNull BaseClient client, @NonNull GlideString aliasName, @NonNull GlideString indexName) {
var args = new GlideString[] {gs("FT.ALIASUPDATE"), aliasName, indexName};

return executeCommand(client, args, false);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import java.util.Map;
import java.util.stream.Stream;
import lombok.Builder;
import lombok.NonNull;

/**
* Additional arguments for {@link FT#aggregate(BaseClient, String, String, FTAggregateOptions)}
Expand Down Expand Up @@ -79,19 +80,19 @@ public FTAggregateOptionsBuilder loadAll() {
return this;
}

public FTAggregateOptionsBuilder loadFields(String[] fields) {
public FTAggregateOptionsBuilder loadFields(@NonNull String[] fields) {
loadFields = toGlideStringArray(fields);
loadAll = false;
return this;
}

public FTAggregateOptionsBuilder loadFields(GlideString[] fields) {
public FTAggregateOptionsBuilder loadFields(@NonNull GlideString[] fields) {
loadFields = fields;
loadAll = false;
return this;
}

public FTAggregateOptionsBuilder addExpression(FTAggregateExpression expression) {
public FTAggregateOptionsBuilder addExpression(@NonNull FTAggregateExpression expression) {
if (expressions == null) expressions = new ArrayList<>();
expressions.add(expression);
return this;
Expand Down Expand Up @@ -138,11 +139,11 @@ GlideString[] toArgs() {
public static class Filter extends FTAggregateExpression {
private final GlideString expression;

public Filter(GlideString expression) {
public Filter(@NonNull GlideString expression) {
this.expression = expression;
}

public Filter(String expression) {
public Filter(@NonNull String expression) {
this.expression = gs(expression);
}

Expand All @@ -160,22 +161,22 @@ public static class GroupBy extends FTAggregateExpression {
private final GlideString[] properties;
private final Reducer[] reducers;

public GroupBy(GlideString[] properties, Reducer[] reducers) {
public GroupBy(@NonNull GlideString[] properties, @NonNull Reducer[] reducers) {
this.properties = properties;
this.reducers = reducers;
}

public GroupBy(String[] properties, Reducer[] reducers) {
public GroupBy(@NonNull String[] properties, @NonNull Reducer[] reducers) {
this.properties = toGlideStringArray(properties);
this.reducers = reducers;
}

public GroupBy(GlideString[] properties) {
public GroupBy(@NonNull GlideString[] properties) {
this.properties = properties;
this.reducers = new Reducer[0];
}

public GroupBy(String[] properties) {
public GroupBy(@NonNull String[] properties) {
this.properties = toGlideStringArray(properties);
this.reducers = new Reducer[0];
}
Expand All @@ -199,25 +200,25 @@ public static class Reducer {
private final GlideString[] args;
private final String alias;

public Reducer(String function, GlideString[] args, String alias) {
public Reducer(@NonNull String function, @NonNull GlideString[] args, @NonNull String alias) {
this.function = function;
this.args = args;
this.alias = alias;
}

public Reducer(String function, GlideString[] args) {
public Reducer(@NonNull String function, @NonNull GlideString[] args) {
this.function = function;
this.args = args;
this.alias = null;
}

public Reducer(String function, String[] args, String alias) {
public Reducer(@NonNull String function, @NonNull String[] args, @NonNull String alias) {
this.function = function;
this.args = toGlideStringArray(args);
this.alias = alias;
}

public Reducer(String function, String[] args) {
public Reducer(@NonNull String function, @NonNull String[] args) {
this.function = function;
this.args = toGlideStringArray(args);
this.alias = null;
Expand All @@ -240,12 +241,12 @@ public static class SortBy extends FTAggregateExpression {
private final SortProperty[] properties;
private final Integer max;

public SortBy(SortProperty[] properties) {
public SortBy(@NonNull SortProperty[] properties) {
this.properties = properties;
this.max = null;
}

public SortBy(SortProperty[] properties, int max) {
public SortBy(@NonNull SortProperty[] properties, int max) {
this.properties = properties;
this.max = max;
}
Expand Down Expand Up @@ -273,12 +274,12 @@ public static class SortProperty {
private final GlideString property;
private final SortOrder order;

public SortProperty(GlideString property, SortOrder order) {
public SortProperty(@NonNull GlideString property, @NonNull SortOrder order) {
this.property = property;
this.order = order;
}

public SortProperty(String property, SortOrder order) {
public SortProperty(@NonNull String property, @NonNull SortOrder order) {
this.property = gs(property);
this.order = order;
}
Expand All @@ -297,12 +298,12 @@ public static class Apply extends FTAggregateExpression {
private final GlideString expression;
private final GlideString alias;

public Apply(GlideString expression, GlideString alias) {
public Apply(@NonNull GlideString expression, @NonNull GlideString alias) {
this.expression = expression;
this.alias = alias;
}

public Apply(String expression, String alias) {
public Apply(@NonNull String expression, @NonNull String alias) {
this.expression = gs(expression);
this.alias = gs(alias);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public GlideString[] toArgs() {
}

public static class FTCreateOptionsBuilder {
public FTCreateOptionsBuilder prefixes(String[] prefixes) {
public FTCreateOptionsBuilder prefixes(@NonNull String[] prefixes) {
this.prefixes = Stream.of(prefixes).map(GlideString::gs).toArray(GlideString[]::new);
return this;
}
Expand Down
Loading
Loading