英文:
MongoID join on embedded documents
问题
We have a Shipment document with an embedded ShipmentEvent document as in...
class Shipment
include Mongoid::Document
embeds_many :shipment_events
end
class ShipmentEvent
include Mongoid::Document
embedded_in :shipment
end
What we need to get is a join containing shipments and their latest shipment_event based on a :event_at field.
Example data (simplified with just one shipment):
[
{
"_id" => BSON::ObjectId('1'),
"shipment_events" => [
{
"_id" => BSON::ObjectId('2'),
"event_at" => 2022-04-09 15:00:00 UTC
},
{
"_id" => BSON::ObjectId('3'),
"event_at" => 2022-04-09 18:00:00 UTC
}
]
}
]
The result expected should contain the shipment and only the second (latest by :event_at) shipment_event. Something like...
[
{
"_id" => BSON::ObjectId('1'),
"_event_id" => BSON::ObjectId('3'),
"event_at" => 2022-04-09 18:00:00 UTC
}
]
I know join queries are not possible with MongoId and we will need to use aggregation I guess. Any ideas will be appreciated.
Thank you.
英文:
We have a Shipment document with an embedded ShipmentEvent document as in...
class Shipment
include Mongoid::Document
embeds_many :shipment_events
end
class ShipmentEvent
include Mongoid::Document
embedded_in :shipment
end
What we need to get is a join containing shipments and theirs latest shipment_event based on a :event_at field.
Example data (simplified with just one shipment):
[
{
"_id" => BSON::ObjectId('1'),
"shipment_events" => [
{
"_id" => BSON::ObjectId('2'),
"event_at" => 2022-04-09 15:00:00 UTC
},
{
"_id" => BSON::ObjectId('3'),
"event_at" => 2022-04-09 18:00:00 UTC
}
]
}
]
The result expected should contain the shipment and only the second (latest by :event_at) shipment_event. Something like...
[
{
"_id" => BSON::ObjectId('1'),
"_event_id" => BSON::ObjectId('3'),
"event_at" => 2022-04-09 18:00:00 UTC
}
]
I know join queries are not possible with MongoId and we will need to use aggregation I guess. Any ideas will be appreciated.
Thank you.
答案1
得分: 0
以下是翻译好的内容:
你可以这样做:
unwind = { "$unwind" => "$shipment_events" }
sort = {
"$sort" => {
"_id" => 1, "shipment_events.event_at" => -1
}
}
group = {
"$group" => {
"_id" => "$_id",
"event_id" => {
"$first" => "$$ROOT.shipment_events._id"
},
"event_at" => {
"$first" => "$$ROOT.shipment_events.event_at"
}
}
}
Shipment.collection.aggregate([unwind, sort, group])
请在下方找到示例 playground 链接。
https://mongoplayground.net/p/oLTG-18aIDm
英文:
You can do it this way:
unwind = { "$unwind" => "$shipment_events" }
sort = {
"$sort" => {
"_id" => 1, "shipment_events.event_at" => -1
}
}
group = {
"$group" => {
"_id" => "$_id",
"event_id" => {
"$first" => "$$ROOT.shipment_events._id"
},
"event_at" => {
"$first" => "$$ROOT.shipment_events.event_at"
}
}
}
Shipment.collection.aggregate([unwind, sort, group])
Please find playground example below.
https://mongoplayground.net/p/oLTG-18aIDm
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论