Skip to content

Commit 00ed3ca

Browse files
Merge branch 'master' into users/aditya/FTLanguageOptional
2 parents 30e0996 + 5838871 commit 00ed3ca

File tree

18 files changed

+4157
-115
lines changed

18 files changed

+4157
-115
lines changed

Directory.Build.props

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
22
<PropertyGroup>
3-
<ClientOfficialVersion>3.49.0</ClientOfficialVersion>
3+
<ClientOfficialVersion>3.49.1</ClientOfficialVersion>
44
<ClientPreviewVersion>3.50.0</ClientPreviewVersion>
5-
<ClientPreviewSuffixVersion>preview.0</ClientPreviewSuffixVersion>
5+
<ClientPreviewSuffixVersion>preview.1</ClientPreviewSuffixVersion>
66
<DirectVersion>3.38.0</DirectVersion>
77
<FaultInjectionVersion>1.0.0</FaultInjectionVersion>
88
<FaultInjectionSuffixVersion>beta.0</FaultInjectionSuffixVersion>

Microsoft.Azure.Cosmos/contracts/API_3.49.1.txt

Lines changed: 1705 additions & 0 deletions
Large diffs are not rendered by default.

Microsoft.Azure.Cosmos/contracts/API_3.50.0-preview.1.txt

Lines changed: 1874 additions & 0 deletions
Large diffs are not rendered by default.

