【发布时间】:2018-09-21 10:28:10
【问题描述】:
我们正在尝试在 Azure Cosmos DB 中查询的 where 子句中使用简单的用户定义函数 (UDF),但它无法正常工作。最终目标是查询时间戳_ts 大于或等于昨天的所有结果,但我们的第一步是让 UDF 工作。
缩写数据如下所示:
[
{
"_ts": 1500000007
}
{
"_ts": 1500000005
}
]
使用 Azure 门户的 Cosmos DB 数据资源管理器,类似以下的简单查询将正确返回 一个结果:
SELECT * FROM c WHERE c._ts >= 1500000006
错误地使用我们的 UDF 的简单查询会返回 零 个结果。该查询如下:
SELECT * FROM c WHERE c._ts >= udf.getHardcodedTime()
函数定义如下:
function getHardcodedTime(){
return 1500000006;
}
这是用于验证的 UDF 的屏幕截图:
如您所见,两个查询之间的唯一区别是一个查询使用硬编码值,而另一个查询使用 UDF 来获取硬编码值。问题是使用 UDF 的查询返回 zero 结果而不是返回 one 结果。
我们是否正确使用了 UDF?
更新 1
当 UDF 更新为返回数字 1 时,我们每次都会得到不同的结果计数。
新功能:
function getHardcodedTime(){
return 1;
}
新查询:SELECT count(1) FROM c WHERE c._ts >= udf.getHardcodedTime()
结果因 7240、7236、7233、7264 等而异(这组是 Cosmos DB 响应的实际顺序。)
【问题讨论】:
-
我没有看到使用 udf 的问题,也无法使用 Cosmos DB Emulator 重现该问题。如果你运行
SELECT udf.getHardcodedTime() FROM c,你会得到什么? -
我返回了许多对象,其中对象包含来自函数的值。这是一个sn-p。 [ {"$1": 1500000006 }, ... {"$1": 1500000006} ]
-
会不会是在 select-using-udf 案例中获得了延续令牌?如果 cosmosDB 没有推断出您的 udf 是确定性的,那么它就不能再使用索引,因此它将进行完整扫描。
-
有没有办法向 Cosmos DB 表明该函数是确定性的?我找到了一些关于如何使用 SQL 数据库执行此操作的示例,但我没有找到任何适用于 Cosmos DB 的示例。
-
我不认为你可以。但是您可以通过使用 SP,从 UDF 获取参数并将其作为值传递给查询来解决此问题。麻烦,但应该可以。
标签: user-defined-functions azure-cosmosdb