diff --git a/src/commands/cmd_search.cc b/src/commands/cmd_search.cc index 7a09885e511..75bf08dd908 100644 --- a/src/commands/cmd_search.cc +++ b/src/commands/cmd_search.cc @@ -449,13 +449,31 @@ class CommandFTInfo : public Commander { output->append(redis::SimpleString("type")); auto type = field.metadata->Type(); output->append(redis::BulkString(std::string(type.begin(), type.end()))); - output->append(redis::SimpleString("options")); + output->append(redis::SimpleString("properties")); if (auto tag = field.MetadataAs()) { output->append(redis::MultiLen(4)); output->append(redis::SimpleString("separator")); output->append(redis::BulkString(std::string(1, tag->separator))); output->append(redis::SimpleString("case_sensitive")); output->append(conn->Bool(tag->case_sensitive)); + } else if (auto vec = field.MetadataAs()) { + output->append(redis::MultiLen(16)); + output->append(redis::SimpleString("algorithm")); + output->append(redis::SimpleString("HNSW")); + output->append(redis::SimpleString("vector_type")); + output->append(redis::SimpleString(VectorTypeToString(vec->vector_type))); + output->append(redis::SimpleString("dim")); + output->append(redis::Integer(vec->dim)); + output->append(redis::SimpleString("distance_metric")); + output->append(redis::SimpleString(DistanceMetricToString(vec->distance_metric))); + output->append(redis::SimpleString("m")); + output->append(redis::Integer(vec->m)); + output->append(redis::SimpleString("ef_construction")); + output->append(redis::Integer(vec->ef_construction)); + output->append(redis::SimpleString("ef_runtime")); + output->append(redis::Integer(vec->ef_runtime)); + output->append(redis::SimpleString("epsilon")); + output->append(conn->Double(vec->epsilon)); } else { output->append(redis::MultiLen(0)); } diff --git a/src/search/search_encoding.h b/src/search/search_encoding.h index 26b442ca32c..bbc84f84735 100644 --- a/src/search/search_encoding.h +++ b/src/search/search_encoding.h @@ -85,12 +85,34 @@ enum class VectorType : uint8_t { FLOAT64 = 1, }; +inline const char *VectorTypeToString(VectorType type) { + switch (type) { + case VectorType::FLOAT64: + return "FLOAT64"; + } + + return "unknown"; +} + enum class DistanceMetric : uint8_t { L2 = 0, IP = 1, COSINE = 2, }; +inline const char *DistanceMetricToString(DistanceMetric dm) { + switch (dm) { + case DistanceMetric::L2: + return "L2"; + case DistanceMetric::IP: + return "IP"; + case DistanceMetric::COSINE: + return "COSINE"; + } + + return "unknown"; +} + enum class HnswLevelType : uint8_t { NODE = 1, EDGE = 2, diff --git a/tests/gocase/unit/search/search_test.go b/tests/gocase/unit/search/search_test.go index b67d1d7fa0c..e93b1dee7c3 100644 --- a/tests/gocase/unit/search/search_test.go +++ b/tests/gocase/unit/search/search_test.go @@ -64,9 +64,9 @@ func TestSearch(t *testing.T) { require.Equal(t, "index_definition", idxInfo[2]) require.Equal(t, []interface{}{"key_type", "ReJSON-RL", "prefixes", []interface{}{"test1:"}}, idxInfo[3]) require.Equal(t, "fields", idxInfo[4]) - require.Equal(t, []interface{}{"identifier", "a", "type", "tag", "options", []interface{}{"separator", ",", "case_sensitive", int64(0)}}, idxInfo[5].([]interface{})[0]) - require.Equal(t, []interface{}{"identifier", "b", "type", "numeric", "options", []interface{}{}}, idxInfo[5].([]interface{})[1]) - require.Equal(t, []interface{}{"identifier", "c", "type", "vector", "options", []interface{}{}}, idxInfo[5].([]interface{})[2]) + require.Equal(t, []interface{}{"identifier", "a", "type", "tag", "properties", []interface{}{"separator", ",", "case_sensitive", int64(0)}}, idxInfo[5].([]interface{})[0]) + require.Equal(t, []interface{}{"identifier", "b", "type", "numeric", "properties", []interface{}{}}, idxInfo[5].([]interface{})[1]) + require.Equal(t, []interface{}{"identifier", "c", "type", "vector", "properties", []interface{}{"algorithm", "HNSW", "vector_type", "FLOAT64", "dim", int64(3), "distance_metric", "L2", "m", int64(16), "ef_construction", int64(200), "ef_runtime", int64(10), "epsilon", "0.01"}}, idxInfo[5].([]interface{})[2]) } verify(t)