MongoDb,查询最后一个,并分组
MongoDb, query the last, and group by
我在处理 MongoDb 时遇到了麻烦。
我需要:
- 获取所有最后的条目
- 关于一个字段
- 喜欢:SELECT MAX(id), foreignKey FROM t_table GROUP BY foreignKey
我知道我们可以将 $last 与 mongodb 一起使用,但我完全不知道如何进行。
我试过了:
db.collection.aggregate(
[
{
$group:
{
_id: "$zone._id",
lastRegistered: { $last: "$_id" }
}
}
]
)
但它似乎没有给我我需要的东西
编辑示例
据此三:
{ _id: 55d5a01f9f58d2cc0eb79f5d,
controlDate: Thu Aug 20 2015 11:38:40 GMT+0200 (Paris, Madrid (heure d’été)),
zone:
{ _id: 55cb5bb42d191d2022c5c266,
zoneName: 'Syphon 1',
},
actif: true
},
{ _id: 55d59f129f58d2cc0eb79f5c,
controlDate: Fri Aug 21 2015 07:34:12 GMT+0200 (Paris, Madrid (heure d’été)),
zone:
{ _id: 55cb5bb42d191d2022c5c266,
zoneName: 'Syphon 1',
},
actif: true
}
{ _id: 55d5a01f9f58d2cc0eb79f5e,
controlDate: Fri Aug 20 2015 08:38:40 GMT+0200 (Paris, Madrid (heure d’été)),
zone:
{ _id: 55cb5bb42d191d2022c5c278,
zoneName: 'Other zone',
},
actif: true
},
我需要得到:
{ _id: 55d59f129f58d2cc0eb79f5c,
controlDate: Fri Aug 21 2015 07:34:12 GMT+0200 (Paris, Madrid (heure d’été)),
zone:
{ _id: 55cb5bb42d191d2022c5c266,
zoneName: 'Syphon 1',
},
actif: true
}
{ _id: 55d5a01f9f58d2cc0eb79f5e,
controlDate: Fri Aug 20 2015 08:38:40 GMT+0200 (Paris, Madrid (heure d’été)),
zone:
{ _id: 55cb5bb42d191d2022c5c278,
zoneName: 'Other zone',
},
actif: true
},
这意味着:我需要获取按区域 _id 分组的此集合的最后一个(按 ID 或日期,没关系)。 (2 行,因为我有一个区域的 2 个数据集(我只需要最后一个),我需要另一个区域的最后一个(只有 1 行所以..))
你明白我的意思吗?
$last
为您提供由您的分组处理的最后一个文档的值。您无法预测文档的处理顺序,除非您对文档进行排序。所以你没有得到你期望的结果。
尝试在 $group 阶段之前添加一个 $sort 阶段,以按日期升序获取文档:
db.collection.aggregate(
[
{ $sort: {
"control_date":1
}
},
{
$group:
{
_id: "$zone._id",
lastRegistered: { $last: "$_id" },
zoneName:"$zone.zoneName",
control_id:"$_id",
actif:"$actif",
}
}
]
)
您始终可以使用 $$ROOT
来 return 分组边界上的整个文档:
db.collection.aggregate([
{ "$group": {
"_id": "$zone._id",
"doc": { "$last": "$$ROOT" }
}}
])
或者使用直接排序控制而不是自然顺序:
db.collection.aggregate([
{ "$sort": { "_id": 1 } },
{ "$group": {
"_id": "$zone._id",
"doc": { "$last": "$$ROOT" }
}}
])
但请注意,$group
管道不保证保留文档顺序,因此如果您需要,那么您再次 $sort
:
db.collection.aggregate([
{ "$sort": { "_id": 1 } },
{ "$group": {
"_id": "$zone._id",
"doc": { "$last": "$$ROOT" }
}},
{ "$sort": { "doc._id": 1 } }
])
在所有情况下,更改为 $$ROOT
只是声明 $last
explicitly for each field you want from the document. By contrast the $max
运算符仅适用于指定字段,因此当您需要来自分组边界的文档时,这通常对您没有用正如 $last
所做的那样。
考虑那里的 "last" 示例并从您的示例中删除适当的数据然后我得到:
{
"_id" : "55cb5bb42d191d2022c5c266",
"doc" : {
"_id" : "55d5a01f9f58d2cc0eb79f5d",
"zone" : {
"_id" : "55cb5bb42d191d2022c5c266",
"zoneName" : "Syphon 1"
},
"actif" : true
}
},
{
"_id" : "55cb5bb42d191d2022c5c278",
"doc" : {
"_id" : "55d5a01f9f58d2cc0eb79f5e",
"zone" : {
"_id" : "55cb5bb42d191d2022c5c278",
"zoneName" : "Other zone"
},
"actif" : true
}
}
修改后的输入是这样的:
{
"_id" : "55d5a01f9f58d2cc0eb79f5d",
"zone" : {
"_id" : "55cb5bb42d191d2022c5c266",
"zoneName" : "Syphon 1"
},
"actif" : true
},
{
"_id" : "55d59f129f58d2cc0eb79f5c",
"zone" : {
"_id" : "55cb5bb42d191d2022c5c266",
"zoneName" : "Syphon 1"
},
"actif" : true
},
{
"_id" : "55d5a01f9f58d2cc0eb79f5e",
"zone" : {
"_id" : "55cb5bb42d191d2022c5c278",
"zoneName" : "Other zone"
},
"actif" : true
}
不关心正确的 ObjectId
值,因为十六进制字符串值是词法的,就像 ObjectId
的内部排序一样。
集合中每个提供的 zone._id
值的 "last" 文档是哪些,按给定的原始文档 _id
值排序。
我在处理 MongoDb 时遇到了麻烦。
我需要:
- 获取所有最后的条目
- 关于一个字段
- 喜欢:SELECT MAX(id), foreignKey FROM t_table GROUP BY foreignKey
我知道我们可以将 $last 与 mongodb 一起使用,但我完全不知道如何进行。
我试过了:
db.collection.aggregate(
[
{
$group:
{
_id: "$zone._id",
lastRegistered: { $last: "$_id" }
}
}
]
)
但它似乎没有给我我需要的东西
编辑示例
据此三:
{ _id: 55d5a01f9f58d2cc0eb79f5d,
controlDate: Thu Aug 20 2015 11:38:40 GMT+0200 (Paris, Madrid (heure d’été)),
zone:
{ _id: 55cb5bb42d191d2022c5c266,
zoneName: 'Syphon 1',
},
actif: true
},
{ _id: 55d59f129f58d2cc0eb79f5c,
controlDate: Fri Aug 21 2015 07:34:12 GMT+0200 (Paris, Madrid (heure d’été)),
zone:
{ _id: 55cb5bb42d191d2022c5c266,
zoneName: 'Syphon 1',
},
actif: true
}
{ _id: 55d5a01f9f58d2cc0eb79f5e,
controlDate: Fri Aug 20 2015 08:38:40 GMT+0200 (Paris, Madrid (heure d’été)),
zone:
{ _id: 55cb5bb42d191d2022c5c278,
zoneName: 'Other zone',
},
actif: true
},
我需要得到:
{ _id: 55d59f129f58d2cc0eb79f5c,
controlDate: Fri Aug 21 2015 07:34:12 GMT+0200 (Paris, Madrid (heure d’été)),
zone:
{ _id: 55cb5bb42d191d2022c5c266,
zoneName: 'Syphon 1',
},
actif: true
}
{ _id: 55d5a01f9f58d2cc0eb79f5e,
controlDate: Fri Aug 20 2015 08:38:40 GMT+0200 (Paris, Madrid (heure d’été)),
zone:
{ _id: 55cb5bb42d191d2022c5c278,
zoneName: 'Other zone',
},
actif: true
},
这意味着:我需要获取按区域 _id 分组的此集合的最后一个(按 ID 或日期,没关系)。 (2 行,因为我有一个区域的 2 个数据集(我只需要最后一个),我需要另一个区域的最后一个(只有 1 行所以..))
你明白我的意思吗?
$last
为您提供由您的分组处理的最后一个文档的值。您无法预测文档的处理顺序,除非您对文档进行排序。所以你没有得到你期望的结果。
尝试在 $group 阶段之前添加一个 $sort 阶段,以按日期升序获取文档:
db.collection.aggregate(
[
{ $sort: {
"control_date":1
}
},
{
$group:
{
_id: "$zone._id",
lastRegistered: { $last: "$_id" },
zoneName:"$zone.zoneName",
control_id:"$_id",
actif:"$actif",
}
}
]
)
您始终可以使用 $$ROOT
来 return 分组边界上的整个文档:
db.collection.aggregate([
{ "$group": {
"_id": "$zone._id",
"doc": { "$last": "$$ROOT" }
}}
])
或者使用直接排序控制而不是自然顺序:
db.collection.aggregate([
{ "$sort": { "_id": 1 } },
{ "$group": {
"_id": "$zone._id",
"doc": { "$last": "$$ROOT" }
}}
])
但请注意,$group
管道不保证保留文档顺序,因此如果您需要,那么您再次 $sort
:
db.collection.aggregate([
{ "$sort": { "_id": 1 } },
{ "$group": {
"_id": "$zone._id",
"doc": { "$last": "$$ROOT" }
}},
{ "$sort": { "doc._id": 1 } }
])
在所有情况下,更改为 $$ROOT
只是声明 $last
explicitly for each field you want from the document. By contrast the $max
运算符仅适用于指定字段,因此当您需要来自分组边界的文档时,这通常对您没有用正如 $last
所做的那样。
考虑那里的 "last" 示例并从您的示例中删除适当的数据然后我得到:
{
"_id" : "55cb5bb42d191d2022c5c266",
"doc" : {
"_id" : "55d5a01f9f58d2cc0eb79f5d",
"zone" : {
"_id" : "55cb5bb42d191d2022c5c266",
"zoneName" : "Syphon 1"
},
"actif" : true
}
},
{
"_id" : "55cb5bb42d191d2022c5c278",
"doc" : {
"_id" : "55d5a01f9f58d2cc0eb79f5e",
"zone" : {
"_id" : "55cb5bb42d191d2022c5c278",
"zoneName" : "Other zone"
},
"actif" : true
}
}
修改后的输入是这样的:
{
"_id" : "55d5a01f9f58d2cc0eb79f5d",
"zone" : {
"_id" : "55cb5bb42d191d2022c5c266",
"zoneName" : "Syphon 1"
},
"actif" : true
},
{
"_id" : "55d59f129f58d2cc0eb79f5c",
"zone" : {
"_id" : "55cb5bb42d191d2022c5c266",
"zoneName" : "Syphon 1"
},
"actif" : true
},
{
"_id" : "55d5a01f9f58d2cc0eb79f5e",
"zone" : {
"_id" : "55cb5bb42d191d2022c5c278",
"zoneName" : "Other zone"
},
"actif" : true
}
不关心正确的 ObjectId
值,因为十六进制字符串值是词法的,就像 ObjectId
的内部排序一样。
集合中每个提供的 zone._id
值的 "last" 文档是哪些,按给定的原始文档 _id
值排序。