Microsoft.Azure.Cosmos/src/Linq/BuiltinFunctions/OtherBuiltinSystemFunctions.cs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public RRFVisit()
2121
true,
2222
new List<Type[]>()
2323
{
24-
new Type[]{typeof(Func<object, object>[])}
24+
new Type[]{typeof(double[])}
2525
})
2626
{
2727
}
@@ -36,7 +36,27 @@ protected override SqlScalarExpression VisitImplicit(MethodCallExpression method
3636
List<SqlScalarExpression> arguments = new List<SqlScalarExpression>();
3737
foreach (Expression argument in functionListExpression)
3838
{
39-
arguments.Add(ExpressionToSql.VisitScalarExpression(argument, context));
39+
if (!(argument is MethodCallExpression functionCallExpression))
40+
{
41+
throw new ArgumentException(
42+
string.Format(
43+
CultureInfo.CurrentCulture,
44+
"Expressions of type {0} is not supported as an argument to CosmosLinqExtensions.RRF. Supported expressions are method calls to {1}.",
45+
argument.Type,
46+
nameof(CosmosLinqExtensions.FullTextScore)));
47+
}
48+
49+
if (functionCallExpression.Method.Name != nameof(CosmosLinqExtensions.FullTextScore))
50+
{
51+
throw new ArgumentException(
52+
string.Format(
53+
CultureInfo.CurrentCulture,
54+
"Method {0} is not supported as an argument to CosmosLinqExtensions.RRF. Supported methods are {1}.",
55+
functionCallExpression.Method.Name,
56+
nameof(CosmosLinqExtensions.FullTextScore)));
57+
}
58+
59+
arguments.Add(ExpressionToSql.VisitNonSubqueryScalarExpression(argument, context));
4060
}
4161

4262
return SqlFunctionCallScalarExpression.CreateBuiltin(SqlFunctionCallScalarExpression.Names.RRF, arguments.ToImmutableArray());

Microsoft.Azure.Cosmos/src/Linq/CosmosLinqExtensions.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ public static bool FullTextContainsAny(this object obj, params string[] searches
318318
/// ]]>
319319
/// </code>
320320
/// </example>
321-
public static Func<TSource, object> FullTextScore<TSource>(this TSource obj, params string[] terms)
321+
public static double FullTextScore<TSource>(this TSource obj, params string[] terms)
322322
{
323323
throw new NotImplementedException(ClientResources.ExtensionMethodNotImplemented);
324324
}
@@ -339,7 +339,7 @@ public static Func<TSource, object> FullTextScore<TSource>(this TSource obj, par
339339
/// ]]>
340340
/// </code>
341341
/// </example>
342-
public static IOrderedQueryable<TSource> OrderByRank<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, object>> scoreFunction)
342+
public static IOrderedQueryable<TSource> OrderByRank<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> scoreFunction)
343343
{
344344
if (!(source is CosmosLinqQuery<TSource>))
345345
{
@@ -349,7 +349,7 @@ public static IOrderedQueryable<TSource> OrderByRank<TSource>(this IQueryable<TS
349349
return (IOrderedQueryable<TSource>)source.Provider.CreateQuery<TSource>(
350350
Expression.Call(
351351
null,
352-
typeof(CosmosLinqExtensions).GetMethod("OrderByRank").MakeGenericMethod(typeof(TSource)),
352+
typeof(CosmosLinqExtensions).GetMethod("OrderByRank").MakeGenericMethod(typeof(TSource), typeof(TKey)),
353353
source.Expression,
354354
Expression.Quote(scoreFunction)));
355355
}
@@ -360,7 +360,7 @@ public static IOrderedQueryable<TSource> OrderByRank<TSource>(this IQueryable<TS
360360
/// This method is to be used in LINQ expressions only and will be evaluated on server.
361361
/// There's no implementation provided in the client library.
362362
/// </summary>
363-
/// <param name="scoringFunctions">the scoring functions to combine.</param>
363+
/// <param name="scoringFunctions">the scoring functions to combine. Valid functions are FullTextScore and VectorDistance</param>
364364
/// <returns>Returns the the combined scores of the scoring functions.</returns>
365365
/// <example>
366366
/// <code>
@@ -369,7 +369,7 @@ public static IOrderedQueryable<TSource> OrderByRank<TSource>(this IQueryable<TS
369369
/// ]]>
370370
/// </code>
371371
/// </example>
372-
public static Func<TSource, object> RRF<TSource>(params Func<TSource, object>[] scoringFunctions)
372+
public static double RRF(params double[] scoringFunctions)
373373
{
374374
// The reason for not defining "this" keyword is because this causes undesirable serialization when call Expression.ToString() on this method
375375
throw new NotImplementedException(ClientResources.ExtensionMethodNotImplemented);

Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CrossPartition/HybridSearch/HybridSearchCrossPartitionQueryPipelineStage.cs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -404,12 +404,10 @@ private static IReadOnlyList<ComponentWeight> ExtractComponentWeights(HybridSear
404404
for (int index = 0; index < hybridSearchQueryInfo.ComponentQueryInfos.Count; ++index)
405405
{
406406
QueryInfo queryInfo = hybridSearchQueryInfo.ComponentQueryInfos[index];
407-
Debug.Assert(queryInfo.HasOrderBy, "The component query should have an order by");
408-
Debug.Assert(queryInfo.HasNonStreamingOrderBy, "The component query is a non streaming order by");
409-
Debug.Assert(queryInfo.OrderBy.Count == 1, "The component query should have exactly one order by expression");
407+
SortOrder sortOrder = queryInfo.HasOrderBy ? queryInfo.OrderBy[0] : SortOrder.Descending;
410408

411409
double componentWeight = useDefaultComponentWeight ? 1.0 : hybridSearchQueryInfo.ComponentWeights[index];
412-
result.Add(new ComponentWeight(componentWeight, queryInfo.OrderBy[0]));
410+
result.Add(new ComponentWeight(componentWeight, sortOrder));
413411
}
414412

415413
return result;
@@ -635,14 +633,19 @@ private static void ComputeRrfScores(
635633

636634
private static QueryInfo RewriteOrderByQueryInfo(QueryInfo queryInfo, GlobalFullTextSearchStatistics statistics, int componentCount)
637635
{
638-
Debug.Assert(queryInfo.HasOrderBy, "The component query should have an order by");
639-
Debug.Assert(queryInfo.HasNonStreamingOrderBy, "The component query is a non streaming order by");
636+
IReadOnlyList<string> rewrittenOrderByExpressions = queryInfo.OrderByExpressions;
640637

641-
List<string> rewrittenOrderByExpressions = new List<string>(queryInfo.OrderByExpressions.Count);
642-
foreach (string orderByExpression in queryInfo.OrderByExpressions)
638+
if (queryInfo.HasOrderBy)
643639
{
644-
string rewrittenOrderByExpression = FormatComponentQueryTextWorkaround(orderByExpression, statistics, componentCount);
645-
rewrittenOrderByExpressions.Add(rewrittenOrderByExpression);
640+
Debug.Assert(queryInfo.HasNonStreamingOrderBy, "The component query is a non streaming order by");
641+
List<string> orderByExpressions = new List<string>(queryInfo.OrderByExpressions.Count);
642+
foreach (string orderByExpression in queryInfo.OrderByExpressions)
643+
{
644+
string rewrittenOrderByExpression = FormatComponentQueryTextWorkaround(orderByExpression, statistics, componentCount);
645+
orderByExpressions.Add(rewrittenOrderByExpression);
646+
}
647+
648+
rewrittenOrderByExpressions = orderByExpressions;
646649
}
647650

648651
string rewrittenQuery = FormatComponentQueryTextWorkaround(queryInfo.RewrittenQuery, statistics, componentCount);
@@ -777,18 +780,15 @@ private static string FormatComponentQueryTextWorkaround(string format, GlobalFu
777780

778781
private class ComponentWeight
779782
{
780-
public SortOrder SortOrder { get; }
781-
782783
public double Weight { get; }
783784

784785
public Comparison<double> Comparison { get; }
785786

786787
public ComponentWeight(double weight, SortOrder sortOrder)
787788
{
788789
this.Weight = weight;
789-
this.SortOrder = sortOrder;
790790

791-
int comparisonFactor = (this.SortOrder == SortOrder.Ascending) ? 1 : -1;
791+
int comparisonFactor = (sortOrder == SortOrder.Ascending) ? 1 : -1;
792792
this.Comparison = (x, y) => comparisonFactor * x.CompareTo(y);
793793
}
794794
}

Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CrossPartition/HybridSearch/HybridSearchQueryResult.cs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,22 +49,33 @@ public static HybridSearchQueryResult Create(CosmosElement document)
4949
throw new ArgumentException($"{FieldNames.Rid} must exist.");
5050
}
5151

52-
if (!cosmosObject.TryGetValue(FieldNames.Payload, out CosmosObject outerPayload))
53-
{
54-
throw new ArgumentException($"{FieldNames.Payload} must exist.");
55-
}
52+
bool outerPayloadExists = cosmosObject.TryGetValue(FieldNames.Payload, out CosmosObject outerPayload);
5653

57-
if (!outerPayload.TryGetValue(FieldNames.Payload, out CosmosElement innerPayload))
54+
HybridSearchQueryResult result;
55+
if (outerPayloadExists && outerPayload.TryGetValue(FieldNames.ComponentScores, out CosmosArray componentScores))
5856
{
59-
innerPayload = CosmosUndefined.Create();
60-
}
57+
// Using the older format where the payload is nested.
58+
if (!outerPayload.TryGetValue(FieldNames.Payload, out CosmosElement innerPayload))
59+
{
60+
innerPayload = CosmosUndefined.Create();
61+
}
6162

62-
if (!outerPayload.TryGetValue(FieldNames.ComponentScores, out CosmosArray componentScores))
63+
result = new HybridSearchQueryResult(rid, componentScores, innerPayload);
64+
}
65+
else
6366
{
64-
throw new ArgumentException($"{FieldNames.ComponentScores} must exist.");
67+
// Using the newer format where the payload is not nested.
68+
if (!cosmosObject.TryGetValue(FieldNames.ComponentScores, out componentScores))
69+
{
70+
throw new ArgumentException($"{FieldNames.ComponentScores} must exist.");
71+
}
72+
73+
CosmosElement payload = outerPayloadExists ? outerPayload : CosmosUndefined.Create();
74+
75+
result = new HybridSearchQueryResult(rid, componentScores, payload);
6576
}
6677

67-
return new HybridSearchQueryResult(rid, componentScores, innerPayload);
78+
return result;
6879
}
6980

7081
private static class FieldNames

Microsoft.Azure.Cosmos/src/RequestOptions/QueryRequestOptions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ public ConsistencyLevel? ConsistencyLevel
208208

209209
internal FeedRange FeedRange { get; set; }
210210

211-
internal bool IsHybridSearchQueryPlanOptimizationDisabled { get; set; } = ConfigurationManager.IsHybridSearchQueryPlanOptimizationDisabled(defaultValue: false);
211+
internal bool IsHybridSearchQueryPlanOptimizationDisabled { get; set; } = ConfigurationManager.IsHybridSearchQueryPlanOptimizationDisabled(defaultValue: true);
212212

213213
// This is a temporary flag to enable the distributed query gateway mode.
214214
// This flag will be removed once we have a way for the client to determine

Microsoft.Azure.Cosmos/src/Resource/Settings/ContainerProperties.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,12 @@ public GeospatialConfig GeospatialConfig
421421

422422
/// <summary>
423423
/// JSON path used for containers partitioning
424+
///
425+
/// For hierarchical partition keys, please use <see cref="ContainerProperties.PartitionKeyPaths"/>
424426
/// </summary>
427+
/// <remarks>
428+
/// Throws NotImplementedException for hierarchical partition keys
429+
/// </remarks>
425430
[JsonIgnore]
426431
public string PartitionKeyPath
427432
{

Microsoft.Azure.Cosmos/src/Routing/LocationCache.cs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -689,26 +689,26 @@ private void UpdateLocationCache(
689689
nextLocationInfo.AvailableWriteLocationByEndpoint = availableWriteLocationsByEndpoint;
690690
}
691691

692-
if (thinClientReadLocations != null)
692+
if (thinClientReadLocations != null && thinClientReadLocations.Count() > 0)
693693
{
694694
nextLocationInfo.ThinClientReadEndpointByLocation = this.GetEndpointByLocation(
695695
thinClientReadLocations,
696-
out ReadOnlyCollection<string> tcreadLocations,
697-
out ReadOnlyDictionary<Uri, string> tcReadLocByEndpoint);
696+
out ReadOnlyCollection<string> thinClientAvailableReadLocations,
697+
out ReadOnlyDictionary<Uri, string> thinClientAvailableReadLocationsByEndpoint);
698698

699-
nextLocationInfo.ThinClientReadLocations = tcreadLocations;
700-
nextLocationInfo.ThinClientReadLocationByEndpoint = tcReadLocByEndpoint;
699+
nextLocationInfo.ThinClientReadLocations = thinClientAvailableReadLocations;
700+
nextLocationInfo.ThinClientReadLocationByEndpoint = thinClientAvailableReadLocationsByEndpoint;
701701
}
702702

703-
if (thinClientWriteLocations != null)
703+
if (thinClientWriteLocations != null && thinClientWriteLocations.Count() > 0)
704704
{
705705
nextLocationInfo.ThinClientWriteEndpointByLocation = this.GetEndpointByLocation(
706706
thinClientWriteLocations,
707-
out ReadOnlyCollection<string> tcwriteLocations,
708-
out ReadOnlyDictionary<Uri, string> tcWriteLocByEndpoint);
707+
out ReadOnlyCollection<string> thinClientAvailableWriteLocations,
708+
out ReadOnlyDictionary<Uri, string> thinClientAvailableWriteLocationsByEndpoint);
709709

710-
nextLocationInfo.ThinClientWriteLocations = tcwriteLocations;
711-
nextLocationInfo.ThinClientWriteLocationByEndpoint = tcWriteLocByEndpoint;
710+
nextLocationInfo.ThinClientWriteLocations = thinClientAvailableWriteLocations;
711+
nextLocationInfo.ThinClientWriteLocationByEndpoint = thinClientAvailableWriteLocationsByEndpoint;
712712
}
713713

714714
nextLocationInfo.WriteEndpoints = this.GetPreferredAvailableEndpoints(
@@ -725,18 +725,18 @@ private void UpdateLocationCache(
725725

726726
nextLocationInfo.EffectivePreferredLocations = nextLocationInfo.PreferredLocations;
727727

728+
nextLocationInfo.ThinClientWriteEndpoints = this.GetPreferredAvailableEndpoints(
729+
endpointsByLocation: nextLocationInfo.ThinClientWriteEndpointByLocation,
730+
orderedLocations: nextLocationInfo.ThinClientWriteLocations,
731+
expectedAvailableOperation: OperationType.Write,
732+
fallbackEndpoint: this.defaultEndpoint);
733+
728734
nextLocationInfo.ThinClientReadEndpoints = this.GetPreferredAvailableEndpoints(
729735
endpointsByLocation: nextLocationInfo.ThinClientReadEndpointByLocation,
730736
orderedLocations: nextLocationInfo.ThinClientReadLocations,
731737
expectedAvailableOperation: OperationType.Read,
732-
fallbackEndpoint: this.defaultEndpoint);
738+
fallbackEndpoint: nextLocationInfo.ThinClientWriteEndpoints[0]);
733739

734-
nextLocationInfo.ThinClientWriteEndpoints = this.GetPreferredAvailableEndpoints(
735-
endpointsByLocation: nextLocationInfo.ThinClientWriteEndpointByLocation,
736-
orderedLocations: nextLocationInfo.ThinClientWriteLocations,
737-
expectedAvailableOperation: OperationType.Write,
738-
fallbackEndpoint: this.defaultEndpoint);
739-
740740
if (nextLocationInfo.PreferredLocations == null || nextLocationInfo.PreferredLocations.Count == 0)
741741
{
742742
if (!nextLocationInfo.AvailableReadLocationByEndpoint.TryGetValue(this.defaultEndpoint, out string regionForDefaultEndpoint))

0 commit comments

Comments
 (0)