Skip to content

Commit

Permalink
Improved vector range argument parsing (#445)
Browse files Browse the repository at this point in the history
* Better argument parsing for vector range expressions

* Update contributors

* Simplify expression cases, include test coverage for method expressions.

* Reuse GetOperand for evaluating values

---------

Co-authored-by: James Abbott <james.abbott@crispthinking.com>
  • Loading branch information
abbottdev and James Abbott committed Apr 26, 2024
1 parent 875227a commit addbcad
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 2 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ We welcome code contributions from the community, if you want to contribute code
1. Fork this repo.
2. Make your Code Changes.
3. Write your tests.
4. Use the `docker run -p 6379:6379 redis/redis-stack-server` as your local environment for running the functional tests.
4. Use the `docker run -p 6379:6379 redis/redis-stack-server` as your local environment for running the functional tests. (Note: If your tests fail due to missing vocabulary, please run `fetch.models.sh` from the root directory until Git LFS has been resolved. These files are required for the tokenizers used by the functional tests)
5. Verify the tests pass (there may be a couple of deployment-specific tests (e.g. Sentinel/Cluster) in Redis.OM which will fail outside of the GH environment we've setup so don't worry about those).
6. If it's your first time contributing please add your Github handle the the Contributors section in the README.
7. Push your changes to GitHub.
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,7 @@ We'd love your contributions! If you want to contribute please read our [Contrib
* [@mdrakib](https://github.com/mdrakib)
* [@jrpavoncello](https://github.com/jrpavoncello)
* [@axnetg](https://github.com/axnetg)
* [@abbottdev](https://github.com/abbottdev)

<!-- Logo -->
[Logo]: images/logo.svg
Expand Down
5 changes: 4 additions & 1 deletion src/Redis.OM/Common/ExpressionParserUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1014,6 +1014,8 @@ private static object GetOperand(Expression expression)
{
MemberExpression me => GetValue(me.Member, ((ConstantExpression)me.Expression).Value),
ConstantExpression ce => ce.Value,
UnaryExpression ue when ue.NodeType == ExpressionType.Convert => Convert.ChangeType(GetOperand(ue.Operand), ue.Type),
MethodCallExpression me => me.Method.Invoke(me.Object, me.Arguments.Select(GetOperand).ToArray()),
_ => throw new InvalidOperationException("Could not determine value.")
};
}
Expand Down Expand Up @@ -1047,7 +1049,8 @@ private static string TranslateVectorRange(MethodCallExpression exp, List<object
bytes = vector.Embedding ?? throw new InvalidOperationException("Embedding was null");
}

var distance = (double)((ConstantExpression)exp.Arguments[2]).Value;
var distance = (double)GetOperand(exp.Arguments[2]);

var distanceArgName = parameters.Count.ToString();
parameters.Add(distance);
var vectorArgName = parameters.Count.ToString();
Expand Down
80 changes: 80 additions & 0 deletions test/Redis.OM.Vectorizer.Tests/VectorizerFunctionalTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public VectorizerFunctionalTests()
public void Test()
{
var connection = _provider.Connection;
connection.DropIndex(typeof(DocWithVectors));
connection.CreateIndex(typeof(DocWithVectors));
connection.Set(new DocWithVectors
{
Expand All @@ -33,6 +34,85 @@ public void Test()
collection.NearestNeighbors(x => x.Sentence!, 5, "Hello world this really is Hal.");
}

[Fact]
public void VectorRangeUnaryExpressionTest()
{
var connection = _provider.Connection;
connection.DropIndex(typeof(DocWithVectors));
connection.CreateIndex(typeof(DocWithVectors));
connection.Set(new DocWithVectors
{
Sentence = Vector.Of("Hello world this is Hal."),
ImagePath = Vector.Of("hal.jpg")
});

var variableRange = 5;
var collection = new RedisCollection<DocWithVectors>(connection);

// images
var res = collection.Where(x => x.Sentence!.VectorRange("Hal", variableRange, "score"));

Assert.NotNull(res.First().Scores!.RangeScore);
Assert.InRange(res.First().Scores!.RangeScore!.Value, 0, 1);

// sentences
collection.NearestNeighbors(x => x.Sentence!, variableRange, "Hello world this really is Hal.");
}

[Fact]
public void VectorRangeMemberExpressionTest()
{
var connection = _provider.Connection;
connection.DropIndex(typeof(DocWithVectors));
connection.CreateIndex(typeof(DocWithVectors));
connection.Set(new DocWithVectors
{
Sentence = Vector.Of("Hello world this is Hal."),
ImagePath = Vector.Of("hal.jpg")
});

double variableRange = 5 + 5;
var collection = new RedisCollection<DocWithVectors>(connection);

// images

var res = collection.Where(x => x.Sentence!.VectorRange("Hal", variableRange, "score"));

Assert.NotNull(res.First().Scores!.RangeScore);
Assert.InRange(res.First().Scores!.RangeScore!.Value, 0, 1);

// sentences
collection.NearestNeighbors(x => x.Sentence!, 5, "Hello world this really is Hal.");
}

private static double GetVectorRange() => 5;
private static int GetKnnNeighbours() => 5;

[Fact]
public void VectorRangeMethodExpressionTest()
{
var connection = _provider.Connection;
connection.DropIndex(typeof(DocWithVectors));
connection.CreateIndex(typeof(DocWithVectors));
connection.Set(new DocWithVectors
{
Sentence = Vector.Of("Hello world this is Hal."),
ImagePath = Vector.Of("hal.jpg")
});

var collection = new RedisCollection<DocWithVectors>(connection);

// images

var res = collection.Where(x => x.Sentence!.VectorRange("Hal", GetVectorRange(), "score"));

Assert.NotNull(res.First().Scores!.RangeScore);
Assert.InRange(res.First().Scores!.RangeScore!.Value, 0, 1);

// sentences
collection.NearestNeighbors(x => x.Sentence!, GetKnnNeighbours(), "Hello world this really is Hal.");
}

[Fact]
public void SemanticCaching()
{
Expand Down

0 comments on commit addbcad

Please sign in to comment.