Skip to content

Commit 193006b

Browse files
committed
Fix to #35983 - Cosmos/FTS: update translation of FullTextScore to use multiple keywords rather than keyword array
Reacting to Cosmos changing the signature of FullTextScore function. Fixes #35983
1 parent 74350ae commit 193006b

File tree

4 files changed

+50
-54
lines changed

4 files changed

+50
-54
lines changed

src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.ParameterInliner.cs

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,17 @@ protected override Expression VisitExtension(Expression expression)
8080
}
8181

8282
// Inlines array parameter of full-text functions, transforming FullTextContainsAll(x, @keywordsArray) to FullTextContainsAll(x, keyword1, keyword2))
83+
// we do this for FullTextContainsAll, FullTextContainsAny and FullTextScore
8384
case SqlFunctionExpression
8485
{
85-
Name: "FullTextContainsAny" or "FullTextContainsAll",
86+
Name: string name,
87+
IsScoringFunction: bool scoringFunction,
8688
Arguments: [var property, SqlParameterExpression { TypeMapping: { ElementTypeMapping: var elementTypeMapping }, Type: Type type } keywords]
8789
} fullTextContainsAllAnyFunction
88-
when type == typeof(string[]):
90+
when ((name == "FullTextContainsAny" && !scoringFunction)
91+
|| (name == "FullTextContainsAll" && !scoringFunction)
92+
|| (name == "FullTextScore" && scoringFunction))
93+
&& type == typeof(string[]):
8994
{
9095
var keywordValues = new List<SqlExpression>();
9196
foreach (var value in (IEnumerable)parametersValues[keywords.Name])
@@ -100,28 +105,6 @@ protected override Expression VisitExtension(Expression expression)
100105
fullTextContainsAllAnyFunction.TypeMapping);
101106
}
102107

103-
// Inlines array parameter of full-text score, transforming FullTextScore(x, @keywordsArray) to FullTextScore(x, [keyword1, keyword2]))
104-
case SqlFunctionExpression
105-
{
106-
Name: "FullTextScore",
107-
IsScoringFunction: true,
108-
Arguments: [var property, SqlParameterExpression { TypeMapping: { ElementTypeMapping: not null } typeMapping } keywords]
109-
} fullTextScoreFunction:
110-
{
111-
var keywordValues = new List<string>();
112-
foreach (var value in (IEnumerable)parametersValues[keywords.Name])
113-
{
114-
keywordValues.Add((string)value);
115-
}
116-
117-
return new SqlFunctionExpression(
118-
fullTextScoreFunction.Name,
119-
scoringFunction: true,
120-
[property, sqlExpressionFactory.Constant(keywordValues, typeMapping)],
121-
fullTextScoreFunction.Type,
122-
fullTextScoreFunction.TypeMapping);
123-
}
124-
125108
default:
126109
return expression;
127110
}

src/EFCore.Cosmos/Query/Internal/Translators/CosmosFullTextSearchTranslator.cs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,25 @@ public class CosmosFullTextSearchTranslator(ISqlExpressionFactory sqlExpressionF
4141
typeMappingSource.FindMapping(typeof(bool))),
4242

4343
nameof(CosmosDbFunctionsExtensions.FullTextScore)
44-
when arguments is [_, var property, var keywords] => sqlExpressionFactory.ScoringFunction(
44+
when arguments is [_, SqlExpression property, SqlConstantExpression { Type: var keywordClrType, Value: string[] values } keywords]
45+
&& keywordClrType == typeof(string[]) => sqlExpressionFactory.ScoringFunction(
46+
"FullTextScore",
47+
[property, .. values.Select(x => sqlExpressionFactory.Constant(x))],
48+
typeof(double),
49+
typeMappingSource.FindMapping(typeof(double))),
50+
51+
nameof(CosmosDbFunctionsExtensions.FullTextScore)
52+
when arguments is [_, SqlExpression property, SqlParameterExpression { Type: var keywordClrType } keywords]
53+
&& keywordClrType == typeof(string[]) => sqlExpressionFactory.ScoringFunction(
54+
"FullTextScore",
55+
[property, keywords],
56+
typeof(double),
57+
typeMappingSource.FindMapping(typeof(double))),
58+
59+
nameof(CosmosDbFunctionsExtensions.FullTextScore)
60+
when arguments is [_, SqlExpression property, ArrayConstantExpression keywords] => sqlExpressionFactory.ScoringFunction(
4561
"FullTextScore",
46-
[
47-
property,
48-
keywords,
49-
],
62+
[property, .. keywords.Items],
5063
typeof(double),
5164
typeMappingSource.FindMapping(typeof(double))),
5265

test/EFCore.Cosmos.FunctionalTests/FullTextSearchCosmosTest.cs

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ public virtual async Task OrderByRank_FullTextScore_constant()
292292
"""
293293
SELECT VALUE c
294294
FROM root c
295-
ORDER BY RANK FullTextScore(c["Description"], ["otter"])
295+
ORDER BY RANK FullTextScore(c["Description"], "otter")
296296
""");
297297
}
298298

