在 MongoDB 中,我試圖將集合過濾到僅包含其各自組的最新日期的那些檔案。
在傳統的 SQL 中,我會執行以下操作:
Select *
From table a
Join (Select my_group, max(date) as max_date
From table group by my_group) b
ON a.my_group = b.my_group AND
a.date = b.max_date
使用以下示例集合:
[
{
"_id": "123",
"item1": "group 1",
"item2": "abc",
"item3": "abc",
"date": "2022-01-01"
},
{
"_id": "234",
"item1": "group 1",
"item2": "abc",
"item3": "abc",
"date": "2022-01-02"
},
{
"_id": "345",
"item1": "group 1",
"item2": "abc",
"item3": "abc",
"date": "2022-01-02"
},
{
"_id": "789",
"item1": "group 2",
"item2": "abc",
"item3": "abc",
"date": "2022-01-01"
},
{
"_id": "678",
"item1": "group 2",
"item2": "abc",
"item3": "abc",
"date": "2022-01-02"
},
{
"_id": "456",
"item1": "group 2",
"item2": "abc",
"item3": "abc",
"date": "2022-01-02"
}
]
預期的輸出是:
[
{
"_id": "234",
"date": "2022-01-02",
"item1": "group 1",
"item2": "abc",
"item3": "abc"
},
{
"_id": "345",
"date": "2022-01-02",
"item1": "group 1",
"item2": "abc",
"item3": "abc"
},
{
"_id": "678",
"date": "2022-01-02",
"item1": "group 2",
"item2": "abc",
"item3": "abc"
},
{
"_id": "456",
"date": "2022-01-02",
"item1": "group 2",
"item2": "abc",
"item3": "abc"
}
]
我目前最好的嘗試是:
db.collection.aggregate([
{
$group: {
"_id": "$item1",
"max_date": {
$max: "$date"
},
"records": {
$push: "$$ROOT"
}
}
},
{
"$project": {
items: {
"$filter": {
"input": "$records",
"as": "records",
"cond": {
$eq: [
"$$records.date",
"$max_date"
]
}
}
}
}
},
{
$replaceRoot: {
newRoot: {
results: "$items"
}
}
}
])
不幸的是,這會回傳按組磁區的結果。我嘗試了其他帖子建議的一些替代方案并遇到了類似的問題,例如:
- 如何在MongoDB中對每個組內的max對應的檔案進行分組和選擇?
- MongoDB獲取最大值分組的行
- 獲取所有行,分組并具有最大值
這是一個帶有查詢和示例資料的游樂場示例。
uj5u.com熱心網友回復:
你已經接近答案了。
對于最后 2 個階段:
$unwinditems- 將陣列欄位解構為多個檔案。$replaceWith- 用檔案替換輸出items檔案。
db.collection.aggregate([
{
$group: {
"_id": "$item1",
"max_date": {
$max: "$date"
},
"records": {
$push: "$$ROOT"
}
}
},
{
"$project": {
items: {
"$filter": {
"input": "$records",
"as": "records",
"cond": {
$eq: [
"$$records.date",
"$max_date"
]
}
}
}
}
},
{
$unwind: "$items"
},
{
$replaceWith: "$items"
}
])
示例 Mongo Playground
獎金
雖然上面的查詢比較好,但也想分享一下類似SQL實作的MongoDB查詢。
$group- 分組item1并獲得最大值date。$lookupitem1- 使用和自行加入集合date。并回傳items陣列欄位。$matchitems- 使用非空陣列過濾檔案。$unwinditems- 將陣列解構為多個檔案。$replaceWith- 用檔案替換輸出items檔案。
db.collection.aggregate([
{
$group: {
"_id": "$item1",
"max_date": {
$max: "$date"
}
}
},
{
$lookup: {
from: "collection",
let: {
item1: "$_id",
max_date: "$max_date"
},
pipeline: [
{
$match: {
$expr: {
$and: [
{
$eq: [
"$item1",
"$$item1"
]
},
{
$eq: [
"$date",
"$$max_date"
]
}
]
}
}
}
],
as: "items"
}
},
{
$match: {
items: {
$ne: []
}
}
},
{
$unwind: "$items"
},
{
$replaceWith: "$items"
}
])
示例 Mongo Playground(獎金)
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/470768.html
標籤:mongodb
