寻找适用于 mongodb 4.2.x 的替代结果投影
Looking for alternative result projection that works on mongodb 4.2.x
根据我的最后一个问题 (),我构建了一个查询来检查多个可能重叠的日期范围内的文档数量。
该查询适用于 MongoDB 4.4,但我也需要 运行 它适用于 4.2。
在 MongoDB 4.2 上,我收到以下错误:
Mongo Server error (MongoCommandException): Command failed with error 168 (InvalidPipelineOperator): 'Unrecognized expression '$first'' on server localhost:27017.
The full response is:
{
"ok" : 0.0,
"errmsg" : "Unrecognized expression '$first'",
"code" : 168.0,
"codeName" : "InvalidPipelineOperator"
}
您将如何编写聚合投影来实现相同的结果结构。
这是带有数据设置的完整代码
db.createCollection("object_location_tracking");
db.getCollection("object_location_tracking").insertMany([
{
_id: "1",
locationId: "locationA",
objectId: "objectA",
timestamp: ISODate("2020-01-01T00:00:00Z")
},
{
_id: "2",
locationId: "locationB",
objectId: "objectA",
timestamp: ISODate("2020-01-01T00:00:00Z")
},
{
_id: "3",
locationId: "locationA",
objectId: "objectB",
timestamp: ISODate("2019-01-01T00:00:00Z")
},
{
_id: "4",
locationId: "locationB",
objectId: "objectB",
timestamp: ISODate("2020-01-01T00:00:00Z")
}
]);
db.getCollection("object_location_tracking").aggregate([
{$facet: {
"first_bucket_id": [
{$match: {"objectId":"objectA",
"locationId":"locationA",
"timestamp": {$gte: new ISODate('2020-01-01'),
$lt: new ISODate('2020-12-31')}
}},
{$count: "N"}
],
"second_bucket_id": [
{$match: {"objectId":"objectA",
"locationId":"locationA",
"timestamp": {$gte: new ISODate('2020-01-01'),
$lt: new ISODate('2022-12-31')}
}},
{$count: "N"}
],
"third_bucket_id": [
{$match: {"objectId":"objectA",
"locationId":"locationB",
"timestamp": {$gte: new ISODate('2022-01-01'),
$lt: new ISODate('2022-12-31')}
}},
{$count: "N"}
]
}},
{
$set: {
first_bucket_id: { $first: "$first_bucket_id.N"},
second_bucket_id: { $first: "$second_bucket_id.N"},
third_bucket_id: { $first: "$third_bucket_id.N"}
}
}
, {
$project: {
first_bucket_id: 1,
second_bucket_id: 1,
third_bucket_id: 1
}
}
]);
您正在使用 first array element,您可以看出这是为版本 4.4 添加的新运算符
幸运的是,这很容易克服,只需使用 $arrayElemAt,就像这样:
{
$set: {
first_bucket_id: {$arrayElemAt: ["$first_bucket_id.N", 0]},
second_bucket_id: {$arrayElemAt: ["$second_bucket_id.N", 0]},
third_bucket_id: {$arrayElemAt: ["$third_bucket_id.N", 0]}
}
}
根据我的最后一个问题 (
该查询适用于 MongoDB 4.4,但我也需要 运行 它适用于 4.2。 在 MongoDB 4.2 上,我收到以下错误:
Mongo Server error (MongoCommandException): Command failed with error 168 (InvalidPipelineOperator): 'Unrecognized expression '$first'' on server localhost:27017.
The full response is:
{
"ok" : 0.0,
"errmsg" : "Unrecognized expression '$first'",
"code" : 168.0,
"codeName" : "InvalidPipelineOperator"
}
您将如何编写聚合投影来实现相同的结果结构。 这是带有数据设置的完整代码
db.createCollection("object_location_tracking");
db.getCollection("object_location_tracking").insertMany([
{
_id: "1",
locationId: "locationA",
objectId: "objectA",
timestamp: ISODate("2020-01-01T00:00:00Z")
},
{
_id: "2",
locationId: "locationB",
objectId: "objectA",
timestamp: ISODate("2020-01-01T00:00:00Z")
},
{
_id: "3",
locationId: "locationA",
objectId: "objectB",
timestamp: ISODate("2019-01-01T00:00:00Z")
},
{
_id: "4",
locationId: "locationB",
objectId: "objectB",
timestamp: ISODate("2020-01-01T00:00:00Z")
}
]);
db.getCollection("object_location_tracking").aggregate([
{$facet: {
"first_bucket_id": [
{$match: {"objectId":"objectA",
"locationId":"locationA",
"timestamp": {$gte: new ISODate('2020-01-01'),
$lt: new ISODate('2020-12-31')}
}},
{$count: "N"}
],
"second_bucket_id": [
{$match: {"objectId":"objectA",
"locationId":"locationA",
"timestamp": {$gte: new ISODate('2020-01-01'),
$lt: new ISODate('2022-12-31')}
}},
{$count: "N"}
],
"third_bucket_id": [
{$match: {"objectId":"objectA",
"locationId":"locationB",
"timestamp": {$gte: new ISODate('2022-01-01'),
$lt: new ISODate('2022-12-31')}
}},
{$count: "N"}
]
}},
{
$set: {
first_bucket_id: { $first: "$first_bucket_id.N"},
second_bucket_id: { $first: "$second_bucket_id.N"},
third_bucket_id: { $first: "$third_bucket_id.N"}
}
}
, {
$project: {
first_bucket_id: 1,
second_bucket_id: 1,
third_bucket_id: 1
}
}
]);
您正在使用 first array element,您可以看出这是为版本 4.4 添加的新运算符
幸运的是,这很容易克服,只需使用 $arrayElemAt,就像这样:
{
$set: {
first_bucket_id: {$arrayElemAt: ["$first_bucket_id.N", 0]},
second_bucket_id: {$arrayElemAt: ["$second_bucket_id.N", 0]},
third_bucket_id: {$arrayElemAt: ["$third_bucket_id.N", 0]}
}
}