【问题标题】:Difference among the Azure CosmosDB Query Explorer's results and the Azure Functions resultsAzure CosmosDB 查询资源管理器的结果与 Azure Functions 结果之间的差异
【发布时间】:2017-07-05 04:03:17
【问题描述】:

我在 CosmosDB 查询资源管理器上执行了以下查询。

SELECT c.id, c.created_at FROM c 
WHERE c.created_at_epoch <= 1499871600 - 86400*31 
AND (CEILING(1499871600/86400) - CEILING(c.created_at_epoch / 86400)) % 31 = 0

结果如下。

[
  {
    "id": "70251cbf-44b3-4cd9-991f-81127ad78bca",
    "created_at": "2017-05-11 18:46:16"
  },
  {
    "id": "0fa31de2-4832-49ea-a0c6-b517d64ede85",
    "created_at": "2017-05-11 18:48:22"
  },
  {
    "id": "b9959d15-92e7-41c3-8eff-718c4ab2be6e",
    "created_at": "2017-05-11 19:01:43"
  }
]

看起来问题不存在。

接下来,我将静态定义的 epoch 值替换为占位符,以将其用作 Azure Functions DocumentDB 输入绑定的 sqlQuery。然后,我将调制符号替换为%modulationsymbol%,以避免this issue

SELECT c.id, c.created_at FROM c 
WHERE c.created_at_epoch <= {epoch} - 86400*31 
AND (CEILING({epoch}/86400) - CEILING(c.created_at_epoch / 86400))  %modulationsymbol% 31 = 0

我将modulationsymbol = % 定义为应用程序设置。

然后,我指定函数如下。

// index.js
module.exports = function (context, myQueueItem) {
    context.log(context.bindings.members, myQueueItem);
    context.done();
};

// function.json
{
  "bindings": [
    {
      "name": "myQueueItem",
      "type": "queueTrigger",
      "direction": "in",
      "queueName": "myqueue",
      "connection": "MYSTORAGE"
    },
    {
      "type": "documentDB",
      "name": "members",
      "databaseName": "myproject-db",
      "collectionName": "member",
      "sqlQuery": "SELECT c.id, c.created_at FROM c  WHERE {epoch} - c.created_at_epoch >= 86400*31  AND (CEILING({epoch}/86400) - CEILING(c.created_at_epoch / 86400)) %modulationsymbol% 31 = 0",
      "connection": "MYCOSMOSDB",
      "direction": "in"
    }
  ],
  "disabled": true
}

之后,我触发了这个函数,结果如下。

2017-07-05T03:57:29.640 Function started (Id=d980521e-d23a-4bda-a730-57a236bcd011)
2017-07-05T03:57:30.594 [] { epoch: 1499871600 }
2017-07-05T03:57:30.594 Function completed (Success, Id=d980521e-d23a-4bda-a730-57a236bcd011, Duration=951ms)

看起来context.bindings.members 是一个空列表。它与 CosmosDB 查询资源管理器的结果不同。

为什么会出现这种差异?

【问题讨论】:

    标签: azure azure-functions azure-cosmosdb


    【解决方案1】:

    打印出 {epoch} 后,我发现它的类型是字符串,预期的类型是数字而不是字符串。这就是使用相同查询时得到空列表的原因。

    要解决此问题,您可以将类型转换为数字,然后再使用它来过滤查询结果。以下步骤供您参考。

    第一步,创建一个可以将字符串转换为数字的UDF。脚本资源管理器->创建用户定义函数

    function toNumber(ts) { 
       return parseInt(ts);
    }
    

    第2步,创建ConvertToNumber函数后,您可以使用它将{epoch}的类型转换为数字。

    SELECT c.id, c.created_at FROM c 
    WHERE c.created_at_epoch <= udf.ConvertToNumber({epoch}) - 86400*31 
    AND (CEILING(udf.ConvertToNumber({epoch})/86400) - CEILING(c.created_at_epoch / 86400))  %modulationsymbol% 31 = 0
    

    如果您熟悉 C#,则可以使用 C# 创建函数。因为 C# 是一种强类型语言。我们可以定义一个类,用于反序列化队列中的消息。它会在语言层转换类型。

    public class EpochMessage
    {
        public int epoch { get; set; }
    }
    

    整个函数可能是这样的。

    using System;
    
    public static void Run(EpochMessage myQueueItem, TraceWriter log, IEnumerable<dynamic> members)
    {
        log.Info(context.bindings.members, myQueueItem);
    }
    
    public class EpochMessage
    {
        public int epoch { get; set; }
    }
    

    【讨论】:

    • 我知道了,谢谢。但是我的资源中不存在脚本资源管理器。 !Snapshot of CosmosDB Blade
    • 您使用的是不支持 UDF 的 Azure MongoDB 吗?我尝试的是 Azure DocumentDB。
    • 我还编辑了我的回复以提供 C# 版本的解决方法。
    • 我使用这个 CosmosDB 资源,因为它被称为 DocumentDB。今天,EA ProDirect 支持人员教给我一种解决此问题的方法。以下是解决方案的步骤。 Data Explorer(Preview) -> [Collection Menu(looks as '...')] -> New User Defined Function 然后将 sqlQuery 替换为新查询。就这样。多亏你解决了。
    • 很高兴听到您的问题已解决,并感谢您分享您的解决方案。
    猜你喜欢
    • 2020-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-25
    • 1970-01-01
    • 2011-04-21
    • 2021-05-24
    相关资源
    最近更新 更多