很抱歉我的英语不太好,因为我无法用更清晰的方式说明我的问题。
TLDR:
-
需要按字段分组da
-
排序按字段递减db
-
然后排序按字段递增dc
-
然后每组只挑最上面的一个。
这是我的场景;我在mongodb中有一些记录。示例文档:
{"userId" 2"data"bbbbbx"版本:2mainVersion: 1}
一个用户可能有多条记录,例如userId:2有N条记录。规则是:每当在这里保存新记录时,版本属性增加1。
所以,userId可能有5条记录;最旧记录的版本为1,最新记录的版本为5。
同样,这些记录继承自系统的一个主记录,它也有一个版本号。上面的记录有一个"mainversion";域,等于1。当系统的主记录被更新时,用户记录也被更新。
我们设;userId:2有5条记录,最近的版本是5,mainVersion是1。然后发生系统更新,所有用户记录也随之更新。UserId:2现在有6条记录,我可以像这样显示UserId:2的记录流:
- 版本:1mainVersion: 1
- (用户更新其记录) 2
- 版本:mainVersion: 1
- (用户更新其记录)
- 版本:3mainVersion: 1
- (用户更新其记录) 4
- 版本:mainVersion: 1
- (用户更新其记录) 5
- 版本:mainVersion: 1
- (此处为系统更新)
- 版:5 mainVersion:2
如果有新用户加入系统,其第一条记录以当前mainVersion开头。如果userId:3是此时的新用户,它的第一条记录应该是:
{"userId" 3,数据:这里的数据第1版:(它的第一条记录),2 mainVersion:(当前mainVersion)}
我的问题:我正在试着做一些查询。
我试图为用户选择最近的记录。对于我编写的场景,我需要记录;
- 版:5 mainVersion: 2
标识:2。主排序字段是mainVersion,二级排序字段是版本. 如果userId:2已经创建了一个版本:6但mainVersion:1的记录(我们可以说这是系统故障或用户决定不使用该记录),我忽略它。
我已经在mongo playground中实现了这个基本场景,你可以检查一下。https://mongoplayground.net/p/LMBpWSLB1tN
我认为我能够选择最近的记录与我的聚合查询那里,我使用mergeObjects对于双字段,选择max
但是现在我需要选择当前mainVersion的第一个记录。假设userId:2的记录是:
- 版:5 mainVersion: 2
但是userId:3有许多更新并且有N条记录与mainVersion:2.
- 版本:1 mainVersion: 1
- 版本:2 mainVersion: 1
- …
- 版本:11 mainVersion: 1
- 版本:11 mainVersion:2(当前mainVersion的第一个记录,我需要那个!)
- 版本:12 mainVersion: 2
- …
- 版本:N mainVersion:2(这是最新版本)
我需要userId:3的版本:11和mainVersion:2的记录
我需要为每个userId each。
我在这里工作的mongo是4.2.22版本,所以我不能使用新版本中引入的窗口函数等新东西。
有什么选择这些记录的想法吗?我不知道如何使用多个mergeObjects获取maxmainVersion andmin的版本。(很抱歉写了这么长)
您可以在$lookup
的子管道中执行$sort
+$limit
逻辑
db.collection.aggregate([
{
$group: {
_id: "$userId"
}
},
{
"$lookup": {
"from": "collection",
"let": {
uid: "$_id"
},
"pipeline": [
{
$match: {
$expr: {
$eq: [
"$$uid",
"$userId"
]
}
}
},
{
$sort: {
mainVersion: -1,
version: 1
}
},
{
"$limit": 1
}
],
"as": "top1"
}
},
{
$unwind: "$top1"
},
{
"$replaceRoot": {
"newRoot": "$top1"
}
}
])
Mongo操场