使用 .NET 查询适用于 NoSQL 的 Azure Cosmos DB 中的项

适用范围: NoSQL

Azure Cosmos DB 中的项表示存储在容器中的实体。 在 API for NoSQL 中,项由具有唯一标识符的 JSON 格式数据组成。 使用 API for NoSQL 发出查询时,结果将作为 JSON 文档的 JSON 数组返回。

使用 SQL 查询项

适用于 NoSQL 的 Azure Cosmos DB 支持使用结构化查询语言 (SQL) 对容器中的项执行查询。 像 SELECT * FROM products 这样的简单 SQL 查询将返回容器中的所有项和属性。 查询可能更复杂,包括特定的字段投影、筛选器和其他常见的 SQL 子句:

SELECT 
    p.name, 
    p.description AS copy
FROM 
    products p 
WHERE 
    p.price > 500

若要详细了解适用于 NoSQL 的 Azure Cosmos DB 的 SQL 语法,请参阅 SQL 查询入门

查询项

注意

本文中的示例假定你已定义一个 C# 类型来表示名为 Product 的数据:

// C# record type for items in the container
public record Product(
    string id,
    string category,
    string name,
    int quantity,
    bool sale
);

要查询容器中的项,请调用以下任一方法:

使用 SQL 查询异步查询项

此示例使用简单的字符串生成一个 SQL 查询,检索源迭代器,然后使用嵌套循环循环访问结果。 外部 while 循环将循环访问结果页面,而内部 foreach 循环将循环访问页面内的结果。

// Query multiple items from container
using FeedIterator<Product> feed = container.GetItemQueryIterator<Product>(
    queryText: "SELECT * FROM products"
);

// Iterate query result pages
while (feed.HasMoreResults)
{
    FeedResponse<Product> response = await feed.ReadNextAsync();

    // Iterate query results
    foreach (Product item in response)
    {
        Console.WriteLine($"Found item:\t{item.name}");
    }
}

Container.GetItemQueryIterator<> 方法返回一个用于循环访问多页结果的 FeedIterator<>HasMoreResults 属性指示是否还有更多结果页面。 ReadNextAsync 方法以可枚举的形式获取下一页结果,然后在循环中使用它来循环访问结果。

或者,使用 QueryDefinition 构建带有参数化输入的 SQL 查询:

// Build query definition
var parameterizedQuery = new QueryDefinition(
    query: "SELECT * FROM products p WHERE p.category = @partitionKey"
)
    .WithParameter("@partitionKey", "gear-surf-surfboards");

// Query multiple items from container
using FeedIterator<Product> filteredFeed = container.GetItemQueryIterator<Product>(
    queryDefinition: parameterizedQuery
);

// Iterate query result pages
while (filteredFeed.HasMoreResults)
{
    FeedResponse<Product> response = await filteredFeed.ReadNextAsync();

    // Iterate query results
    foreach (Product item in response)
    {
        Console.WriteLine($"Found item:\t{item.name}");
    }
}

提示

参数化输入值有助于防止许多常见的 SQL 查询注入攻击。

使用 LINQ 异步查询项

在此示例中,IQueryable<> 对象用于构造语言集成查询 (LINQ)。 然后,使用源迭代器对结果进行循环访问。

// Get LINQ IQueryable object
IOrderedQueryable<Product> queryable = container.GetItemLinqQueryable<Product>();

// Construct LINQ query
var matches = queryable
    .Where(p => p.category == "gear-surf-surfboards")
    .Where(p => p.sale == false)
    .Where(p => p.quantity > 10);

// Convert to feed iterator
using FeedIterator<Product> linqFeed = matches.ToFeedIterator();

// Iterate query result pages
while (linqFeed.HasMoreResults)
{
    FeedResponse<Product> response = await linqFeed.ReadNextAsync();

    // Iterate query results
    foreach (Product item in response)
    {
        Console.WriteLine($"Matched item:\t{item.name}");
    }
}

Container.GetItemLinqQueryable<> 方法构造一个 IQueryable 来构建 LINQ 查询。 然后使用 ToFeedIterator<> 方法将 LINQ 查询表达式转换为 FeedIterator<>

提示

虽然可以循环访问 IQueryable<>,但此操作是同步的。 使用 ToFeedIterator<> 方法异步收集结果。

后续步骤

现在你已经查询了多个项,请尝试 API for NoSQL 的任一端到端教程。