操作方法:查询状态

使用查询API查询状态存储

alpha

状态查询API目前处于alpha阶段。

使用状态查询 API,您可以检索、过滤和排序存储在状态存储组件中的键/值数据。 查询 API 不能替代完整的查询语言。

即使状态存储是键/值存储,value 也可能是具有自己的层次结构、键和值的 JSON 文档。 查询 API 允许您使用这些键和值来检索相应的文档。

查询状态

您可以通过 HTTP POST/PUT 或 gRPC 提交查询请求。 请求的正文是包含 3 个条目的 JSON 映射:

  • filter
  • sort
  • page

filter

filter 指定查询条件的形式,其中每个节点代表一元或多元操作。

支持以下操作:

运算符操作数说明
EQkey:valuekey == value
NEQkey:valuekey != value
GTkey:valuekey > value
GTEkey:valuekey >= value
LTkey:valuekey < value
LTEkey:valuekey <= value
INkey:[]valuekey == value[0] OR key == value[1] OR … OR key == value[n]
AND[]operationoperation[0] AND operation[1] AND … AND operation[n]
OR[]operationoperation[0] OR operation[1] OR … OR operation[n]

操作数中的key与JSONPath表示法类似。 键中的每个点表示一个嵌套的JSON结构。 例如,考虑这个结构:

  1. {
  2. "shape": {
  3. "name": "rectangle",
  4. "dimensions": {
  5. "height": 24,
  6. "width": 10
  7. },
  8. "color": {
  9. "name": "red",
  10. "code": "#FF0000"
  11. }
  12. }
  13. }

要比较颜色代码的值,键将是shape.color.code

如果省略filter部分,则查询将返回所有条目。

sort

sort 是一个有序数组,其中包含 key:order 对,其中:

  • key是状态存储中的键
  • order是一个可选字符串,表示排序顺序:
    • "ASC"表示升序
    • "DESC"用于降序排列 如果省略,则默认为升序。

page

page 包含 limittoken 参数。

  • limit设置页面大小。
  • token是组件返回的迭代令牌,用于后续查询。

在后台,此查询请求被转换为本机查询语言,并由状态存储组件执行。

示例数据和查询

让我们看一些真实例子,从简单到复杂。

作为数据集,考虑一个包含员工记录的集合,包含员工ID、组织、州和城市。 请注意,此数据集是一个键/值对数组,其中:

  • key 是唯一的 ID
  • value 是具有员工记录的 JSON 对象。

为了更好地说明功能,组织名称(org)和员工ID(id)作为嵌套的JSON人员对象。

首先,您需要创建 MongoDB 的实例,这是您的状态存储。

  1. docker run -d --rm -p 27017:27017 --name mongodb mongo:5

接下来,启动一个 Dapr 应用程序。 请参阅组件配置文件,它指示Dapr使用MongoDB作为其状态存储。

  1. dapr run --app-id demo --dapr-http-port 3500 --resources-path query-api-examples/components/mongodb

使用员工数据集填充状态存储,以便以后可以查询它。

  1. curl -X POST -H "Content-Type: application/json" -d @query-api-examples/dataset.json http://localhost:3500/v1.0/state/statestore

填充后,可以检查状态存储中的数据。 在下面的图像中,MongoDB UI的一部分显示员工记录。

Sample dataset

每个条目都有 _id 成员作为串联的对象键,value 包含 JSON 记录的成员。

查询 API 允许您从此 JSON 结构中选择记录。

现在,您可以运行示例查询。

示例 1

首先,找到加利福尼亚州的所有员工,并按其员工 ID 降序排序。

这是查询

  1. {
  2. "filter": {
  3. "EQ": { "state": "CA" }
  4. },
  5. "sort": [
  6. {
  7. "key": "person.id",
  8. "order": "DESC"
  9. }
  10. ]
  11. }

在 SQL 中,此查询的等效项是:

  1. SELECT * FROM c WHERE
  2. state = "CA"
  3. ORDER BY
  4. person.id DESC

