添加 JavaScript 代码以使用 Cosmos DB

已完成

在本单元中,你将了解如何使用 SQL 关键字(如 LIKE、JOIN 和 WHERE)通过 Cosmos SDK 查询数据。

对容器执行查询操作

查询操作特定于容器。 由于对容器本身执行查询,因此不需要使用容器的正确名称,例如 products。 在 SDK 参考文档或门户中,你可能会看到容器名称(例如 rootc)来指示容器。

查询所有文档

若要在 Cosmos DB Core (SQL) 数据库的容器中查找文档,请对容器对象使用 SDK 查询方法以及查询规范。 查询规范需要 query 属性和可选的 parameters 属性。

属性 用途
query(必需) SQL 查询文本。 简单查询是 select * from products
parameters(可选) 查询中的变量替换。 名称对应于查询中使用的名称,值是实际替换。 最多提供 10 个参数。
const querySpecification = {
    query: `select * from products`,
    parameters: undefined
};

此查询返回容器中的所有文档。

在容器中使用 LIKE 按名称查询文档

若要优化搜索,但仍提供一些灵活性,请使用 LIKE 关键字允许文档属性上有文档的名称属性包含 Blue 值的任何匹配项。 名称可以以 Blue 开头、以 Blue 结尾或中间有 Blue,因为值用百分比符号 % 围起来。

// SQL Query specification
const querySpec = {
    // SQL query text using LIKE keyword and parameter
    query: `select * from products p where p.name LIKE @propertyValue`,
    // Optional SQL parameters, to be used in query
    parameters: [
        {
            // name of property to find in query text
            name: "@propertyValue",
            // value to insert in place of property
            value: `%Blue%`,
        }
    ]
};

使用 LIKE 关键字

对容器执行查询以提取文档。 查询的结果通过 fetchAll 提取,并在析构化属性 resources 中返回。

// Execute query
const { resources } = await container.items.query(querySpec).fetchAll();

它会循环访问整个集合,使用 for/of 循环。

let i = 0;

// Show results of query
for (const item of resources) {
    console.log(`${++i}: ${item.id}: ${item.name}, ${item.sku}`);
}

输出与下面类似:

1: 08225A9E-F2B3-4FA3-AB08-8C70ADD6C3C2: Touring-1000 Blue, 50, BK-T79U-50      
2: 2C981511-AC73-4A65-9DA3-A0577E386394: Touring-1000 Blue, 46, BK-T79U-46      
3: 44873725-7B3B-4B28-804D-963D2D62E761: Touring-1000 Blue, 60, BK-T79U-60      
4: 4E4B38CB-0D82-43E5-89AF-20270CD28A04: Touring-2000 Blue, 60, BK-T44U-60      
5: 5308BAE7-B0CB-4883-9A93-192CB10DC94F: Touring-3000 Blue, 44, BK-T18U-44 

在容器中使用 LIKE 按字符串属性查询文档

若要使查询更加灵活,请将其包装在采用文档属性的函数及其要查找的值中。

// Find all products that match a property with a value like `value`
async function executeSqlFind(property, value) {
  // Build query
  const querySpec = {
    query: `select * from products p where p.${property} LIKE @propertyValue`,
    parameters: [
      {
        name: "@propertyValue",
        value: `${value}`,
      },
    ],
  };

  // Show query
  console.log(querySpec);

  // Get results
  const { resources } = await container.items.query(querySpec).fetchAll();

  let i = 0;

  // Show results of query
  for (const item of resources) {
    console.log(`${++i}: ${item.id}: ${item.name}, ${item.sku}`);
  }
}

属性和值将传递到函数中,并用于字符串值的查询。

使用容器中的 JOIN 关键字查询文档并返回清单子属性

文档形状包括两个子属性、标记和清单。 若要访问这些子属性,请使用 JOIN 关键字。 以下 SQL 查询的格式仅用于可读性,无需与 Cosmos DB SDK 一起使用。

SELECT
    p.id, 
    p.name, 
    i.location, 
    i.inventory
FROM 
    products p 
JOIN 
    inventory i IN p.inventory 
WHERE 
    p.name LIKE '%Blue%'
AND 
    i.location='Dallas'

清单变量 i

  • 在 JOIN 子句中命名以访问子属性数据。
  • 在 WHERE 子句中使用以减少数据集。
  • 在 SELECT 子句中使用以返回清单属性。

若要查找特定位置中特定属性的所有清单,请使用以下函数。 它使用参数替换来提供文档的顶级属性和子属性值以匹配某个位置。

async function executeSqlInventory(propertyName, propertyValue, locationPropertyName, locationPropertyValue) {
  // Build query
  const querySpec = {
    query: `select p.id, p.name, i.location, i.inventory from products p JOIN i IN p.inventory where p.${propertyName} LIKE @propertyValue AND i.${locationPropertyName}=@locationPropertyValue`,

    parameters: [
      {
        name: "@propertyValue",
        value: `${propertyValue}`,
      },
      { 
        name: "@locationPropertyValue", 
        value: `${locationPropertyValue}` },
    ],
  };

  // Show query
  console.log(querySpec);

  // Get results
  const { resources } = await container.items.query(querySpec).fetchAll();

  let i = 0;

  // Show results of query
  console.log(`Looking for ${propertyName}=${propertyValue}, ${locationPropertyName}=${locationPropertyValue}`);
  for (const item of resources) {
    console.log(
      `${++i}: ${item.id}: '${item.name}': current inventory = ${
        item.inventory
      }`
    );
  }
}

此函数返回如下输出:

Looking for name=%Blue%, location=Dallas
1: 08225A9E-F2B3-4FA3-AB08-8C70ADD6C3C2: 'Touring-1000 Blue, 50': current inventory = 42
2: 2C981511-AC73-4A65-9DA3-A0577E386394: 'Touring-1000 Blue, 46': current inventory = 12
3: 44873725-7B3B-4B28-804D-963D2D62E761: 'Touring-1000 Blue, 60': current inventory = 83
4: 4E4B38CB-0D82-43E5-89AF-20270CD28A04: 'Touring-2000 Blue, 60': current inventory = 90
5: 5308BAE7-B0CB-4883-9A93-192CB10DC94F: 'Touring-3000 Blue, 44': current inventory = 97

用于插入或更新数据的更新插入

使用更新插入有助于确保在不存在数据时进行添加,并在数据存在时进行更新。 JavaScript SDK 返回 statusCode,表示已采取哪些操作:

更新插入 statusCode 含义
201 插入
200 更新

以下 JavaScript 使用单个函数,并使用 container.items().upsert()。

// Either insert or update item
async function upsert(item) {

  // Process request
  const result = await container.items.upsert(item);

  if(result.statusCode===201){
    console.log("Inserted data");
  } else if (result.statusCode===200){
    console.log("Updated data");
  } else {
    console.log(`unexpected statusCode ${result.statusCode}`);
  }
}