【问题标题】:Azure CosmosDB nested WHERE queryAzure CosmosDB 嵌套 WHERE 查询
【发布时间】:2018-12-09 08:27:23
【问题描述】:

我正在尝试在 CosmosDB 中实现以下查询:

SELECT * FROM c
WHERE c.timestamp = (SELECT VALUE MAX(c.timestamp) FROM c )

但是它似乎并没有首先调用子查询并返回所有行。

这可能吗?

【问题讨论】:

  • 这个查询运行起来会非常昂贵。你想做什么?获取最新项目?您查看过更改提要吗?
  • @ChrisAnderson-MSFT 我实际上只是在测试这个,他报告的行为是真实的。查询运行良好,但您获得了所有记录,而不是与嵌套查询匹配的记录。
  • 是的,我正在循环查询人员来回答为什么这不仅会失败。它不应该工作。 :) 但它仍然是一个糟糕的设计模式,所以我可以先尝试帮助解决这个问题。 :)
  • @ChrisAnderson-MSFT - 除了不支持嵌套查询之外,为什么这样的查询会很昂贵?如果时间戳被索引,那么 MAX(timestamp) 会不会相当有效,因为它是服务端聚合?
  • 跨分区聚合需要访问每个分区,获取其最大值,然后找到客户端的最大值。所以有很多要求。 Krishnan 在下面有一些很好的建议。我仍然建议查看更改提要以查找最新项目。非常划算。

标签: azure-cosmosdb


【解决方案1】:

我来自 CosmosDB 工程团队。

CosmosDB 查询仅支持相关子查询,因此子查询只能引用父集合中的项目。例如,您可以对文档中的嵌套属性使用聚合,如下所示:

SELECT TOP 1000 
    c.id, 
    MaxNutritionValue,
    MinNutritionValue,
    AvgNutritionValue
FROM c
JOIN (SELECT VALUE Max(n.nutritionValue) FROM n IN c.nutrients) MaxNutritionValue
JOIN (SELECT VALUE Min(n.nutritionValue) FROM n IN c.nutrients) MinNutritionValue
JOIN (SELECT VALUE Avg(n.nutritionValue) FROM n IN c.nutrients) AvgNutritionValue

假设文档结构如下:

{
     "id":"someId",
     "nutrients":[
            { 
               "item": "pizza",
               "nutritionValue": 20 
            },
            { 
               "item": "burger",
               "nutritionValue": 30 
            }
     ] 
}

要实现你想要的,你可以这样做:

SELECT TOP 1 * FROM c ORDER BY c.timestamp DESC 

虽然不适用于所有聚合,但此方法可以帮助处理 Max 或 Min。

【讨论】:

  • 嗨 Krishnan,只是为了确保我理解你所说的。如果我有一个名为 Table1 的容器,那么我不能对其执行子查询来选择 CosmosDB 中的最大值吗?为什么会有这样的限制?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-26
  • 1970-01-01
  • 2020-03-24
  • 2018-08-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多