@@ -309,7 +309,7 @@ public virtual async Task OrderByRank_FullTextScore_constants()
309309
"""
310310
SELECT VALUE c
311311
FROM root c
312-
ORDER BY RANK FullTextScore(c["Description"], ["otter","beaver"])
312+
ORDER BY RANK FullTextScore(c["Description"], "otter", "beaver")
313313
""");
314314
}
315315

@@ -326,7 +326,7 @@ public virtual async Task OrderByRank_FullTextScore_constant_array()
326326
"""
327327
SELECT VALUE c
328328
FROM root c
329-
ORDER BY RANK FullTextScore(c["Description"], ["otter","beaver"])
329+
ORDER BY RANK FullTextScore(c["Description"], "otter", "beaver")
330330
""");
331331
}
332332

@@ -343,7 +343,7 @@ public virtual async Task OrderByRank_FullTextScore_constant_array_with_one_elem
343343
"""
344344
SELECT VALUE c
345345
FROM root c
346-
ORDER BY RANK FullTextScore(c["Description"], ["otter"])
346+
ORDER BY RANK FullTextScore(c["Description"], "otter")
347347
""");
348348
}
349349

@@ -361,7 +361,7 @@ public virtual async Task OrderByRank_FullTextScore_parameter_array()
361361
"""
362362
SELECT VALUE c
363363
FROM root c
364-
ORDER BY RANK FullTextScore(c["Description"], ["otter","beaver"])
364+
ORDER BY RANK FullTextScore(c["Description"], "otter", "beaver")
365365
""");
366366
}
367367

@@ -384,7 +384,7 @@ public virtual async Task OrderByRank_FullTextScore_using_parameters()
384384
385385
SELECT VALUE c
386386
FROM root c
387-
ORDER BY RANK FullTextScore(c["Description"], [@otter, @beaver])
387+
ORDER BY RANK FullTextScore(c["Description"], @otter, @beaver)
388388
""");
389389
}
390390

@@ -405,7 +405,7 @@ public virtual async Task OrderByRank_FullTextScore_using_one_parameter()
405405
406406
SELECT VALUE c
407407
FROM root c
408-
ORDER BY RANK FullTextScore(c["Description"], [@otter])
408+
ORDER BY RANK FullTextScore(c["Description"], @otter)
409409
""");
410410
}
411411

@@ -426,7 +426,7 @@ public virtual async Task OrderByRank_FullTextScore_using_parameters_constant_mi
426426
427427
SELECT VALUE c
428428
FROM root c
429-
ORDER BY RANK FullTextScore(c["Description"], ["otter", @beaver])
429+
ORDER BY RANK FullTextScore(c["Description"], "otter", @beaver)
430430
""");
431431
}
432432

@@ -447,7 +447,7 @@ public virtual async Task OrderByRank_FullTextScore_using_parameter()
447447
448448
SELECT VALUE c
449449
FROM root c
450-
ORDER BY RANK FullTextScore(c["Description"], [@otter])
450+
ORDER BY RANK FullTextScore(c["Description"], @otter)
451451
""");
452452
}
453453

