-
Notifications
You must be signed in to change notification settings - Fork 847
Description
Please provide a succinct description of the issue.
Array indexing within a an Expression<'A -> 'B> is mapped to a GetArray call (in line with how it works for Expr ?) rather than a get_Item invocation.
There does not appear to be a clean workaround aside from using a list or a ResizeArray instead (as the get_Item mechanism is not exposed).
Provide the steps required to reproduce the problem:
#r "nuget: Microsoft.Azure.Cosmos, 3.38.1"
open Microsoft.Azure.Cosmos
open Microsoft.Azure.Cosmos.Linq
open System.Linq
type Doc =
{ p: string
u: Unfold[] }
and Unfold =
{ c: string }
let client = new CosmosClient(conns)
let c = client.GetDatabase("name").GetContainer("container")
let q = c.GetItemLinqQueryable<Doc>(allowSynchronousQueryExecution = true)
let i = q.Where(fun x -> x.p = "Snapshotted" )
.OrderBy(fun d -> d.u[0].c)
.Select(fun x -> x.u.[0].c)
printfn "%O" i.Expression
printfn "%s" (i.ToQueryDefinition().QueryText)
for x in i.Take(2) do
printfn $"%A{x}"
Expected behavior
Should generate System.Linq.Expression.Expression of the form:
dbs/name/colls/container.Where(x => (x.p == "Snapshotted")).OrderBy(d => d.u.get_Item(0).c).Select(x => x.u.get_Item(0).c)
Which yields correct SQL:
SELECT VALUE root["u"][0]["c"] FROM root WHERE (root["p"] = "Snapshotted") ORDER BY root["u"][0]["c"] ASC
Actual behavior
dbs/name/colls/container.Where(x => (x.p == "Snapshotted")).OrderBy(d => GetArray(d.u, 0).c).Select(x => GetArray(x.u, 0).c)
Microsoft.Azure.Cosmos.Linq.DocumentQueryException: Method 'GetArray' is not supported.
NOTE other approaches such as using query { run aground for the same fundamental reason (mapping to a surprising F#-specific expression tree)
Known workarounds
- Switch the
u: Unfold[]to be aResizeArray(or even alist!)
Related information
- Env: Rider F# interactive 2023.3.2, SDK 8.0.101 on MacOS
- Cosmos SDK has details of the supported expression tree navigation patterns near top of the relevant docs section
**C# equivalent (for completeness, yields same get_Item invocation)
using Microsoft.Azure.Cosmos;
using Microsoft.Azure.Cosmos.Linq;
var client = new CosmosClient(conns);
var c = client.GetDatabase("database").GetContainer("container");
var q = c.GetItemLinqQueryable<Doc>(allowSynchronousQueryExecution: true);
var i = q.Select(d => d.u[0].c);
Console.WriteLine(i.Expression);
Console.WriteLine(i.ToQueryDefinition().QueryText);
Console.WriteLine(i);
foreach (var x in i.Take(2))
Console.WriteLine(x);
record Doc(String p, Unfold[] u);
record Unfold(String c, int i, Index d);
record Index(string k, int v);
Metadata
Metadata
Assignees
Labels
Type
Projects
Status