mongodb - Mongo 聚合:使用 $count 找到的文档进行查询
问题描述
我有一个 Mongo 集合系列,其中每个文档都有一个带有dataPoints的列表。具有相同testStepId的所有系列都包含相同数量的dataPoints:
{
"seriesId": {
"seriesId": "77678ca1-31db-4cec-a042-68a3053b92c6"
},
"testStepId": {
"testStepId": "c152415b-2392-4c2b-af74-51a4973bd257"
},
"measurement": {
"startTime": {
"$date": "2020-07-07T12:40:49.782Z"
},
"endTime": {
"$date": "2020-07-07T12:42:19.782Z"
}
},
"dataPoints": [
{
"timeStamp": {
"$date": "2020-07-07T12:41:09.782Z"
},
"value": "Value_1_1"
},
{
"timeStamp": {
"$date": "2020-07-07T12:41:29.782Z"
},
"value": "Value_1_2"
},
{
"timeStamp": {
"$date": "2020-07-07T12:41:39.782Z"
},
"value": "Value_1_3"
},
...
{
"timeStamp": {
"$date": "2020-07-07T12:42:19.782Z"
},
"value": "Value_2_11"
}
]
}
现在我想查询与特定testStepId匹配的所有系列文档(没问题)。但是,我不想加载所有找到的系列的所有数据点,我只想加载 1000 个数据点。因此,如果找到 10 个系列,我只需为每个系列加载 100个数据点:
-> 加载每个(dataPoints.size() / 100)-th 个数据点
-> 这意味着我必须考虑找到的系列文档的数量和系列中数据点的数量
-> 加载每个第 X 个数据点,其中
X = 1000 / <count of documents> / <count of dataPoints>
我正在努力通过与MongoDB Compass聚合来完成这项工作。但是我仍然无法计算找到的文件并取消这个值......
首先,我只是尝试获取每个第二个dataPoint:
{
project: {
dataPoints: {
$map: {
input: { $range: [ 0, {"$size": "$dataPoints"}, 2 ] },
as: "index",
in: { $arrayElemAt: [ "$dataPoints", "$$index" ] }
}
}
}
}
-> 工作正常
现在我想根据找到的文档的数量来获取每个 x-th 'dataPoint' 依赖。为此,我尝试了一些不同的方法,它们都不起作用......
- 尝试:使用$count而不是固定数字:
{
project: {
dataPoints: {
$map: {
input: { $range: [ 0, {"$size": "$dataPoints"}, $count ] },
as: "index",
in: { $arrayElemAt: [ "$dataPoints", "$$index" ] }
}
}
}
}
-> “项目规范必须是一个对象”
- 尝试:将计数定义为变量:
{
project: {
dataPoints: {
$let: {
vars: {
total: "$count",
},
in: {
$map: {
input: { $range: [ 0, {"$size": "$dataPoints"}, "$$total"] },
as: "index",
in: { $arrayElemAt: [ "$dataPoints", "$$index" ] }
}
}
}
}
}
}
-> "$range 需要一个数值步骤,找到类型的值:缺失"
显然我的方法是错误的。任何人都可以给我一些提示如何让它工作吗?
解决方案
我认为的公式X
是X = <count of dataPoints> * <count of documents> / 1000
您不能直接访问特定聚合管道阶段的文档数量(计数)。但是,您可以将所有文档合并为一个文档并对其进行计数,然后将它们展开回单独的文档。您可以使用$group
or来实现此目的$facet
。
我将展示一个例子$group
[
{
$group: {
_id: null,
count: { $sum: 1 },
all: { $push: "$$ROOT" }
}
},
{
$unwind: "$all"
},
{
$replaceWith: { // $replaceWith is available from v4.2, for earlier version use { $replaceRoot: { newRoot: <doc> } }
$mergeObjects: [
"$all",
{
dataPoints: {
$map: {
input: {
$range: [
0,
{ $size: "$all.dataPoints" },
{
$ceil: {
$divide: [
{
$multiply: [
{ "$size": "$all.dataPoints" },
"$count"
]
},
1000
]
}
}
]
},
as: "index",
in: { $arrayElemAt: ["$all.dataPoints", "$$index"] }
}
}
}
]
}
}
]
推荐阅读
- math - 构造一个双射函数将任意整数从 [1, n] 随机映射到 [1, n]
- c# - 输出不是它应该是的
- android - 如何通过点击Fragment中的菜单项来设置和更新工具栏中的标题?
- react-native - React Native - 离线视频加密+解密
- python-3.x - MADDPG:RuntimeError:梯度计算所需的变量之一已被就地操作修改
- android - 设置 MinifyEnabled 后应用程序崩溃并出现未知错误 - Kotlin
- javascript - 如何自动选择 React Material TextField 的值?
- javascript - 如何在 React JS 中呈现 CKEditor4 wiris MathML 公式
- mysql - 如何根据一对多的关系进行选择?
- r - 根据if语句重复R中的单元格值