@@ -495,7 +495,7 @@ public virtual async Task OrderByRank_FullTextScore_on_non_FTS_property()
495495
"""
496496
SELECT VALUE c
497497
FROM root c
498-
ORDER BY RANK FullTextScore(c["PartitionKey"], ["taxonomy"])
498+
ORDER BY RANK FullTextScore(c["PartitionKey"], "taxonomy")
499499
""");
500500
}
501501

@@ -514,7 +514,7 @@ public virtual async Task OrderByRank_with_RRF_using_two_FullTextScore_functions
514514
"""
515515
SELECT VALUE c
516516
FROM root c
517-
ORDER BY RANK RRF(FullTextScore(c["Description"], ["beaver"]), FullTextScore(c["Description"], ["otter","bat"]))
517+
ORDER BY RANK RRF(FullTextScore(c["Description"], "beaver"), FullTextScore(c["Description"], "otter", "bat"))
518518
""");
519519
}
520520

@@ -584,7 +584,7 @@ public virtual async Task OrderByRank_Take()
584584
"""
585585
SELECT VALUE c
586586
FROM root c
587-
ORDER BY RANK FullTextScore(c["Description"], ["beaver"])
587+
ORDER BY RANK FullTextScore(c["Description"], "beaver")
588588
OFFSET 0 LIMIT 10
589589
""");
590590
}
@@ -603,7 +603,7 @@ public virtual async Task OrderByRank_Skip_Take()
603603
"""
604604
SELECT VALUE c
605605
FROM root c
606-
ORDER BY RANK FullTextScore(c["Description"], ["beaver","dolphin"])
606+
ORDER BY RANK FullTextScore(c["Description"], "beaver", "dolphin")
607607
OFFSET 1 LIMIT 20
608608
""");
609609
}
@@ -633,7 +633,7 @@ public virtual async Task OrderBy_scoring_function_overridden_by_another()
633633
"""
634634
SELECT VALUE c
635635
FROM root c
636-
ORDER BY RANK FullTextScore(c["Description"], ["beaver","dolphin","second"])
636+
ORDER BY RANK FullTextScore(c["Description"], "beaver", "dolphin", "second")
637637
""");
638638
}
639639

@@ -667,7 +667,7 @@ public virtual async Task Regular_OrderBy_overridden_by_OrderBy_using_scoring_fu
667667
"""
668668
SELECT VALUE c
669669
FROM root c
670-
ORDER BY RANK FullTextScore(c["Description"], ["beaver","dolphin"])
670+
ORDER BY RANK FullTextScore(c["Description"], "beaver", "dolphin")
671671
""");
672672
}
673673