使用以下命令执行查询:

  1. curl -s -X POST -H "Content-Type: application/json" -d @query-api-examples/query1.json http://localhost:3500/v1.0-alpha1/state/statestore/query | jq .
  1. Invoke-RestMethod -Method Post -ContentType 'application/json' -InFile query-api-examples/query1.json -Uri 'http://localhost:3500/v1.0-alpha1/state/statestore/query'

查询结果是按请求的顺序排列的匹配键/值对的数组:

  1. {
  2. "results": [
  3. {
  4. "key": "3",
  5. "data": {
  6. "person": {
  7. "org": "Finance",
  8. "id": 1071
  9. },
  10. "city": "Sacramento",
  11. "state": "CA"
  12. },
  13. "etag": "44723d41-deb1-4c23-940e-3e6896c3b6f7"
  14. },
  15. {
  16. "key": "7",
  17. "data": {
  18. "city": "San Francisco",
  19. "state": "CA",
  20. "person": {
  21. "id": 1015,
  22. "org": "Dev Ops"
  23. }
  24. },
  25. "etag": "0e69e69f-3dbc-423a-9db8-26767fcd2220"
  26. },
  27. {
  28. "key": "5",
  29. "data": {
  30. "state": "CA",
  31. "person": {
  32. "org": "Hardware",
  33. "id": 1007
  34. },
  35. "city": "Los Angeles"
  36. },
  37. "etag": "f87478fa-e5c5-4be0-afa5-f9f9d75713d8"
  38. },
  39. {
  40. "key": "9",
  41. "data": {
  42. "person": {
  43. "org": "Finance",
  44. "id": 1002
  45. },
  46. "city": "San Diego",
  47. "state": "CA"
  48. },
  49. "etag": "f5cf05cd-fb43-4154-a2ec-445c66d5f2f8"
  50. }
  51. ]
  52. }

示例 2

现在,让我们查找”Dev Ops”和”Hardware”组织中的所有员工。

这是查询

  1. {
  2. "filter": {
  3. "IN": { "person.org": [ "Dev Ops", "Hardware" ] }
  4. }
  5. }

在 SQL 中,此查询的等效项是:

  1. SELECT * FROM c WHERE
  2. person.org IN ("Dev Ops", "Hardware")

使用以下命令执行查询:

  1. curl -s -X POST -H "Content-Type: application/json" -d @query-api-examples/query2.json http://localhost:3500/v1.0-alpha1/state/statestore/query | jq .
  1. Invoke-RestMethod -Method Post -ContentType 'application/json' -InFile query-api-examples/query2.json -Uri 'http://localhost:3500/v1.0-alpha1/state/statestore/query'

与前面的示例类似,结果是一个匹配键/值对的数组。

示例 3

在这个示例中,查找:

  • “Dev Ops” 部门的所有员工。
  • 来自“Finance”部门的员工居住在华盛顿州和加利福尼亚州。

此外,让我们先按州(按字母降序)对结果进行排序,然后按员工 ID(升序)对结果进行排序。 另外,让我们一次最多处理 3 条记录。

这是查询

  1. {
  2. "filter": {
  3. "OR": [
  4. {
  5. "EQ": { "person.org": "Dev Ops" }
  6. },
  7. {
  8. "AND": [
  9. {
  10. "EQ": { "person.org": "Finance" }
  11. },
  12. {
  13. "IN": { "state": [ "CA", "WA" ] }
  14. }
  15. ]
  16. }
  17. ]
  18. },
  19. "sort": [
  20. {
  21. "key": "state",
  22. "order": "DESC"
  23. },
  24. {
  25. "key": "person.id"
  26. }
  27. ],
  28. "page": {
  29. "limit": 3
  30. }
  31. }

在 SQL 中,此查询的等效项是:

  1. SELECT * FROM c WHERE
  2. person.org = "Dev Ops" OR
  3. (person.org = "Finance" AND state IN ("CA", "WA"))
  4. ORDER BY
  5. state DESC,
  6. person.id ASC
  7. LIMIT 3

