服务器上的 dotnet core azure documentdb linq lambda 查询不是 运行 查询

dotnet core azure documentdb linq lambda query not running query on server

我正在 运行正在使用 dotnet 核心并访问 documentdb。

当我尝试 运行 使用 linq where 子句的查询时 returns 但是它需要很长时间并且似乎没有在服务器上进行过滤。我能够通过使用 SqlQuerySpec 运行 查询来解决这个问题,现在它似乎 运行 服务器上的查询条件。

这是已知问题还是我遗漏了什么?

不行的那个:

var query = _client.CreateDocumentQuery<T>(documentCollection.DocumentsLink).Where(criteria);    
return query.ToList();

标准的类型是

Func<T, bool> criteria

有效的那个:

var documentQuery = _client.CreateDocumentQuery<T>(UriFactory.CreateDocumentCollectionUri(_databaseName, collectionName), query).AsDocumentQuery();
List<T> results = new List<T>();
while (documentQuery.HasMoreResults)
{
results.AddRange(await documentQuery.ExecuteNextAsync<T>());
}
return results;

查询的类型是

SqlQuerySpec query

在 dotnet core 的 documentdb sdk 与标准 .NET 包的实现中,这是一个落后的功能吗?

When I try to run a query using a linq where clause it returns but it takes a long time and doesn't seem to filter on the server.

如果我们在 运行 var query = _client.CreateDocumentQuery<T>(documentCollection.DocumentsLink).Where(criteria); 时捕获请求,我们可以找到它 performs a GET on the documents resource of a particular collection

GET https://{databaseaccount}.documents.azure.com/dbs/{db-id}/colls/{coll-id}/docs获取集合下的文件列表,其实并不query and filter on DocumentDB server.

Where method用于根据谓词过滤一系列值,这发生在客户端(不将搜索条件传递给DocumentDB服务器)。

问题是您使用 Func<T, bool> 作为条件。您使用的是 IEnumerable。按照设计 IEnumerable 将进行内存中过滤(客户端)。

CreateDocumentQuery.Where() 实际上 returns 一个 IQueryable。您需要将条件类型更改为 Expression<Func<T, bool>>,因为这是 CreateDocumentQuery.

所期望的

当您使用 Expression 时,您的 LINQ 表达式将转换为特定于数据库的 SQL 查询,并将在服务器上执行。

Uri documentCollectionUri = UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId);
var query = client.CreateDocumentQuery<T>(documentCollectionUri)
                  .Where(predicate)
                  .AsDocumentQuery();
List<T> results = new List<T>();
while (documentQuery.HasMoreResults)
{
    results.AddRange(await documentQuery.ExecuteNextAsync<T>());
}

return results;

其中 predicateExpression<Func<T, bool>>

要记住一件重要的事情:您只能使用那些在 DocumentDb 的 SQL 语言中具有等效功能的 LINQ 扩展。例如,可以使用 Take() 但不能使用 Skip(),不能在特定的嵌套字段上使用 Array contains 等