CosmosDb 复杂排序
CosmosDb complex sorting
我有一个 CosmosDb 集合,其中包含如下所示的文档:
{
"status": [0/1]
"someFlag": [true/false]
"score": 24.0
}
我想通过一些复杂的排序查询此集合:
- 首先我想获取状态为 1 且 someFlag 为 true 的文档
- 其次,status为1,someFlag为false
- 三、status为0且someFlag为true
- 四、status为0,someFlag为false
所以我有 4 个部分,我希望在每个部分中从最高分开始排序。
我能以某种方式使用单个 SQL 查询或使用 .NET 客户端对数据库进行单个请求吗?
我只是想补充一些信息。
如果你有这样的collection
[{"status": 0,"someFlag": true,"score": 24},{"status": 0,"someFlag": false,"score": 23},
{"status": 1,"someFlag": false,"score": 20},{"status": 1,"someFlag": true,"score": 28},
{"status": 0,"someFlag": false,"score": 31},{"status": 0,"someFlag": true,"score": 33},
{"status": 1,"someFlag": false,"score": 17},{"status": 1,"someFlag": true,"score": 15}]
并且您想在 cosmosbd 中使用单个 sql 获得这样的查询结果:
[{"status": 0,"someFlag": true,"score": 24},{"status": 0,"someFlag": true,"score": 33},
{"status": 0,"someFlag": false,"score": 23},{"status": 0,"someFlag": false,"score": 31},
{"status": 1,"someFlag": true,"score": 15},{"status": 1,"someFlag": true,"score": 28},
{"status": 1,"someFlag": false,"score": 17},{"status": 1,"someFlag": false,"score": 20}]
我觉得不可能。我试过这样的 sql 但它失败了。正如你所说,你可以使用 4 个查询部分来获得结果,所以剩下的任务是连接这 4 个部分,所以我们需要使用 array_concat,但它确实在 cosmosdb 中不支持。至少,到现在我还没有找到实现它的函数。
SELECT ARRAY_CONCAT((SELECT aa.status,aa.someFlag,aa.score FROM c as aa where aa.status=0 and aa.someFlag=true order by aa.score),
(SELECT bb.status,bb.someFlag,bb.score FROM c as bb where bb.status=1 and bb.someFlag=true order by bb.score)) AS arrayConcat
如我的评论所述,您可以在 where
子句中组合多个表达式,将它们与 or
或 and
.
组合
我认为这里的困惑在于,在您的问题中,您没有提供示例输出,而且您不太清楚您想如何执行排序。如果总共有四个查询形成一个联合,就可以完成。如果是四个单独的查询,您希望每个子查询都排序,那么您不能这样做。
对于前者:在你的例子中,你可以这样做:
SELECT c.status, c.someFlag, c.score FROM c
WHERE (c.status = 1 AND c.someFlag = true)
OR (c.status = 1 AND c.someFlag = false)
OR (c.status = 0 AND c.someFlag = true)
OR (c.status = 0 AND c.someFlag = false)
ORDER BY c.score DESC
对于输入数据,包括一份将被过滤掉的文档(带有status = 2
的文档):
[
{
"status": 0,
"someFlag": true,
"score": 24
},
{
"status": 0,
"someFlag": false,
"score": 25
},
{
"status": 1,
"someFlag": true,
"score": 26
},
{
"status": 1,
"someFlag": false,
"score": 27
},
{
"status": 2,
"someFlag": false,
"score": 0
}
]
结果:
[
{
"status": 1,
"someFlag": false,
"score": 27
},
{
"status": 1,
"someFlag": true,
"score": 26
},
{
"status": 0,
"someFlag": false,
"score": 25
},
{
"status": 0,
"someFlag": true,
"score": 24
}
]
使用以下 SQL 和 ut 需要的复合索引与这三个字段一起工作。
SELECT *
FROM c
WHERE c.Status = 0 OR c.Status = 1
ORDER BY c.Status DESC, c.SomeFlag DESC, c.Score DESC
我有一个 CosmosDb 集合,其中包含如下所示的文档:
{
"status": [0/1]
"someFlag": [true/false]
"score": 24.0
}
我想通过一些复杂的排序查询此集合:
- 首先我想获取状态为 1 且 someFlag 为 true 的文档
- 其次,status为1,someFlag为false
- 三、status为0且someFlag为true
- 四、status为0,someFlag为false
所以我有 4 个部分,我希望在每个部分中从最高分开始排序。 我能以某种方式使用单个 SQL 查询或使用 .NET 客户端对数据库进行单个请求吗?
我只是想补充一些信息。
如果你有这样的collection
[{"status": 0,"someFlag": true,"score": 24},{"status": 0,"someFlag": false,"score": 23},
{"status": 1,"someFlag": false,"score": 20},{"status": 1,"someFlag": true,"score": 28},
{"status": 0,"someFlag": false,"score": 31},{"status": 0,"someFlag": true,"score": 33},
{"status": 1,"someFlag": false,"score": 17},{"status": 1,"someFlag": true,"score": 15}]
并且您想在 cosmosbd 中使用单个 sql 获得这样的查询结果:
[{"status": 0,"someFlag": true,"score": 24},{"status": 0,"someFlag": true,"score": 33},
{"status": 0,"someFlag": false,"score": 23},{"status": 0,"someFlag": false,"score": 31},
{"status": 1,"someFlag": true,"score": 15},{"status": 1,"someFlag": true,"score": 28},
{"status": 1,"someFlag": false,"score": 17},{"status": 1,"someFlag": false,"score": 20}]
我觉得不可能。我试过这样的 sql 但它失败了。正如你所说,你可以使用 4 个查询部分来获得结果,所以剩下的任务是连接这 4 个部分,所以我们需要使用 array_concat,但它确实在 cosmosdb 中不支持。至少,到现在我还没有找到实现它的函数。
SELECT ARRAY_CONCAT((SELECT aa.status,aa.someFlag,aa.score FROM c as aa where aa.status=0 and aa.someFlag=true order by aa.score),
(SELECT bb.status,bb.someFlag,bb.score FROM c as bb where bb.status=1 and bb.someFlag=true order by bb.score)) AS arrayConcat
如我的评论所述,您可以在 where
子句中组合多个表达式,将它们与 or
或 and
.
我认为这里的困惑在于,在您的问题中,您没有提供示例输出,而且您不太清楚您想如何执行排序。如果总共有四个查询形成一个联合,就可以完成。如果是四个单独的查询,您希望每个子查询都排序,那么您不能这样做。
对于前者:在你的例子中,你可以这样做:
SELECT c.status, c.someFlag, c.score FROM c
WHERE (c.status = 1 AND c.someFlag = true)
OR (c.status = 1 AND c.someFlag = false)
OR (c.status = 0 AND c.someFlag = true)
OR (c.status = 0 AND c.someFlag = false)
ORDER BY c.score DESC
对于输入数据,包括一份将被过滤掉的文档(带有status = 2
的文档):
[
{
"status": 0,
"someFlag": true,
"score": 24
},
{
"status": 0,
"someFlag": false,
"score": 25
},
{
"status": 1,
"someFlag": true,
"score": 26
},
{
"status": 1,
"someFlag": false,
"score": 27
},
{
"status": 2,
"someFlag": false,
"score": 0
}
]
结果:
[
{
"status": 1,
"someFlag": false,
"score": 27
},
{
"status": 1,
"someFlag": true,
"score": 26
},
{
"status": 0,
"someFlag": false,
"score": 25
},
{
"status": 0,
"someFlag": true,
"score": 24
}
]
使用以下 SQL 和 ut 需要的复合索引与这三个字段一起工作。
SELECT *
FROM c
WHERE c.Status = 0 OR c.Status = 1
ORDER BY c.Status DESC, c.SomeFlag DESC, c.Score DESC