@@ -725,7 +725,7 @@ public virtual async Task OrderByRank_Where()
725725
SELECT VALUE c
726726
FROM root c
727727
WHERE ((c["PartitionKey"] || "Foo") = "habitatFoo")
728-
ORDER BY RANK FullTextScore(c["Description"], ["beaver","dolphin"])
728+
ORDER BY RANK FullTextScore(c["Description"], "beaver", "dolphin")
729729
""");
730730
}
731731

@@ -779,7 +779,7 @@ public virtual async Task OrderByRank_with_FullTextScore_on_nested_owned_type()
779779
"""
780780
SELECT VALUE c
781781
FROM root c
782-
ORDER BY RANK FullTextScore(c["Owned"]["NestedReference"]["AnotherDescription"], ["beaver","dolphin"])
782+
ORDER BY RANK FullTextScore(c["Owned"]["NestedReference"]["AnotherDescription"], "beaver", "dolphin")
783783
""");
784784
}
785785

@@ -816,7 +816,7 @@ public virtual async Task OrderByRank_with_FullTextScore_on_nested_owned_collect
816816
"""
817817
SELECT VALUE c
818818
FROM root c
819-
ORDER BY RANK FullTextScore(c["Owned"]["NestedCollection"][0]["AnotherDescription"], ["beaver","dolphin"])
819+
ORDER BY RANK FullTextScore(c["Owned"]["NestedCollection"][0]["AnotherDescription"], "beaver", "dolphin")
820820
""");
821821
}
822822

@@ -832,7 +832,7 @@ public virtual async Task OrderBy_scoring_function_on_property_with_modified_jso
832832
"""
833833
SELECT VALUE c
834834
FROM root c
835-
ORDER BY RANK FullTextScore(c["CustomDecription"], ["beaver","dolphin"])
835+
ORDER BY RANK FullTextScore(c["CustomDecription"], "beaver", "dolphin")
836836
""");
837837
}
838838

@@ -849,7 +849,7 @@ public virtual async Task OrderByRank_with_FullTextScore_on_nested_owned_type_wi
849849
"""
850850
SELECT VALUE c
851851
FROM root c
852-
ORDER BY RANK FullTextScore(c["Owned"]["CustomNestedReference"]["AnotherDescription"], ["beaver","dolphin"])
852+
ORDER BY RANK FullTextScore(c["Owned"]["CustomNestedReference"]["AnotherDescription"], "beaver", "dolphin")
853853
""");
854854
}
855855

@@ -866,7 +866,7 @@ public virtual async Task OrderByRank_with_FullTextScore_on_property_without_ind
866866
"""
867867
SELECT VALUE c
868868
FROM root c
869-
ORDER BY RANK FullTextScore(c["DescriptionNoIndex"], ["beaver","dolphin"])
869+
ORDER BY RANK FullTextScore(c["DescriptionNoIndex"], "beaver", "dolphin")
870870
""");
871871
}
872872

test/EFCore.Cosmos.FunctionalTests/HybridSearchCosmosTest.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public virtual async Task Hybrid_search_vector_distance_and_FullTextScore_in_Ord
3939
4040
SELECT VALUE c
4141
FROM root c
42-
ORDER BY RANK RRF(FullTextScore(c["Description"], ["beaver","otter"]), VectorDistance(c["SBytes"], @inputVector, false, {'distanceFunction':'dotproduct', 'dataType':'int8'}))
42+
ORDER BY RANK RRF(FullTextScore(c["Description"], "beaver", "otter"), VectorDistance(c["SBytes"], @inputVector, false, {'distanceFunction':'dotproduct', 'dataType':'int8'}))
4343
""");
4444
}
4545

@@ -62,7 +62,7 @@ public virtual async Task Hybrid_search_vector_distance_and_FullTextScore_with_s
6262
6363
SELECT VALUE c
6464
FROM root c
65-
ORDER BY RANK RRF(FullTextScore(c["Description"], ["beaver"]), VectorDistance(c["SBytes"], @inputVector, false, {'distanceFunction':'dotproduct', 'dataType':'int8'}))
65+
ORDER BY RANK RRF(FullTextScore(c["Description"], "beaver"), VectorDistance(c["SBytes"], @inputVector, false, {'distanceFunction':'dotproduct', 'dataType':'int8'}))
6666
""");
6767
}
6868

@@ -84,7 +84,7 @@ public virtual async Task Hybrid_search_vector_distance_and_FullTextScore_in_Ord
8484
8585
SELECT VALUE c
8686
FROM root c
87-
ORDER BY RANK RRF(FullTextScore(c["Owned"]["AnotherDescription"], ["beaver"]), VectorDistance(c["Owned"]["Singles"], @inputVector, false, {'distanceFunction':'cosine', 'dataType':'float32'}))
87+
ORDER BY RANK RRF(FullTextScore(c["Owned"]["AnotherDescription"], "beaver"), VectorDistance(c["Owned"]["Singles"], @inputVector, false, {'distanceFunction':'cosine', 'dataType':'float32'}))
8888
""");
8989
}
9090

@@ -107,7 +107,7 @@ public virtual async Task Hybrid_search_vector_distance_and_FullTextScore_in_Ord
107107
108108
SELECT VALUE c
109109
FROM root c
110-
ORDER BY RANK RRF(VectorDistance(c["Owned"]["Singles"], @inputVector, false, {'distanceFunction':'cosine', 'dataType':'float32'}), FullTextScore(c["Owned"]["AnotherDescription"], ["beaver","otter"]))
110+
ORDER BY RANK RRF(VectorDistance(c["Owned"]["Singles"], @inputVector, false, {'distanceFunction':'cosine', 'dataType':'float32'}), FullTextScore(c["Owned"]["AnotherDescription"], "beaver", "otter"))
111111
""");
112112
}
113113

0 commit comments

Comments
 (0)