使用以下命令执行查询:

  1. curl -s -X POST -H "Content-Type: application/json" -d @query-api-examples/query3.json http://localhost:3500/v1.0-alpha1/state/statestore/query | jq .
  1. Invoke-RestMethod -Method Post -ContentType 'application/json' -InFile query-api-examples/query3.json -Uri 'http://localhost:3500/v1.0-alpha1/state/statestore/query'

成功执行后,状态存储将返回一个 JSON 对象,其中包含匹配记录列表和分页标记:

  1. {
  2. "results": [
  3. {
  4. "key": "1",
  5. "data": {
  6. "person": {
  7. "org": "Dev Ops",
  8. "id": 1036
  9. },
  10. "city": "Seattle",
  11. "state": "WA"
  12. },
  13. "etag": "6f54ad94-dfb9-46f0-a371-e42d550adb7d"
  14. },
  15. {
  16. "key": "4",
  17. "data": {
  18. "person": {
  19. "org": "Dev Ops",
  20. "id": 1042
  21. },
  22. "city": "Spokane",
  23. "state": "WA"
  24. },
  25. "etag": "7415707b-82ce-44d0-bf15-6dc6305af3b1"
  26. },
  27. {
  28. "key": "10",
  29. "data": {
  30. "person": {
  31. "org": "Dev Ops",
  32. "id": 1054
  33. },
  34. "city": "New York",
  35. "state": "NY"
  36. },
  37. "etag": "26bbba88-9461-48d1-8a35-db07c374e5aa"
  38. }
  39. ],
  40. "token": "3"
  41. }

分页标记在subsequent query中”按原样”使用,以获取下一批记录:

  1. {
  2. "filter": {
  3. "OR": [
  4. {
  5. "EQ": { "person.org": "Dev Ops" }
  6. },
  7. {
  8. "AND": [
  9. {
  10. "EQ": { "person.org": "Finance" }
  11. },
  12. {
  13. "IN": { "state": [ "CA", "WA" ] }
  14. }
  15. ]
  16. }
  17. ]
  18. },
  19. "sort": [
  20. {
  21. "key": "state",
  22. "order": "DESC"
  23. },
  24. {
  25. "key": "person.id"
  26. }
  27. ],
  28. "page": {
  29. "limit": 3,
  30. "token": "3"
  31. }
  32. }
  1. curl -s -X POST -H "Content-Type: application/json" -d @query-api-examples/query3-token.json http://localhost:3500/v1.0-alpha1/state/statestore/query | jq .
  1. Invoke-RestMethod -Method Post -ContentType 'application/json' -InFile query-api-examples/query3-token.json -Uri 'http://localhost:3500/v1.0-alpha1/state/statestore/query'

此查询的结果是:

  1. {
  2. "results": [
  3. {
  4. "key": "9",
  5. "data": {
  6. "person": {
  7. "org": "Finance",
  8. "id": 1002
  9. },
  10. "city": "San Diego",
  11. "state": "CA"
  12. },
  13. "etag": "f5cf05cd-fb43-4154-a2ec-445c66d5f2f8"
  14. },
  15. {
  16. "key": "7",
  17. "data": {
  18. "city": "San Francisco",
  19. "state": "CA",
  20. "person": {
  21. "id": 1015,
  22. "org": "Dev Ops"
  23. }
  24. },
  25. "etag": "0e69e69f-3dbc-423a-9db8-26767fcd2220"
  26. },
  27. {
  28. "key": "3",
  29. "data": {
  30. "person": {
  31. "org": "Finance",
  32. "id": 1071
  33. },
  34. "city": "Sacramento",
  35. "state": "CA"
  36. },
  37. "etag": "44723d41-deb1-4c23-940e-3e6896c3b6f7"
  38. }
  39. ],
  40. "token": "6"
  41. }

这样,您可以更新查询中的分页令牌并循环访问结果,直到不再返回任何记录。

局限性

状态查询 API 具有以下限制:

  • 要查询存储在状态存储中的 actor 状态,您需要对特定数据库使用查询 API。 参见查询 actor 状态
  • 该 API 不适用于 Dapr 加密状态存储功能。 由于加密是由 Dapr 运行时完成并存储为加密数据,因此这有效地阻止了服务器端查询。

您可以在相关链接部分找到更多信息。

相关链接